Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

tools build: Add new build support

Adding new build framework into 'tools/build' to be used by tools.

There's no change for actual building at this point, it comes in the
next patches.

The idea and more details are explained in the
'tools/build/Documentation/Build.txt' file.

I adopted everything from the kernel build system, with some changes to
allow for multiple binaries build definitions.

While the kernel's build output is single image (forget modules) we need
to be able to build several binaries/libraries.

The basic idea is that sser provides 'Build' files with objects
definitions like:

perf-y += a.o
perf-y += b.o
libperf-y += c.o
libperf-y += d.o

and the build framework outputs files:

perf-in.o # a.o, b.o compiled in
libperf-in.o # c.o, d.o compiled in

Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Tested-by: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
Tested-by: Will Deacon <will.deacon@arm.com>
Cc: Alexis Berlemont <alexis.berlemont@gmail.com>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/n/tip-fbj22h4av0otlxupwcmrxgpa@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

authored by

Jiri Olsa and committed by
Arnaldo Carvalho de Melo
c819e2cf 39f57043

+442
+81
tools/build/Build.include
··· 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))
+139
tools/build/Documentation/Build.txt
··· 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
+97
tools/build/Makefile.build
··· 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)
+8
tools/build/tests/ex/Build
··· 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/
+23
tools/build/tests/ex/Makefile
··· 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
+5
tools/build/tests/ex/a.c
··· 1 + 2 + int a(void) 3 + { 4 + return 0; 5 + }
+2
tools/build/tests/ex/arch/Build
··· 1 + libex-y += e.o 2 + libex-y += f.o
+5
tools/build/tests/ex/arch/e.c
··· 1 + 2 + int e(void) 3 + { 4 + return 0; 5 + }
+5
tools/build/tests/ex/arch/f.c
··· 1 + 2 + int f(void) 3 + { 4 + return 0; 5 + }
+5
tools/build/tests/ex/b.c
··· 1 + 2 + int b(void) 3 + { 4 + return 0; 5 + }
+5
tools/build/tests/ex/c.c
··· 1 + 2 + int c(void) 3 + { 4 + return 0; 5 + }
+5
tools/build/tests/ex/d.c
··· 1 + 2 + int d(void) 3 + { 4 + return 0; 5 + }
tools/build/tests/ex/empty/Build
+19
tools/build/tests/ex/ex.c
··· 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 + }
+42
tools/build/tests/run.sh
··· 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
+1
tools/perf/MANIFEST
··· 1 1 tools/perf 2 2 tools/scripts 3 + tools/build 3 4 tools/lib/traceevent 4 5 tools/lib/api 5 6 tools/lib/symbol/kallsyms.c