Computer Science
Algorithm
Data Processing
Digital Life
Distributed System
Distributed System Infrastructure
Machine Learning
Operating System
Android
Linux
How Kernel's Makefile Specify Output Directory (2013)
MacOS
Tizen
Windows
iOS
Programming Language
C++
Erlang
Go
Scala
Scheme
Type System
Software Engineering
Storage
UI
Flutter
Javascript
Virtualization
Life
Life in Guangzhou (2013)
Recent Works (2013)
东京之旅 (2014)
My 2017 Year in Review (2018)
My 2020 in Review (2021)
十三年前被隔离的经历 (2022)
A Travel to Montreal (2022)
My 2022 in Review (2023)
Travel Back to China (2024)
Projects
Bard
Blog
RSS Brain
Scala2grpc
Comment Everywhere (2013)
Fetch Popular Erlang Modules by Coffee Script (2013)
Psychology
耶鲁大学心理学导论 (2012)
Thoughts
Chinese
English

How Kernel's Makefile Specify Output Directory

Posted on 21 Jan 2013, tagged kernelmake

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:

ifeq ($(KBUILD_SRC),)
ifeq ("$(origin O)", "command line")
	KBUILD_OUTPUT := $(O)
endif

ifneq ($(KBUILD_OUTPUT),)
$(filter-out submake $(CURDIR)/Makefile, $(MAKECMDGOALS)): sub-make
	@:

sub-make:
	make -C $(KBUILD_OUTPUT) -f /home/wangbin/maketest/Makefile \
		KBUILD_SRC=$(PWD) \
		$(MAKECMDGOALS)
	@echo " sub-make KBUILD_OUTPUT: $(KBUILD_OUTPUT)"
skip-makefile := 1
endif #end KBUILD_OUTPUT
endif #end KBUILD_SRC

ifeq ($(skip-makefile),)

target1:
	touch target1
	@echo "target KBUILD_OUTPUT: $(KBUILD_OUTPUT)"

target2:
	touch target2
	@echo "target KBUILD_OUTPUT: $(KBUILD_OUTPUT)"
endif

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:

make -C ../build -f /home/wangbin/maketest/Makefile \
                KBUILD_SRC=/home/wangbin/maketest \
                target1
make[1]: Entering directory `/home/wangbin/build'
touch target1
target KBUILD_OUTPUT: 
make[1]: Leaving directory `/home/wangbin/build'
sub-make KBUILD_OUTPUT: ../build