How Kernel's Makefile Specify Output Directory
Posted on 21 Jan 2013, tagged kernel
make
When compile Linux kernel, we could output files to a split directory with “make O=”. The kernel’s way to do it is a little tricky. Since kernel’s Makefile is very big, we could have a simpler version to analyse:
1ifeq ($(KBUILD_SRC),) 2ifeq ("$(origin O)", "command line") 3 KBUILD_OUTPUT := $(O) 4endif 5 6ifneq ($(KBUILD_OUTPUT),) 7$(filter-out submake $(CURDIR)/Makefile, $(MAKECMDGOALS)): sub-make 8 @: 9 10sub-make: 11 make -C $(KBUILD_OUTPUT) -f /home/wangbin/maketest/Makefile \ 12 KBUILD_SRC=$(PWD) \ 13 $(MAKECMDGOALS) 14 @echo " sub-make KBUILD_OUTPUT: $(KBUILD_OUTPUT)" 15skip-makefile := 1 16endif #end KBUILD_OUTPUT 17endif #end KBUILD_SRC 18 19ifeq ($(skip-makefile),) 20 21target1: 22 touch target1 23 @echo "target KBUILD_OUTPUT: $(KBUILD_OUTPUT)" 24 25target2: 26 touch target2 27 @echo "target KBUILD_OUTPUT: $(KBUILD_OUTPUT)" 28endif
You could try to execute make O=../build target1
, it will output files to ../build
. Let’s see how it works.
When you execute make, KBUILD_SRC
is not defined at first, so it will make sub-make
as a dependency of any target you input(except some filter-out
target such as sub-make
). Change the directory to KBUILD_OUTPUT
(-C
option), set KBUILD_SRC
and then invoke itself again(-f
option).
At the second time, KBUILD_SRC
is defined so it will make the real targets.
The thing to notice is, while you make the real target1
, variables between ifeq ($(KBUILD_SRC),)
is not defined. You could see the output: