diff options
Diffstat (limited to 'tools')
-rw-r--r-- | tools/build/Build.include | 81 | ||||
-rw-r--r-- | tools/build/Documentation/Build.txt | 139 | ||||
-rw-r--r-- | tools/build/Makefile.build | 97 | ||||
-rw-r--r-- | tools/build/tests/ex/Build | 8 | ||||
-rw-r--r-- | tools/build/tests/ex/Makefile | 23 | ||||
-rw-r--r-- | tools/build/tests/ex/a.c | 5 | ||||
-rw-r--r-- | tools/build/tests/ex/arch/Build | 2 | ||||
-rw-r--r-- | tools/build/tests/ex/arch/e.c | 5 | ||||
-rw-r--r-- | tools/build/tests/ex/arch/f.c | 5 | ||||
-rw-r--r-- | tools/build/tests/ex/b.c | 5 | ||||
-rw-r--r-- | tools/build/tests/ex/c.c | 5 | ||||
-rw-r--r-- | tools/build/tests/ex/d.c | 5 | ||||
-rw-r--r-- | tools/build/tests/ex/empty/Build | 0 | ||||
-rw-r--r-- | tools/build/tests/ex/ex.c | 19 | ||||
-rwxr-xr-x | tools/build/tests/run.sh | 42 | ||||
-rw-r--r-- | tools/perf/MANIFEST | 1 |
16 files changed, 442 insertions, 0 deletions
diff --git a/tools/build/Build.include b/tools/build/Build.include new file mode 100644 index 000000000000..4c8daaccb82a --- /dev/null +++ b/tools/build/Build.include | |||
@@ -0,0 +1,81 @@ | |||
1 | ### | ||
2 | # build: Generic definitions | ||
3 | # | ||
4 | # Lots of this code have been borrowed or heavily inspired from parts | ||
5 | # of kbuild code, which is not credited, but mostly developed by: | ||
6 | # | ||
7 | # Copyright (C) Sam Ravnborg <sam@mars.ravnborg.org>, 2015 | ||
8 | # Copyright (C) Linus Torvalds <torvalds@linux-foundation.org>, 2015 | ||
9 | # | ||
10 | |||
11 | ### | ||
12 | # Convenient variables | ||
13 | comma := , | ||
14 | squote := ' | ||
15 | |||
16 | ### | ||
17 | # Name of target with a '.' as filename prefix. foo/bar.o => foo/.bar.o | ||
18 | dot-target = $(dir $@).$(notdir $@) | ||
19 | |||
20 | ### | ||
21 | # filename of target with directory and extension stripped | ||
22 | basetarget = $(basename $(notdir $@)) | ||
23 | |||
24 | ### | ||
25 | # The temporary file to save gcc -MD generated dependencies must not | ||
26 | # contain a comma | ||
27 | depfile = $(subst $(comma),_,$(dot-target).d) | ||
28 | |||
29 | ### | ||
30 | # Check if both arguments has same arguments. Result is empty string if equal. | ||
31 | arg-check = $(strip $(filter-out $(cmd_$(1)), $(cmd_$@)) \ | ||
32 | $(filter-out $(cmd_$@), $(cmd_$(1))) ) | ||
33 | |||
34 | ### | ||
35 | # Escape single quote for use in echo statements | ||
36 | escsq = $(subst $(squote),'\$(squote)',$1) | ||
37 | |||
38 | # Echo command | ||
39 | # Short version is used, if $(quiet) equals `quiet_', otherwise full one. | ||
40 | echo-cmd = $(if $($(quiet)cmd_$(1)),\ | ||
41 | echo ' $(call escsq,$($(quiet)cmd_$(1)))';) | ||
42 | |||
43 | ### | ||
44 | # Replace >$< with >$$< to preserve $ when reloading the .cmd file | ||
45 | # (needed for make) | ||
46 | # Replace >#< with >\#< to avoid starting a comment in the .cmd file | ||
47 | # (needed for make) | ||
48 | # Replace >'< with >'\''< to be able to enclose the whole string in '...' | ||
49 | # (needed for the shell) | ||
50 | make-cmd = $(call escsq,$(subst \#,\\\#,$(subst $$,$$$$,$(cmd_$(1))))) | ||
51 | |||
52 | ### | ||
53 | # Find any prerequisites that is newer than target or that does not exist. | ||
54 | # PHONY targets skipped in both cases. | ||
55 | any-prereq = $(filter-out $(PHONY),$?) $(filter-out $(PHONY) $(wildcard $^),$^) | ||
56 | |||
57 | ### | ||
58 | # if_changed_dep - execute command if any prerequisite is newer than | ||
59 | # target, or command line has changed and update | ||
60 | # dependencies in the cmd file | ||
61 | if_changed_dep = $(if $(strip $(any-prereq) $(arg-check)), \ | ||
62 | @set -e; \ | ||
63 | $(echo-cmd) $(cmd_$(1)); \ | ||
64 | cat $(depfile) > $(dot-target).cmd; \ | ||
65 | printf '%s\n' 'cmd_$@ := $(make-cmd)' >> $(dot-target).cmd) | ||
66 | |||
67 | # if_changed - execute command if any prerequisite is newer than | ||
68 | # target, or command line has changed | ||
69 | if_changed = $(if $(strip $(any-prereq) $(arg-check)), \ | ||
70 | @set -e; \ | ||
71 | $(echo-cmd) $(cmd_$(1)); \ | ||
72 | printf '%s\n' 'cmd_$@ := $(make-cmd)' > $(dot-target).cmd) | ||
73 | |||
74 | ### | ||
75 | # C flags to be used in rule definitions, includes: | ||
76 | # - depfile generation | ||
77 | # - global $(CFLAGS) | ||
78 | # - per target C flags | ||
79 | # - per object C flags | ||
80 | # - BUILD_STR macro to allow '-D"$(variable)"' constructs | ||
81 | c_flags = -Wp,-MD,$(depfile),-MT,$@ $(CFLAGS) -D"BUILD_STR(s)=\#s" $(CFLAGS_$(basetarget).o) $(CFLAGS_$(obj)) | ||
diff --git a/tools/build/Documentation/Build.txt b/tools/build/Documentation/Build.txt new file mode 100644 index 000000000000..00ad2d608727 --- /dev/null +++ b/tools/build/Documentation/Build.txt | |||
@@ -0,0 +1,139 @@ | |||
1 | Build Framework | ||
2 | =============== | ||
3 | |||
4 | The perf build framework was adopted from the kernel build system, hence the | ||
5 | idea and the way how objects are built is the same. | ||
6 | |||
7 | Basically the user provides set of 'Build' files that list objects and | ||
8 | directories to nest for specific target to be build. | ||
9 | |||
10 | Unlike the kernel we don't have a single build object 'obj-y' list that where | ||
11 | we setup source objects, but we support more. This allows one 'Build' file to | ||
12 | carry a sources list for multiple build objects. | ||
13 | |||
14 | a) Build framework makefiles | ||
15 | ---------------------------- | ||
16 | |||
17 | The build framework consists of 2 Makefiles: | ||
18 | |||
19 | Build.include | ||
20 | Makefile.build | ||
21 | |||
22 | While the 'Build.include' file contains just some generic definitions, the | ||
23 | 'Makefile.build' file is the makefile used from the outside. It's | ||
24 | interface/usage is following: | ||
25 | |||
26 | $ make -f tools/build/Makefile srctree=$(KSRC) dir=$(DIR) obj=$(OBJECT) | ||
27 | |||
28 | where: | ||
29 | |||
30 | KSRC - is the path to kernel sources | ||
31 | DIR - is the path to the project to be built | ||
32 | OBJECT - is the name of the build object | ||
33 | |||
34 | When succefully finished the $(DIR) directory contains the final object file | ||
35 | called $(OBJECT)-in.o: | ||
36 | |||
37 | $ ls $(DIR)/$(OBJECT)-in.o | ||
38 | |||
39 | which includes all compiled sources described in 'Build' makefiles. | ||
40 | |||
41 | a) Build makefiles | ||
42 | ------------------ | ||
43 | |||
44 | The user supplies 'Build' makefiles that contains a objects list, and connects | ||
45 | the build to nested directories. | ||
46 | |||
47 | Assume we have the following project structure: | ||
48 | |||
49 | ex/a.c | ||
50 | /b.c | ||
51 | /c.c | ||
52 | /d.c | ||
53 | /arch/e.c | ||
54 | /arch/f.c | ||
55 | |||
56 | Out of which you build the 'ex' binary ' and the 'libex.a' library: | ||
57 | |||
58 | 'ex' - consists of 'a.o', 'b.o' and libex.a | ||
59 | 'libex.a' - consists of 'c.o', 'd.o', 'e.o' and 'f.o' | ||
60 | |||
61 | The build framework does not create the 'ex' and 'libex.a' binaries for you, it | ||
62 | only prepares proper objects to be compiled and grouped together. | ||
63 | |||
64 | To follow the above example, the user provides following 'Build' files: | ||
65 | |||
66 | ex/Build: | ||
67 | ex-y += a.o | ||
68 | ex-y += b.o | ||
69 | |||
70 | libex-y += c.o | ||
71 | libex-y += d.o | ||
72 | libex-y += arch/ | ||
73 | |||
74 | ex/arch/Build: | ||
75 | libex-y += e.o | ||
76 | libex-y += f.o | ||
77 | |||
78 | and runs: | ||
79 | |||
80 | $ make -f tools/build/Makefile.build dir=. obj=ex | ||
81 | $ make -f tools/build/Makefile.build dir=. obj=libex | ||
82 | |||
83 | which creates the following objects: | ||
84 | |||
85 | ex/ex-in.o | ||
86 | ex/libex-in.o | ||
87 | |||
88 | that contain request objects names in Build files. | ||
89 | |||
90 | It's only a matter of 2 single commands to create the final binaries: | ||
91 | |||
92 | $ ar rcs libex.a libex-in.o | ||
93 | $ gcc -o ex ex-in.o libex.a | ||
94 | |||
95 | You can check the 'ex' example in 'tools/build/tests/ex' for more details. | ||
96 | |||
97 | b) Rules | ||
98 | -------- | ||
99 | |||
100 | The build framework provides standard compilation rules to handle .S and .c | ||
101 | compilation. | ||
102 | |||
103 | It's possible to include special rule if needed (like we do for flex or bison | ||
104 | code generation). | ||
105 | |||
106 | c) CFLAGS | ||
107 | --------- | ||
108 | |||
109 | It's possible to alter the standard object C flags in the following way: | ||
110 | |||
111 | CFLAGS_perf.o += '...' - alters CFLAGS for perf.o object | ||
112 | CFLAGS_gtk += '...' - alters CFLAGS for gtk build object | ||
113 | |||
114 | This C flags changes has the scope of the Build makefile they are defined in. | ||
115 | |||
116 | |||
117 | d) Dependencies | ||
118 | --------------- | ||
119 | |||
120 | For each built object file 'a.o' the '.a.cmd' is created and holds: | ||
121 | |||
122 | - Command line used to built that object | ||
123 | (for each object) | ||
124 | |||
125 | - Dependency rules generated by 'gcc -Wp,-MD,...' | ||
126 | (for compiled object) | ||
127 | |||
128 | All existing '.cmd' files are included in the Build process to follow properly | ||
129 | the dependencies and trigger a rebuild when necessary. | ||
130 | |||
131 | |||
132 | e) Single rules | ||
133 | --------------- | ||
134 | |||
135 | It's possible to build single object file by choice, like: | ||
136 | |||
137 | $ make util/map.o # objects | ||
138 | $ make util/map.i # preprocessor | ||
139 | $ make util/map.s # assembly | ||
diff --git a/tools/build/Makefile.build b/tools/build/Makefile.build new file mode 100644 index 000000000000..ae203f21cc86 --- /dev/null +++ b/tools/build/Makefile.build | |||
@@ -0,0 +1,97 @@ | |||
1 | ### | ||
2 | # Main build makefile. | ||
3 | # | ||
4 | # Lots of this code have been borrowed or heavily inspired from parts | ||
5 | # of kbuild code, which is not credited, but mostly developed by: | ||
6 | # | ||
7 | # Copyright (C) Sam Ravnborg <sam@mars.ravnborg.org>, 2015 | ||
8 | # Copyright (C) Linus Torvalds <torvalds@linux-foundation.org>, 2015 | ||
9 | # | ||
10 | |||
11 | PHONY := __build | ||
12 | __build: | ||
13 | |||
14 | ifeq ($(V),1) | ||
15 | quiet = | ||
16 | else | ||
17 | quiet=quiet_ | ||
18 | endif | ||
19 | |||
20 | build-dir := $(srctree)/tools/build | ||
21 | |||
22 | # Generic definitions | ||
23 | include $(build-dir)/Build.include | ||
24 | |||
25 | # Init all relevant variables used in build files so | ||
26 | # 1) they have correct type | ||
27 | # 2) they do not inherit any value from the environment | ||
28 | subdir-y := | ||
29 | obj-y := | ||
30 | subdir-y := | ||
31 | subdir-obj-y := | ||
32 | |||
33 | # Build definitions | ||
34 | build-file := $(dir)/Build | ||
35 | include $(build-file) | ||
36 | |||
37 | # Compile command | ||
38 | quiet_cmd_cc_o_c = CC $@ | ||
39 | cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $< | ||
40 | |||
41 | # Link agregate command | ||
42 | # If there's nothing to link, create empty $@ object. | ||
43 | quiet_cmd_ld_multi = LD $@ | ||
44 | cmd_ld_multi = $(if $(strip $(obj-y)),\ | ||
45 | $(LD) -r -o $@ $(obj-y),rm -f $@; $(AR) rcs $@) | ||
46 | |||
47 | # Build rules | ||
48 | $(OUTPUT)%.o: %.c FORCE | ||
49 | $(call if_changed_dep,cc_o_c) | ||
50 | |||
51 | $(OUTPUT)%.o: %.S FORCE | ||
52 | $(call if_changed_dep,cc_o_c) | ||
53 | |||
54 | # Gather build data: | ||
55 | # obj-y - list of build objects | ||
56 | # subdir-y - list of directories to nest | ||
57 | # subdir-obj-y - list of directories objects 'dir/$(obj)-in.o' | ||
58 | obj-y := $($(obj)-y) | ||
59 | subdir-y := $(patsubst %/,%,$(filter %/, $(obj-y))) | ||
60 | obj-y := $(patsubst %/, %/$(obj)-in.o, $(obj-y)) | ||
61 | subdir-obj-y := $(filter %/$(obj)-in.o, $(obj-y)) | ||
62 | |||
63 | # '$(OUTPUT)/dir' prefix to all objects | ||
64 | prefix := $(subst ./,,$(OUTPUT)$(dir)/) | ||
65 | obj-y := $(addprefix $(prefix),$(obj-y)) | ||
66 | subdir-obj-y := $(addprefix $(prefix),$(subdir-obj-y)) | ||
67 | |||
68 | # Final '$(obj)-in.o' object | ||
69 | in-target := $(prefix)$(obj)-in.o | ||
70 | |||
71 | PHONY += $(subdir-y) | ||
72 | |||
73 | $(subdir-y): | ||
74 | @$(MAKE) -f $(build-dir)/Makefile.build dir=$(dir)/$@ obj=$(obj) | ||
75 | |||
76 | $(sort $(subdir-obj-y)): $(subdir-y) ; | ||
77 | |||
78 | $(in-target): $(obj-y) FORCE | ||
79 | $(call rule_mkdir) | ||
80 | $(call if_changed,ld_multi) | ||
81 | |||
82 | __build: $(in-target) | ||
83 | @: | ||
84 | |||
85 | PHONY += FORCE | ||
86 | FORCE: | ||
87 | |||
88 | # Include all cmd files to get all the dependency rules | ||
89 | # for all objects included | ||
90 | targets := $(wildcard $(sort $(obj-y) $(in-target))) | ||
91 | cmd_files := $(wildcard $(foreach f,$(targets),$(dir $(f)).$(notdir $(f)).cmd)) | ||
92 | |||
93 | ifneq ($(cmd_files),) | ||
94 | include $(cmd_files) | ||
95 | endif | ||
96 | |||
97 | .PHONY: $(PHONY) | ||
diff --git a/tools/build/tests/ex/Build b/tools/build/tests/ex/Build new file mode 100644 index 000000000000..0e6c3e6767e6 --- /dev/null +++ b/tools/build/tests/ex/Build | |||
@@ -0,0 +1,8 @@ | |||
1 | ex-y += ex.o | ||
2 | ex-y += a.o | ||
3 | ex-y += b.o | ||
4 | ex-y += empty/ | ||
5 | |||
6 | libex-y += c.o | ||
7 | libex-y += d.o | ||
8 | libex-y += arch/ | ||
diff --git a/tools/build/tests/ex/Makefile b/tools/build/tests/ex/Makefile new file mode 100644 index 000000000000..52d2476073a3 --- /dev/null +++ b/tools/build/tests/ex/Makefile | |||
@@ -0,0 +1,23 @@ | |||
1 | export srctree := ../../../.. | ||
2 | export CC := gcc | ||
3 | export LD := ld | ||
4 | export AR := ar | ||
5 | |||
6 | build := -f $(srctree)/tools/build/Makefile.build dir=. obj | ||
7 | ex: ex-in.o libex-in.o | ||
8 | gcc -o $@ $^ | ||
9 | |||
10 | ex.%: FORCE | ||
11 | make -f $(srctree)/tools/build/Makefile.build dir=. $@ | ||
12 | |||
13 | ex-in.o: FORCE | ||
14 | make $(build)=ex | ||
15 | |||
16 | libex-in.o: FORCE | ||
17 | make $(build)=libex | ||
18 | |||
19 | clean: | ||
20 | find . -name '*.o' -delete -o -name '\.*.cmd' -delete -o -name '\.*.d' -delete | ||
21 | rm -f ex ex.i ex.s | ||
22 | |||
23 | .PHONY: FORCE | ||
diff --git a/tools/build/tests/ex/a.c b/tools/build/tests/ex/a.c new file mode 100644 index 000000000000..851762798c83 --- /dev/null +++ b/tools/build/tests/ex/a.c | |||
@@ -0,0 +1,5 @@ | |||
1 | |||
2 | int a(void) | ||
3 | { | ||
4 | return 0; | ||
5 | } | ||
diff --git a/tools/build/tests/ex/arch/Build b/tools/build/tests/ex/arch/Build new file mode 100644 index 000000000000..55506189efae --- /dev/null +++ b/tools/build/tests/ex/arch/Build | |||
@@ -0,0 +1,2 @@ | |||
1 | libex-y += e.o | ||
2 | libex-y += f.o | ||
diff --git a/tools/build/tests/ex/arch/e.c b/tools/build/tests/ex/arch/e.c new file mode 100644 index 000000000000..beaa4a1d7ba8 --- /dev/null +++ b/tools/build/tests/ex/arch/e.c | |||
@@ -0,0 +1,5 @@ | |||
1 | |||
2 | int e(void) | ||
3 | { | ||
4 | return 0; | ||
5 | } | ||
diff --git a/tools/build/tests/ex/arch/f.c b/tools/build/tests/ex/arch/f.c new file mode 100644 index 000000000000..7c3e9e9da5b7 --- /dev/null +++ b/tools/build/tests/ex/arch/f.c | |||
@@ -0,0 +1,5 @@ | |||
1 | |||
2 | int f(void) | ||
3 | { | ||
4 | return 0; | ||
5 | } | ||
diff --git a/tools/build/tests/ex/b.c b/tools/build/tests/ex/b.c new file mode 100644 index 000000000000..c24ff9ca9a97 --- /dev/null +++ b/tools/build/tests/ex/b.c | |||
@@ -0,0 +1,5 @@ | |||
1 | |||
2 | int b(void) | ||
3 | { | ||
4 | return 0; | ||
5 | } | ||
diff --git a/tools/build/tests/ex/c.c b/tools/build/tests/ex/c.c new file mode 100644 index 000000000000..e216d0217499 --- /dev/null +++ b/tools/build/tests/ex/c.c | |||
@@ -0,0 +1,5 @@ | |||
1 | |||
2 | int c(void) | ||
3 | { | ||
4 | return 0; | ||
5 | } | ||
diff --git a/tools/build/tests/ex/d.c b/tools/build/tests/ex/d.c new file mode 100644 index 000000000000..80dc0f06151b --- /dev/null +++ b/tools/build/tests/ex/d.c | |||
@@ -0,0 +1,5 @@ | |||
1 | |||
2 | int d(void) | ||
3 | { | ||
4 | return 0; | ||
5 | } | ||
diff --git a/tools/build/tests/ex/empty/Build b/tools/build/tests/ex/empty/Build new file mode 100644 index 000000000000..e69de29bb2d1 --- /dev/null +++ b/tools/build/tests/ex/empty/Build | |||
diff --git a/tools/build/tests/ex/ex.c b/tools/build/tests/ex/ex.c new file mode 100644 index 000000000000..dc42eb2e1a67 --- /dev/null +++ b/tools/build/tests/ex/ex.c | |||
@@ -0,0 +1,19 @@ | |||
1 | |||
2 | int a(void); | ||
3 | int b(void); | ||
4 | int c(void); | ||
5 | int d(void); | ||
6 | int e(void); | ||
7 | int f(void); | ||
8 | |||
9 | int main(void) | ||
10 | { | ||
11 | a(); | ||
12 | b(); | ||
13 | c(); | ||
14 | d(); | ||
15 | e(); | ||
16 | f(); | ||
17 | |||
18 | return 0; | ||
19 | } | ||
diff --git a/tools/build/tests/run.sh b/tools/build/tests/run.sh new file mode 100755 index 000000000000..5494f8ea7567 --- /dev/null +++ b/tools/build/tests/run.sh | |||
@@ -0,0 +1,42 @@ | |||
1 | #!/bin/sh | ||
2 | |||
3 | function test_ex { | ||
4 | make -C ex V=1 clean > ex.out 2>&1 | ||
5 | make -C ex V=1 >> ex.out 2>&1 | ||
6 | |||
7 | if [ ! -x ./ex/ex ]; then | ||
8 | echo FAILED | ||
9 | exit -1 | ||
10 | fi | ||
11 | |||
12 | make -C ex V=1 clean > /dev/null 2>&1 | ||
13 | rm -f ex.out | ||
14 | } | ||
15 | |||
16 | function test_ex_suffix { | ||
17 | make -C ex V=1 clean > ex.out 2>&1 | ||
18 | |||
19 | # use -rR to disable make's builtin rules | ||
20 | make -rR -C ex V=1 ex.o >> ex.out 2>&1 | ||
21 | make -rR -C ex V=1 ex.i >> ex.out 2>&1 | ||
22 | make -rR -C ex V=1 ex.s >> ex.out 2>&1 | ||
23 | |||
24 | if [ -x ./ex/ex ]; then | ||
25 | echo FAILED | ||
26 | exit -1 | ||
27 | fi | ||
28 | |||
29 | if [ ! -f ./ex/ex.o -o ! -f ./ex/ex.i -o ! -f ./ex/ex.s ]; then | ||
30 | echo FAILED | ||
31 | exit -1 | ||
32 | fi | ||
33 | |||
34 | make -C ex V=1 clean > /dev/null 2>&1 | ||
35 | rm -f ex.out | ||
36 | } | ||
37 | echo -n Testing.. | ||
38 | |||
39 | test_ex | ||
40 | test_ex_suffix | ||
41 | |||
42 | echo OK | ||
diff --git a/tools/perf/MANIFEST b/tools/perf/MANIFEST index fbbfdc39271d..11ccbb22ea2b 100644 --- a/tools/perf/MANIFEST +++ b/tools/perf/MANIFEST | |||
@@ -1,5 +1,6 @@ | |||
1 | tools/perf | 1 | tools/perf |
2 | tools/scripts | 2 | tools/scripts |
3 | tools/build | ||
3 | tools/lib/traceevent | 4 | tools/lib/traceevent |
4 | tools/lib/api | 5 | tools/lib/api |
5 | tools/lib/symbol/kallsyms.c | 6 | tools/lib/symbol/kallsyms.c |