요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.
1. 요약·해설
원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.
2. 영어 원문 전체
번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.
원문 전체 펼치기
======================
Linux Kernel Makefiles
======================
This document describes the Linux kernel Makefiles.
Overview
========
The Makefiles have five parts::
Makefile the top Makefile.
.config the kernel configuration file.
arch/$(SRCARCH)/Makefile the arch Makefile.
scripts/Makefile.* common rules etc. for all kbuild Makefiles.
kbuild Makefiles exist in every subdirectory
The top Makefile reads the .config file, which comes from the kernel
configuration process.
The top Makefile is responsible for building two major products: vmlinux
(the resident kernel image) and modules (any module files).
It builds these goals by recursively descending into the subdirectories of
the kernel source tree.
The list of subdirectories which are visited depends upon the kernel
configuration. The top Makefile textually includes an arch Makefile
with the name arch/$(SRCARCH)/Makefile. The arch Makefile supplies
architecture-specific information to the top Makefile.
Each subdirectory has a kbuild Makefile which carries out the commands
passed down from above. The kbuild Makefile uses information from the
.config file to construct various file lists used by kbuild to build
any built-in or modular targets.
scripts/Makefile.* contains all the definitions/rules etc. that
are used to build the kernel based on the kbuild makefiles.
Who does what
=============
People have four different relationships with the kernel Makefiles.
*Users* are people who build kernels. These people type commands such as
``make menuconfig`` or ``make``. They usually do not read or edit
any kernel Makefiles (or any other source files).
*Normal developers* are people who work on features such as device
drivers, file systems, and network protocols. These people need to
maintain the kbuild Makefiles for the subsystem they are
working on. In order to do this effectively, they need some overall
knowledge about the kernel Makefiles, plus detailed knowledge about the
public interface for kbuild.
*Arch developers* are people who work on an entire architecture, such
as sparc or x86. Arch developers need to know about the arch Makefile
as well as kbuild Makefiles.
*Kbuild developers* are people who work on the kernel build system itself.
These people need to know about all aspects of the kernel Makefiles.
This document is aimed towards normal developers and arch developers.
The kbuild files
================
Most Makefiles within the kernel are kbuild Makefiles that use the
kbuild infrastructure. This chapter introduces the syntax used in the
kbuild makefiles.
The preferred name for the kbuild files are ``Makefile`` but ``Kbuild`` can
be used and if both a ``Makefile`` and a ``Kbuild`` file exists, then the ``Kbuild``
file will be used.
Section `Goal definitions`_ is a quick intro; further chapters provide
more details, with real examples.
Goal definitions
----------------
Goal definitions are the main part (heart) of the kbuild Makefile.
These lines define the files to be built, any special compilation
options, and any subdirectories to be entered recursively.
The most simple kbuild makefile contains one line:
Example::
obj-y += foo.o
This tells kbuild that there is one object in that directory, named
foo.o. foo.o will be built from foo.c or foo.S.
If foo.o shall be built as a module, the variable obj-m is used.
Therefore the following pattern is often used:
Example::
obj-$(CONFIG_FOO) += foo.o
$(CONFIG_FOO) evaluates to either y (for built-in) or m (for module).
If CONFIG_FOO is neither y nor m, then the file will not be compiled
nor linked.
Built-in object goals - obj-y
-----------------------------
The kbuild Makefile specifies object files for vmlinux
in the $(obj-y) lists. These lists depend on the kernel
configuration.
Kbuild compiles all the $(obj-y) files. It then calls
``$(AR) rcSTP`` to merge these files into one built-in.a file.
This is a thin archive without a symbol table. It will be later
linked into vmlinux by scripts/link-vmlinux.sh
The order of files in $(obj-y) is significant. Duplicates in
the lists are allowed: the first instance will be linked into
built-in.a and succeeding instances will be ignored.
Link order is significant, because certain functions
(module_init() / __initcall) will be called during boot in the
order they appear. So keep in mind that changing the link
order may e.g. change the order in which your SCSI
controllers are detected, and thus your disks are renumbered.
Example::
#drivers/isdn/i4l/Makefile
# Makefile for the kernel ISDN subsystem and device drivers.
# Each configuration option enables a list of files.
obj-$(CONFIG_ISDN_I4L) += isdn.o
obj-$(CONFIG_ISDN_PPP_BSDCOMP) += isdn_bsdcomp.o
Loadable module goals - obj-m
-----------------------------
$(obj-m) specifies object files which are built as loadable
kernel modules.
A module may be built from one source file or several source
files. In the case of one source file, the kbuild makefile
simply adds the file to $(obj-m).
Example::
#drivers/isdn/i4l/Makefile
obj-$(CONFIG_ISDN_PPP_BSDCOMP) += isdn_bsdcomp.o
Note: In this example $(CONFIG_ISDN_PPP_BSDCOMP) evaluates to "m"
If a kernel module is built from several source files, you specify
that you want to build a module in the same way as above; however,
kbuild needs to know which object files you want to build your
module from, so you have to tell it by setting a $(<module_name>-y)
variable.
Example::
#drivers/isdn/i4l/Makefile
obj-$(CONFIG_ISDN_I4L) += isdn.o
isdn-y := isdn_net_lib.o isdn_v110.o isdn_common.o
In this example, the module name will be isdn.o. Kbuild will
compile the objects listed in $(isdn-y) and then run
``$(LD) -r`` on the list of these files to generate isdn.o.
Due to kbuild recognizing $(<module_name>-y) for composite objects,
you can use the value of a ``CONFIG_`` symbol to optionally include an
object file as part of a composite object.
Example::
#fs/ext2/Makefile
obj-$(CONFIG_EXT2_FS) += ext2.o
ext2-y := balloc.o dir.o file.o ialloc.o inode.o ioctl.o \
namei.o super.o symlink.o
ext2-$(CONFIG_EXT2_FS_XATTR) += xattr.o xattr_user.o \
xattr_trusted.o
In this example, xattr.o, xattr_user.o and xattr_trusted.o are only
part of the composite object ext2.o if $(CONFIG_EXT2_FS_XATTR)
evaluates to "y".
Note: Of course, when you are building objects into the kernel,
the syntax above will also work. So, if you have CONFIG_EXT2_FS=y,
kbuild will build an ext2.o file for you out of the individual
parts and then link this into built-in.a, as you would expect.
Library file goals - lib-y
--------------------------
Objects listed with obj-* are used for modules, or
combined in a built-in.a for that specific directory.
There is also the possibility to list objects that will
be included in a library, lib.a.
All objects listed with lib-y are combined in a single
library for that directory.
Objects that are listed in obj-y and additionally listed in
lib-y will not be included in the library, since they will
be accessible anyway.
For consistency, objects listed in lib-m will be included in lib.a.
Note that the same kbuild makefile may list files to be built-in
and to be part of a library. Therefore the same directory
may contain both a built-in.a and a lib.a file.
Example::
#arch/x86/lib/Makefile
lib-y := delay.o
This will create a library lib.a based on delay.o. For kbuild to
actually recognize that there is a lib.a being built, the directory
shall be listed in libs-y.
See also `List directories to visit when descending`_.
Use of lib-y is normally restricted to ``lib/`` and ``arch/*/lib``.
Descending down in directories
------------------------------
A Makefile is only responsible for building objects in its own
directory. Files in subdirectories should be taken care of by
Makefiles in these subdirs. The build system will automatically
invoke make recursively in subdirectories, provided you let it know of
them.
To do so, obj-y and obj-m are used.
ext2 lives in a separate directory, and the Makefile present in fs/
tells kbuild to descend down using the following assignment.
Example::
#fs/Makefile
obj-$(CONFIG_EXT2_FS) += ext2/
If CONFIG_EXT2_FS is set to either "y" (built-in) or "m" (modular)
the corresponding obj- variable will be set, and kbuild will descend
down in the ext2 directory.
Kbuild uses this information not only to decide that it needs to visit
the directory, but also to decide whether or not to link objects from
the directory into vmlinux.
When Kbuild descends into the directory with "y", all built-in objects
from that directory are combined into the built-in.a, which will be
eventually linked into vmlinux.
When Kbuild descends into the directory with "m", in contrast, nothing
from that directory will be linked into vmlinux. If the Makefile in
that directory specifies obj-y, those objects will be left orphan.
It is very likely a bug of the Makefile or of dependencies in Kconfig.
Kbuild also supports dedicated syntax, subdir-y and subdir-m, for
descending into subdirectories. It is a good fit when you know they
do not contain kernel-space objects at all. A typical usage is to let
Kbuild descend into subdirectories to build tools.
Examples::
# scripts/Makefile
subdir-$(CONFIG_GCC_PLUGINS) += gcc-plugins
subdir-$(CONFIG_MODVERSIONS) += genksyms
subdir-$(CONFIG_SECURITY_SELINUX) += selinux
Unlike obj-y/m, subdir-y/m does not need the trailing slash since this
syntax is always used for directories.
It is good practice to use a ``CONFIG_`` variable when assigning directory
names. This allows kbuild to totally skip the directory if the
corresponding ``CONFIG_`` option is neither "y" nor "m".
Non-builtin vmlinux targets - extra-y
-------------------------------------
extra-y specifies targets which are needed for building vmlinux,
but not combined into built-in.a.
Examples are:
1) vmlinux linker script
The linker script for vmlinux is located at
arch/$(SRCARCH)/kernel/vmlinux.lds
Example::
# arch/x86/kernel/Makefile
extra-y += vmlinux.lds
extra-y is now deprecated because this is equivalent to:
always-$(KBUILD_BUILTIN) += vmlinux.lds
$(extra-y) should only contain targets needed for vmlinux.
Kbuild skips extra-y when vmlinux is apparently not a final goal.
(e.g. ``make modules``, or building external modules)
If you intend to build targets unconditionally, always-y (explained
in the next section) is the correct syntax to use.
Always built goals - always-y
-----------------------------
always-y specifies targets which are literally always built when
Kbuild visits the Makefile.
Example::
# ./Kbuild
offsets-file := include/generated/asm-offsets.h
always-y += $(offsets-file)
Compilation flags
-----------------
ccflags-y, asflags-y and ldflags-y
These three flags apply only to the kbuild makefile in which they
are assigned. They are used for all the normal cc, as and ld
invocations happening during a recursive build.
ccflags-y specifies options for compiling with $(CC).
Example::
# drivers/acpi/acpica/Makefile
ccflags-y := -Os -D_LINUX -DBUILDING_ACPICA
ccflags-$(CONFIG_ACPI_DEBUG) += -DACPI_DEBUG_OUTPUT
This variable is necessary because the top Makefile owns the
variable $(KBUILD_CFLAGS) and uses it for compilation flags for the
entire tree.
asflags-y specifies assembler options.
Example::
#arch/sparc/kernel/Makefile
asflags-y := -ansi
ldflags-y specifies options for linking with $(LD).
Example::
#arch/cris/boot/compressed/Makefile
ldflags-y += -T $(src)/decompress_$(arch-y).lds
subdir-ccflags-y, subdir-asflags-y
The two flags listed above are similar to ccflags-y and asflags-y.
The difference is that the subdir- variants have effect for the kbuild
file where they are present and all subdirectories.
Options specified using subdir-* are added to the commandline before
the options specified using the non-subdir variants.
Example::
subdir-ccflags-y := -Werror
ccflags-remove-y, asflags-remove-y
These flags are used to remove particular flags for the compiler,
assembler invocations.
Example::
ccflags-remove-$(CONFIG_MCOUNT) += -pg
CFLAGS_$@, AFLAGS_$@
CFLAGS_$@ and AFLAGS_$@ only apply to commands in current
kbuild makefile.
$(CFLAGS_$@) specifies per-file options for $(CC). The $@
part has a literal value which specifies the file that it is for.
CFLAGS_$@ has the higher priority than ccflags-remove-y; CFLAGS_$@
can re-add compiler flags that were removed by ccflags-remove-y.
Example::
# drivers/scsi/Makefile
CFLAGS_aha152x.o = -DAHA152X_STAT -DAUTOCONF
This line specify compilation flags for aha152x.o.
$(AFLAGS_$@) is a similar feature for source files in assembly
languages.
AFLAGS_$@ has the higher priority than asflags-remove-y; AFLAGS_$@
can re-add assembler flags that were removed by asflags-remove-y.
Example::
# arch/arm/kernel/Makefile
AFLAGS_head.o := -DTEXT_OFFSET=$(TEXT_OFFSET)
AFLAGS_crunch-bits.o := -Wa,-mcpu=ep9312
AFLAGS_iwmmxt.o := -Wa,-mcpu=iwmmxt
Dependency tracking
-------------------
Kbuild tracks dependencies on the following:
1) All prerequisite files (both ``*.c`` and ``*.h``)
2) ``CONFIG_`` options used in all prerequisite files
3) Command-line used to compile target
Thus, if you change an option to $(CC) all affected files will
be re-compiled.
Custom Rules
------------
Custom rules are used when the kbuild infrastructure does
not provide the required support. A typical example is
header files generated during the build process.
Another example are the architecture-specific Makefiles which
need custom rules to prepare boot images etc.
Custom rules are written as normal Make rules.
Kbuild is not executing in the directory where the Makefile is
located, so all custom rules shall use a relative
path to prerequisite files and target files.
Two variables are used when defining custom rules:
$(src)
$(src) is the directory where the Makefile is located. Always use $(src) when
referring to files located in the src tree.
$(obj)
$(obj) is the directory where the target is saved. Always use $(obj) when
referring to generated files. Use $(obj) for pattern rules that need to work
for both generated files and real sources (VPATH will help to find the
prerequisites not only in the object tree but also in the source tree).
Example::
#drivers/scsi/Makefile
$(obj)/53c8xx_d.h: $(src)/53c7,8xx.scr $(src)/script_asm.pl
$(CPP) -DCHIP=810 - < $< | ... $(src)/script_asm.pl
This is a custom rule, following the normal syntax
required by make.
The target file depends on two prerequisite files. References
to the target file are prefixed with $(obj), references
to prerequisites are referenced with $(src) (because they are not
generated files).
$(srcroot)
$(srcroot) refers to the root of the source you are building, which can be
either the kernel source or the external modules source, depending on whether
KBUILD_EXTMOD is set. This can be either a relative or an absolute path, but
if KBUILD_ABS_SRCTREE=1 is set, it is always an absolute path.
$(srctree)
$(srctree) refers to the root of the kernel source tree. When building the
kernel, this is the same as $(srcroot).
$(objtree)
$(objtree) refers to the root of the kernel object tree. It is ``.`` when
building the kernel, but it is different when building external modules.
$(kecho)
echoing information to user in a rule is often a good practice
but when execution ``make -s`` one does not expect to see any output
except for warnings/errors.
To support this kbuild defines $(kecho) which will echo out the
text following $(kecho) to stdout except if ``make -s`` is used.
Example::
# arch/arm/Makefile
$(BOOT_TARGETS): vmlinux
$(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/$@
@$(kecho) ' Kernel: $(boot)/$@ is ready'
When kbuild is executing with KBUILD_VERBOSE unset, then only a shorthand
of a command is normally displayed.
To enable this behaviour for custom commands kbuild requires
two variables to be set::
quiet_cmd_<command> - what shall be echoed
cmd_<command> - the command to execute
Example::
# lib/Makefile
quiet_cmd_crc32 = GEN $@
cmd_crc32 = $< > $@
$(obj)/crc32table.h: $(obj)/gen_crc32table
$(call cmd,crc32)
When updating the $(obj)/crc32table.h target, the line::
GEN lib/crc32table.h
will be displayed with ``make KBUILD_VERBOSE=``.
Command change detection
------------------------
When the rule is evaluated, timestamps are compared between the target
and its prerequisite files. GNU Make updates the target when any of the
prerequisites is newer than that.
The target should be rebuilt also when the command line has changed
since the last invocation. This is not supported by Make itself, so
Kbuild achieves this by a kind of meta-programming.
if_changed is the macro used for this purpose, in the following form::
quiet_cmd_<command> = ...
cmd_<command> = ...
<target>: <source(s)> FORCE
$(call if_changed,<command>)
Any target that utilizes if_changed must be listed in $(targets),
otherwise the command line check will fail, and the target will
always be built.
If the target is already listed in the recognized syntax such as
obj-y/m, lib-y/m, extra-y/m, always-y/m, hostprogs, userprogs, Kbuild
automatically adds it to $(targets). Otherwise, the target must be
explicitly added to $(targets).
Assignments to $(targets) are without $(obj)/ prefix. if_changed may be
used in conjunction with custom rules as defined in `Custom Rules`_.
Note: It is a typical mistake to forget the FORCE prerequisite.
Another common pitfall is that whitespace is sometimes significant; for
instance, the below will fail (note the extra space after the comma)::
target: source(s) FORCE
**WRONG!** $(call if_changed, objcopy)
Note:
if_changed should not be used more than once per target.
It stores the executed command in a corresponding .cmd
file and multiple calls would result in overwrites and
unwanted results when the target is up to date and only the
tests on changed commands trigger execution of commands.
$(CC) support functions
-----------------------
The kernel may be built with several different versions of
$(CC), each supporting a unique set of features and options.
kbuild provides basic support to check for valid options for $(CC).
$(CC) is usually the gcc compiler, but other alternatives are
available.
as-option
as-option is used to check if $(CC) -- when used to compile
assembler (``*.S``) files -- supports the given option. An optional
second option may be specified if the first option is not supported.
Example::
#arch/sh/Makefile
cflags-y += $(call as-option,-Wa$(comma)-isa=$(isa-y),)
In the above example, cflags-y will be assigned the option
-Wa$(comma)-isa=$(isa-y) if it is supported by $(CC).
The second argument is optional, and if supplied will be used
if first argument is not supported.
as-instr
as-instr checks if the assembler reports a specific instruction
and then outputs either option1 or option2
C escapes are supported in the test instruction
Note: as-instr-option uses KBUILD_AFLAGS for assembler options
cc-option
cc-option is used to check if $(CC) supports a given option, and if
not supported to use an optional second option.
Example::
#arch/x86/Makefile
cflags-y += $(call cc-option,-march=pentium-mmx,-march=i586)
In the above example, cflags-y will be assigned the option
-march=pentium-mmx if supported by $(CC), otherwise -march=i586.
The second argument to cc-option is optional, and if omitted,
cflags-y will be assigned no value if first option is not supported.
Note: cc-option uses KBUILD_CFLAGS for $(CC) options
cc-option-yn
cc-option-yn is used to check if $(CC) supports a given option
and return "y" if supported, otherwise "n".
Example::
#arch/ppc/Makefile
biarch := $(call cc-option-yn, -m32)
aflags-$(biarch) += -a32
cflags-$(biarch) += -m32
In the above example, $(biarch) is set to y if $(CC) supports the -m32
option. When $(biarch) equals "y", the expanded variables $(aflags-y)
and $(cflags-y) will be assigned the values -a32 and -m32,
respectively.
Note: cc-option-yn uses KBUILD_CFLAGS for $(CC) options
cc-disable-warning
cc-disable-warning checks if $(CC) supports a given warning and returns
the commandline switch to disable it. This special function is needed,
because gcc 4.4 and later accept any unknown -Wno-* option and only
warn about it if there is another warning in the source file.
Example::
KBUILD_CFLAGS += $(call cc-disable-warning, unused-but-set-variable)
In the above example, -Wno-unused-but-set-variable will be added to
KBUILD_CFLAGS only if $(CC) really accepts it.
gcc-min-version
gcc-min-version tests if the value of $(CONFIG_GCC_VERSION) is greater than
or equal to the provided value and evaluates to y if so.
Example::
cflags-$(call gcc-min-version, 110100) := -foo
In this example, cflags-y will be assigned the value -foo if $(CC) is gcc and
$(CONFIG_GCC_VERSION) is >= 11.1.
clang-min-version
clang-min-version tests if the value of $(CONFIG_CLANG_VERSION) is greater
than or equal to the provided value and evaluates to y if so.
Example::
cflags-$(call clang-min-version, 110000) := -foo
In this example, cflags-y will be assigned the value -foo if $(CC) is clang
and $(CONFIG_CLANG_VERSION) is >= 11.0.0.
cc-cross-prefix
cc-cross-prefix is used to check if there exists a $(CC) in path with
one of the listed prefixes. The first prefix where there exist a
prefix$(CC) in the PATH is returned - and if no prefix$(CC) is found
then nothing is returned.
Additional prefixes are separated by a single space in the
call of cc-cross-prefix.
This functionality is useful for architecture Makefiles that try
to set CROSS_COMPILE to well-known values but may have several
values to select between.
It is recommended only to try to set CROSS_COMPILE if it is a cross
build (host arch is different from target arch). And if CROSS_COMPILE
is already set then leave it with the old value.
Example::
#arch/m68k/Makefile
ifneq ($(SUBARCH),$(ARCH))
ifeq ($(CROSS_COMPILE),)
CROSS_COMPILE := $(call cc-cross-prefix, m68k-linux-gnu-)
endif
endif
$(RUSTC) support functions
--------------------------
rustc-min-version
rustc-min-version tests if the value of $(CONFIG_RUSTC_VERSION) is greater
than or equal to the provided value and evaluates to y if so.
Example::
rustflags-$(call rustc-min-version, 108500) := -Cfoo
In this example, rustflags-y will be assigned the value -Cfoo if
$(CONFIG_RUSTC_VERSION) is >= 1.85.0.
$(LD) support functions
-----------------------
ld-option
ld-option is used to check if $(LD) supports the supplied option.
ld-option takes two options as arguments.
The second argument is an optional option that can be used if the
first option is not supported by $(LD).
Example::
#Makefile
LDFLAGS_vmlinux += $(call ld-option, -X)
Script invocation
-----------------
Make rules may invoke scripts to build the kernel. The rules shall
always provide the appropriate interpreter to execute the script. They
shall not rely on the execute bits being set, and shall not invoke the
script directly. For the convenience of manual script invocation, such
as invoking ./scripts/checkpatch.pl, it is recommended to set execute
bits on the scripts nonetheless.
Kbuild provides variables $(CONFIG_SHELL), $(AWK), $(PERL),
and $(PYTHON3) to refer to interpreters for the respective
scripts.
Example::
#Makefile
cmd_depmod = $(CONFIG_SHELL) $(srctree)/scripts/depmod.sh $(DEPMOD) \
$(KERNELRELEASE)
Host Program support
====================
Kbuild supports building executables on the host for use during the
compilation stage.
Two steps are required in order to use a host executable.
The first step is to tell kbuild that a host program exists. This is
done utilising the variable ``hostprogs``.
The second step is to add an explicit dependency to the executable.
This can be done in two ways. Either add the dependency in a rule,
or utilise the variable ``always-y``.
Both possibilities are described in the following.
Simple Host Program
-------------------
In some cases there is a need to compile and run a program on the
computer where the build is running.
The following line tells kbuild that the program bin2hex shall be
built on the build host.
Example::
hostprogs := bin2hex
Kbuild assumes in the above example that bin2hex is made from a single
c-source file named bin2hex.c located in the same directory as
the Makefile.
Composite Host Programs
-----------------------
Host programs can be made up based on composite objects.
The syntax used to define composite objects for host programs is
similar to the syntax used for kernel objects.
$(<executable>-objs) lists all objects used to link the final
executable.
Example::
#scripts/lxdialog/Makefile
hostprogs := lxdialog
lxdialog-objs := checklist.o lxdialog.o
Objects with extension .o are compiled from the corresponding .c
files. In the above example, checklist.c is compiled to checklist.o
and lxdialog.c is compiled to lxdialog.o.
Finally, the two .o files are linked to the executable, lxdialog.
Note: The syntax <executable>-y is not permitted for host-programs.
Using C++ for host programs
---------------------------
kbuild offers support for host programs written in C++. This was
introduced solely to support kconfig, and is not recommended
for general use.
Example::
#scripts/kconfig/Makefile
hostprogs := qconf
qconf-cxxobjs := qconf.o
In the example above the executable is composed of the C++ file
qconf.cc - identified by $(qconf-cxxobjs).
If qconf is composed of a mixture of .c and .cc files, then an
additional line can be used to identify this.
Example::
#scripts/kconfig/Makefile
hostprogs := qconf
qconf-cxxobjs := qconf.o
qconf-objs := check.o
Using Rust for host programs
----------------------------
Kbuild offers support for host programs written in Rust. However,
since a Rust toolchain is not mandatory for kernel compilation,
it may only be used in scenarios where Rust is required to be
available (e.g. when ``CONFIG_RUST`` is enabled).
Example::
hostprogs := target
target-rust := y
Kbuild will compile ``target`` using ``target.rs`` as the crate root,
located in the same directory as the ``Makefile``. The crate may
consist of several source files (see ``samples/rust/hostprogs``).
Controlling compiler options for host programs
----------------------------------------------
When compiling host programs, it is possible to set specific flags.
The programs will always be compiled utilising $(HOSTCC) passed
the options specified in $(KBUILD_HOSTCFLAGS).
To set flags that will take effect for all host programs created
in that Makefile, use the variable HOST_EXTRACFLAGS.
Example::
#scripts/lxdialog/Makefile
HOST_EXTRACFLAGS += -I/usr/include/ncurses
To set specific flags for a single file the following construction
is used:
Example::
#arch/ppc64/boot/Makefile
HOSTCFLAGS_piggyback.o := -DKERNELBASE=$(KERNELBASE)
It is also possible to specify additional options to the linker.
Example::
#scripts/kconfig/Makefile
HOSTLDLIBS_qconf := -L$(QTDIR)/lib
When linking qconf, it will be passed the extra option
``-L$(QTDIR)/lib``.
When host programs are actually built
-------------------------------------
Kbuild will only build host-programs when they are referenced
as a prerequisite.
This is possible in two ways:
(1) List the prerequisite explicitly in a custom rule.
Example::
#drivers/pci/Makefile
hostprogs := gen-devlist
$(obj)/devlist.h: $(src)/pci.ids $(obj)/gen-devlist
( cd $(obj); ./gen-devlist ) < $<
The target $(obj)/devlist.h will not be built before
$(obj)/gen-devlist is updated. Note that references to
the host programs in custom rules must be prefixed with $(obj).
(2) Use always-y
When there is no suitable custom rule, and the host program
shall be built when a makefile is entered, the always-y
variable shall be used.
Example::
#scripts/lxdialog/Makefile
hostprogs := lxdialog
always-y := $(hostprogs)
Kbuild provides the following shorthand for this::
hostprogs-always-y := lxdialog
This will tell kbuild to build lxdialog even if not referenced in
any rule.
Userspace Program support
=========================
Just like host programs, Kbuild also supports building userspace executables
for the target architecture (i.e. the same architecture as you are building
the kernel for).
The syntax is quite similar. The difference is to use ``userprogs`` instead of
``hostprogs``.
Simple Userspace Program
------------------------
The following line tells kbuild that the program bpf-direct shall be
built for the target architecture.
Example::
userprogs := bpf-direct
Kbuild assumes in the above example that bpf-direct is made from a
single C source file named bpf-direct.c located in the same directory
as the Makefile.
Composite Userspace Programs
----------------------------
Userspace programs can be made up based on composite objects.
The syntax used to define composite objects for userspace programs is
similar to the syntax used for kernel objects.
$(<executable>-objs) lists all objects used to link the final
executable.
Example::
#samples/seccomp/Makefile
userprogs := bpf-fancy
bpf-fancy-objs := bpf-fancy.o bpf-helper.o
Objects with extension .o are compiled from the corresponding .c
files. In the above example, bpf-fancy.c is compiled to bpf-fancy.o
and bpf-helper.c is compiled to bpf-helper.o.
Finally, the two .o files are linked to the executable, bpf-fancy.
Note: The syntax <executable>-y is not permitted for userspace programs.
Controlling compiler options for userspace programs
---------------------------------------------------
When compiling userspace programs, it is possible to set specific flags.
The programs will always be compiled utilising $(CC) passed
the options specified in $(KBUILD_USERCFLAGS).
To set flags that will take effect for all userspace programs created
in that Makefile, use the variable userccflags.
Example::
# samples/seccomp/Makefile
userccflags += -I usr/include
To set specific flags for a single file the following construction
is used:
Example::
bpf-helper-userccflags += -I user/include
It is also possible to specify additional options to the linker.
Example::
# net/bpfilter/Makefile
bpfilter_umh-userldflags += -static
To specify libraries linked to a userspace program, you can use
``<executable>-userldlibs``. The ``userldlibs`` syntax specifies libraries
linked to all userspace programs created in the current Makefile.
When linking bpfilter_umh, it will be passed the extra option -static.
From command line, :ref:`USERCFLAGS and USERLDFLAGS <userkbuildflags>` will also be used.
When userspace programs are actually built
------------------------------------------
Kbuild builds userspace programs only when told to do so.
There are two ways to do this.
(1) Add it as the prerequisite of another file
Example::
#net/bpfilter/Makefile
userprogs := bpfilter_umh
$(obj)/bpfilter_umh_blob.o: $(obj)/bpfilter_umh
$(obj)/bpfilter_umh is built before $(obj)/bpfilter_umh_blob.o
(2) Use always-y
Example::
userprogs := binderfs_example
always-y := $(userprogs)
Kbuild provides the following shorthand for this::
userprogs-always-y := binderfs_example
This will tell Kbuild to build binderfs_example when it visits this
Makefile.
Kbuild clean infrastructure
===========================
``make clean`` deletes most generated files in the obj tree where the kernel
is compiled. This includes generated files such as host programs.
Kbuild knows targets listed in $(hostprogs), $(always-y), $(always-m),
$(always-), $(extra-y), $(extra-) and $(targets). They are all deleted
during ``make clean``. Files matching the patterns ``*.[oas]``, ``*.ko``, plus
some additional files generated by kbuild are deleted all over the kernel
source tree when ``make clean`` is executed.
Additional files or directories can be specified in kbuild makefiles by use of
$(clean-files).
Example::
#lib/Makefile
clean-files := crc32table.h
When executing ``make clean``, the file ``crc32table.h`` will be deleted.
Kbuild will assume files to be in the same relative directory as the
Makefile.
To exclude certain files or directories from make clean, use the
$(no-clean-files) variable.
Usually kbuild descends down in subdirectories due to ``obj-* := dir/``,
but in the architecture makefiles where the kbuild infrastructure
is not sufficient this sometimes needs to be explicit.
Example::
#arch/x86/boot/Makefile
subdir- := compressed
The above assignment instructs kbuild to descend down in the
directory compressed/ when ``make clean`` is executed.
Note 1: arch/$(SRCARCH)/Makefile cannot use ``subdir-``, because that file is
included in the top level makefile. Instead, arch/$(SRCARCH)/Kbuild can use
``subdir-``.
Note 2: All directories listed in core-y, libs-y, drivers-y and net-y will
be visited during ``make clean``.
Architecture Makefiles
======================
The top level Makefile sets up the environment and does the preparation,
before starting to descend down in the individual directories.
The top level makefile contains the generic part, whereas
arch/$(SRCARCH)/Makefile contains what is required to set up kbuild
for said architecture.
To do so, arch/$(SRCARCH)/Makefile sets up a number of variables and defines
a few targets.
When kbuild executes, the following steps are followed (roughly):
1) Configuration of the kernel => produce .config
2) Store kernel version in include/linux/version.h
3) Updating all other prerequisites to the target prepare:
- Additional prerequisites are specified in arch/$(SRCARCH)/Makefile
4) Recursively descend down in all directories listed in
init-* core* drivers-* net-* libs-* and build all targets.
- The values of the above variables are expanded in arch/$(SRCARCH)/Makefile.
5) All object files are then linked and the resulting file vmlinux is
located at the root of the obj tree.
The very first objects linked are listed in scripts/head-object-list.txt.
6) Finally, the architecture-specific part does any required post processing
and builds the final bootimage.
- This includes building boot records
- Preparing initrd images and the like
Set variables to tweak the build to the architecture
----------------------------------------------------
KBUILD_LDFLAGS
Generic $(LD) options
Flags used for all invocations of the linker.
Often specifying the emulation is sufficient.
Example::
#arch/s390/Makefile
KBUILD_LDFLAGS := -m elf_s390
Note: ldflags-y can be used to further customise
the flags used. See `Non-builtin vmlinux targets - extra-y`_.
LDFLAGS_vmlinux
Options for $(LD) when linking vmlinux
LDFLAGS_vmlinux is used to specify additional flags to pass to
the linker when linking the final vmlinux image.
LDFLAGS_vmlinux uses the LDFLAGS_$@ support.
Example::
#arch/x86/Makefile
LDFLAGS_vmlinux := -e stext
OBJCOPYFLAGS
objcopy flags
When $(call if_changed,objcopy) is used to translate a .o file,
the flags specified in OBJCOPYFLAGS will be used.
$(call if_changed,objcopy) is often used to generate raw binaries on
vmlinux.
Example::
#arch/s390/Makefile
OBJCOPYFLAGS := -O binary
#arch/s390/boot/Makefile
$(obj)/image: vmlinux FORCE
$(call if_changed,objcopy)
In this example, the binary $(obj)/image is a binary version of
vmlinux. The usage of $(call if_changed,xxx) will be described later.
KBUILD_AFLAGS
Assembler flags
Default value - see top level Makefile.
Append or modify as required per architecture.
Example::
#arch/sparc64/Makefile
KBUILD_AFLAGS += -m64 -mcpu=ultrasparc
KBUILD_CFLAGS
$(CC) compiler flags
Default value - see top level Makefile.
Append or modify as required per architecture.
Often, the KBUILD_CFLAGS variable depends on the configuration.
Example::
#arch/x86/boot/compressed/Makefile
cflags-$(CONFIG_X86_32) := -march=i386
cflags-$(CONFIG_X86_64) := -mcmodel=small
KBUILD_CFLAGS += $(cflags-y)
Many arch Makefiles dynamically run the target C compiler to
probe supported options::
#arch/x86/Makefile
...
cflags-$(CONFIG_MPENTIUMII) += $(call cc-option,\
-march=pentium2,-march=i686)
...
# Disable unit-at-a-time mode ...
KBUILD_CFLAGS += $(call cc-option,-fno-unit-at-a-time)
...
The first example utilises the trick that a config option expands
to "y" when selected.
KBUILD_RUSTFLAGS
$(RUSTC) compiler flags
Default value - see top level Makefile.
Append or modify as required per architecture.
Often, the KBUILD_RUSTFLAGS variable depends on the configuration.
Note that target specification file generation (for ``--target``)
is handled in ``scripts/generate_rust_target.rs``.
KBUILD_AFLAGS_KERNEL
Assembler options specific for built-in
$(KBUILD_AFLAGS_KERNEL) contains extra C compiler flags used to compile
resident kernel code.
KBUILD_AFLAGS_MODULE
Assembler options specific for modules
$(KBUILD_AFLAGS_MODULE) is used to add arch-specific options that
are used for assembler.
From commandline AFLAGS_MODULE shall be used (see kbuild.rst).
KBUILD_CFLAGS_KERNEL
$(CC) options specific for built-in
$(KBUILD_CFLAGS_KERNEL) contains extra C compiler flags used to compile
resident kernel code.
KBUILD_CFLAGS_MODULE
Options for $(CC) when building modules
$(KBUILD_CFLAGS_MODULE) is used to add arch-specific options that
are used for $(CC).
From commandline CFLAGS_MODULE shall be used (see kbuild.rst).
KBUILD_RUSTFLAGS_KERNEL
$(RUSTC) options specific for built-in
$(KBUILD_RUSTFLAGS_KERNEL) contains extra Rust compiler flags used to
compile resident kernel code.
KBUILD_RUSTFLAGS_MODULE
Options for $(RUSTC) when building modules
$(KBUILD_RUSTFLAGS_MODULE) is used to add arch-specific options that
are used for $(RUSTC).
From commandline RUSTFLAGS_MODULE shall be used (see kbuild.rst).
KBUILD_LDFLAGS_MODULE
Options for $(LD) when linking modules
$(KBUILD_LDFLAGS_MODULE) is used to add arch-specific options
used when linking modules. This is often a linker script.
From commandline LDFLAGS_MODULE shall be used (see kbuild.rst).
KBUILD_LDS
The linker script with full path. Assigned by the top-level Makefile.
KBUILD_VMLINUX_OBJS
All object files for vmlinux. They are linked to vmlinux in the same
order as listed in KBUILD_VMLINUX_OBJS.
The objects listed in scripts/head-object-list.txt are exceptions;
they are placed before the other objects.
KBUILD_VMLINUX_LIBS
All .a ``lib`` files for vmlinux. KBUILD_VMLINUX_OBJS and
KBUILD_VMLINUX_LIBS together specify all the object files used to
link vmlinux.
Add prerequisites to archheaders
--------------------------------
The archheaders: rule is used to generate header files that
may be installed into user space by ``make header_install``.
It is run before ``make archprepare`` when run on the
architecture itself.
Add prerequisites to archprepare
--------------------------------
The archprepare: rule is used to list prerequisites that need to be
built before starting to descend down in the subdirectories.
This is usually used for header files containing assembler constants.
Example::
#arch/arm/Makefile
archprepare: maketools
In this example, the file target maketools will be processed
before descending down in the subdirectories.
See also chapter XXX-TODO that describes how kbuild supports
generating offset header files.
List directories to visit when descending
-----------------------------------------
An arch Makefile cooperates with the top Makefile to define variables
which specify how to build the vmlinux file. Note that there is no
corresponding arch-specific section for modules; the module-building
machinery is all architecture-independent.
core-y, libs-y, drivers-y
$(libs-y) lists directories where a lib.a archive can be located.
The rest list directories where a built-in.a object file can be
located.
Then the rest follows in this order:
$(core-y), $(libs-y), $(drivers-y)
The top level Makefile defines values for all generic directories,
and arch/$(SRCARCH)/Makefile only adds architecture-specific
directories.
Example::
# arch/sparc/Makefile
core-y += arch/sparc/
libs-y += arch/sparc/prom/
libs-y += arch/sparc/lib/
drivers-$(CONFIG_PM) += arch/sparc/power/
Architecture-specific boot images
---------------------------------
An arch Makefile specifies goals that take the vmlinux file, compress
it, wrap it in bootstrapping code, and copy the resulting files
somewhere. This includes various kinds of installation commands.
The actual goals are not standardized across architectures.
It is common to locate any additional processing in a boot/
directory below arch/$(SRCARCH)/.
Kbuild does not provide any smart way to support building a
target specified in boot/. Therefore arch/$(SRCARCH)/Makefile shall
call make manually to build a target in boot/.
The recommended approach is to include shortcuts in
arch/$(SRCARCH)/Makefile, and use the full path when calling down
into the arch/$(SRCARCH)/boot/Makefile.
Example::
#arch/x86/Makefile
boot := arch/x86/boot
bzImage: vmlinux
$(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
``$(Q)$(MAKE) $(build)=<dir>`` is the recommended way to invoke
make in a subdirectory.
There are no rules for naming architecture-specific targets,
but executing ``make help`` will list all relevant targets.
To support this, $(archhelp) must be defined.
Example::
#arch/x86/Makefile
define archhelp
echo '* bzImage - Compressed kernel image (arch/x86/boot/bzImage)'
endif
When make is executed without arguments, the first goal encountered
will be built. In the top level Makefile the first goal present
is all:.
An architecture shall always, per default, build a bootable image.
In ``make help``, the default goal is highlighted with a ``*``.
Add a new prerequisite to all: to select a default goal different
from vmlinux.
Example::
#arch/x86/Makefile
all: bzImage
When ``make`` is executed without arguments, bzImage will be built.
Commands useful for building a boot image
-----------------------------------------
Kbuild provides a few macros that are useful when building a
boot image.
ld
Link target. Often, LDFLAGS_$@ is used to set specific options to ld.
Example::
#arch/x86/boot/Makefile
LDFLAGS_bootsect := -Ttext 0x0 -s --oformat binary
LDFLAGS_setup := -Ttext 0x0 -s --oformat binary -e begtext
targets += setup setup.o bootsect bootsect.o
$(obj)/setup $(obj)/bootsect: %: %.o FORCE
$(call if_changed,ld)
In this example, there are two possible targets, requiring different
options to the linker. The linker options are specified using the
LDFLAGS_$@ syntax - one for each potential target.
$(targets) are assigned all potential targets, by which kbuild knows
the targets and will:
1) check for commandline changes
2) delete target during make clean
The ``: %: %.o`` part of the prerequisite is a shorthand that
frees us from listing the setup.o and bootsect.o files.
Note:
It is a common mistake to forget the ``targets :=`` assignment,
resulting in the target file being recompiled for no
obvious reason.
objcopy
Copy binary. Uses OBJCOPYFLAGS usually specified in
arch/$(SRCARCH)/Makefile.
OBJCOPYFLAGS_$@ may be used to set additional options.
gzip
Compress target. Use maximum compression to compress target.
Example::
#arch/x86/boot/compressed/Makefile
$(obj)/vmlinux.bin.gz: $(vmlinux.bin.all-y) FORCE
$(call if_changed,gzip)
dtc
Create flattened device tree blob object suitable for linking
into vmlinux. Device tree blobs linked into vmlinux are placed
in an init section in the image. Platform code *must* copy the
blob to non-init memory prior to calling unflatten_device_tree().
To use this command, simply add ``*.dtb`` into obj-y or targets, or make
some other target depend on ``%.dtb``
A central rule exists to create ``$(obj)/%.dtb`` from ``$(src)/%.dts``;
architecture Makefiles do no need to explicitly write out that rule.
Example::
targets += $(dtb-y)
DTC_FLAGS ?= -p 1024
Preprocessing linker scripts
----------------------------
When the vmlinux image is built, the linker script
arch/$(SRCARCH)/kernel/vmlinux.lds is used.
The script is a preprocessed variant of the file vmlinux.lds.S
located in the same directory.
kbuild knows .lds files and includes a rule ``*lds.S`` -> ``*lds``.
Example::
#arch/x86/kernel/Makefile
extra-y := vmlinux.lds
The assignment to extra-y is used to tell kbuild to build the
target vmlinux.lds.
The assignment to $(CPPFLAGS_vmlinux.lds) tells kbuild to use the
specified options when building the target vmlinux.lds.
When building the ``*.lds`` target, kbuild uses the variables::
KBUILD_CPPFLAGS : Set in top-level Makefile
cppflags-y : May be set in the kbuild makefile
CPPFLAGS_$(@F) : Target-specific flags.
Note that the full filename is used in this
assignment.
The kbuild infrastructure for ``*lds`` files is used in several
architecture-specific files.
Generic header files
--------------------
The directory include/asm-generic contains the header files
that may be shared between individual architectures.
The recommended approach how to use a generic header file is
to list the file in the Kbuild file.
See `generic-y`_ for further info on syntax etc.
Post-link pass
--------------
If the file arch/xxx/Makefile.postlink exists, this makefile
will be invoked for post-link objects (vmlinux and modules.ko)
for architectures to run post-link passes on. Must also handle
the clean target.
This pass runs after kallsyms generation. If the architecture
needs to modify symbol locations, rather than manipulate the
kallsyms, it may be easier to add another postlink target for
.tmp_vmlinux? targets to be called from link-vmlinux.sh.
For example, powerpc uses this to check relocation sanity of
the linked vmlinux file.
Kbuild syntax for exported headers
==================================
The kernel includes a set of headers that is exported to userspace.
Many headers can be exported as-is but other headers require a
minimal pre-processing before they are ready for user-space.
The pre-processing does:
- drop kernel-specific annotations
- drop include of compiler.h
- drop all sections that are kernel internal (guarded by ``ifdef __KERNEL__``)
All headers under include/uapi/, include/generated/uapi/,
arch/<arch>/include/uapi/ and arch/<arch>/include/generated/uapi/
are exported.
A Kbuild file may be defined under arch/<arch>/include/uapi/asm/ and
arch/<arch>/include/asm/ to list asm files coming from asm-generic.
See subsequent chapter for the syntax of the Kbuild file.
no-export-headers
-----------------
no-export-headers is essentially used by include/uapi/linux/Kbuild to
avoid exporting specific headers (e.g. kvm.h) on architectures that do
not support it. It should be avoided as much as possible.
generic-y
---------
If an architecture uses a verbatim copy of a header from
include/asm-generic then this is listed in the file
arch/$(SRCARCH)/include/asm/Kbuild like this:
Example::
#arch/x86/include/asm/Kbuild
generic-y += termios.h
generic-y += rtc.h
During the prepare phase of the build a wrapper include
file is generated in the directory::
arch/$(SRCARCH)/include/generated/asm
When a header is exported where the architecture uses
the generic header a similar wrapper is generated as part
of the set of exported headers in the directory::
usr/include/asm
The generated wrapper will in both cases look like the following:
Example: termios.h::
#include <asm-generic/termios.h>
generated-y
-----------
If an architecture generates other header files alongside generic-y
wrappers, generated-y specifies them.
This prevents them being treated as stale asm-generic wrappers and
removed.
Example::
#arch/x86/include/asm/Kbuild
generated-y += syscalls_32.h
mandatory-y
-----------
mandatory-y is essentially used by include/(uapi/)asm-generic/Kbuild
to define the minimum set of ASM headers that all architectures must have.
This works like optional generic-y. If a mandatory header is missing
in arch/$(SRCARCH)/include/(uapi/)/asm, Kbuild will automatically
generate a wrapper of the asm-generic one.
Kbuild Variables
================
The top Makefile exports the following variables:
VERSION, PATCHLEVEL, SUBLEVEL, EXTRAVERSION
These variables define the current kernel version. A few arch
Makefiles actually use these values directly; they should use
$(KERNELRELEASE) instead.
$(VERSION), $(PATCHLEVEL), and $(SUBLEVEL) define the basic
three-part version number, such as "2", "4", and "0". These three
values are always numeric.
$(EXTRAVERSION) defines an even tinier sublevel for pre-patches
or additional patches. It is usually some non-numeric string
such as "-pre4", and is often blank.
KERNELRELEASE
$(KERNELRELEASE) is a single string such as "2.4.0-pre4", suitable
for constructing installation directory names or showing in
version strings. Some arch Makefiles use it for this purpose.
ARCH
This variable defines the target architecture, such as "i386",
"arm", or "sparc". Some kbuild Makefiles test $(ARCH) to
determine which files to compile.
By default, the top Makefile sets $(ARCH) to be the same as the
host system architecture. For a cross build, a user may
override the value of $(ARCH) on the command line::
make ARCH=m68k ...
SRCARCH
This variable specifies the directory in arch/ to build.
ARCH and SRCARCH may not necessarily match. A couple of arch
directories are biarch, that is, a single ``arch/*/`` directory supports
both 32-bit and 64-bit.
For example, you can pass in ARCH=i386, ARCH=x86_64, or ARCH=x86.
For all of them, SRCARCH=x86 because arch/x86/ supports both i386 and
x86_64.
INSTALL_PATH
This variable defines a place for the arch Makefiles to install
the resident kernel image and System.map file.
Use this for architecture-specific install targets.
INSTALL_MOD_PATH, MODLIB
$(INSTALL_MOD_PATH) specifies a prefix to $(MODLIB) for module
installation. This variable is not defined in the Makefile but
may be passed in by the user if desired.
$(MODLIB) specifies the directory for module installation.
The top Makefile defines $(MODLIB) to
$(INSTALL_MOD_PATH)/lib/modules/$(KERNELRELEASE). The user may
override this value on the command line if desired.
INSTALL_MOD_STRIP
If this variable is specified, it will cause modules to be stripped
after they are installed. If INSTALL_MOD_STRIP is "1", then the
default option --strip-debug will be used. Otherwise, the
INSTALL_MOD_STRIP value will be used as the option(s) to the strip
command.
INSTALL_DTBS_PATH
This variable specifies a prefix for relocations required by build
roots. It defines a place for installing the device tree blobs. Like
INSTALL_MOD_PATH, it isn't defined in the Makefile, but can be passed
by the user if desired. Otherwise it defaults to the kernel install
path.
Makefile language
=================
The kernel Makefiles are designed to be run with GNU Make. The Makefiles
use only the documented features of GNU Make, but they do use many
GNU extensions.
GNU Make supports elementary list-processing functions. The kernel
Makefiles use a novel style of list building and manipulation with few
``if`` statements.
GNU Make has two assignment operators, ``:=`` and ``=``. ``:=`` performs
immediate evaluation of the right-hand side and stores an actual string
into the left-hand side. ``=`` is like a formula definition; it stores the
right-hand side in an unevaluated form and then evaluates this form each
time the left-hand side is used.
There are some cases where ``=`` is appropriate. Usually, though, ``:=``
is the right choice.
Credits
=======
- Original version made by Michael Elizabeth Chastain, <mailto:mec@shout.net>
- Updates by Kai Germaschewski <kai@tp1.ruhr-uni-bochum.de>
- Updates by Sam Ravnborg <sam@ravnborg.org>
- Language QA by Jan Engelhardt <jengelh@gmx.de>
TODO
====
- Generating offset header files.
- Add more variables to chapters 7 or 9?
3. 한국어 전문 번역
영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.
Makefile 구성과 역할
1-78이 문서는 Linux kernel Makefile을 설명합니다. Kernel build의 Makefile 체계는 top `Makefile`, kernel configuration 결과인 `.config`, `arch/$(SRCARCH)/Makefile`, 공통 rule을 담은 `scripts/Makefile.*`, 각 subdirectory의 kbuild Makefile이라는 다섯 부분으로 구성됩니다.
각 file이 build에서 맡는 역할입니다.
Top Makefile은 kernel configuration 과정에서 생성된 `.config`를 읽습니다. 주요 산출물은 resident kernel image인 `vmlinux`와 module file들이며, source tree의 subdirectory로 재귀적으로 내려가 이 goal을 build합니다.
방문할 subdirectory 목록은 kernel configuration에 따라 달라집니다. Top Makefile은 `arch/$(SRCARCH)/Makefile`을 text로 include하며, arch Makefile은 architecture-specific 정보를 top Makefile에 제공합니다.
각 subdirectory의 kbuild Makefile은 위에서 전달된 command를 수행합니다. `.config` 정보를 사용해 built-in target과 modular target을 위한 file list를 구성하고, `scripts/Makefile.*`의 공통 definition과 rule이 실제 kernel build를 수행합니다.
상위 설정이 directory별 file list와 공통 rule로 전달됩니다.
Kernel Makefile과 관계하는 사람은 네 부류입니다. User는 `make menuconfig`, `make`를 실행하지만 보통 Makefile이나 source를 읽고 수정하지 않습니다. Normal developer는 device driver, filesystem, network protocol 같은 subsystem을 개발하며 해당 kbuild Makefile을 유지하므로 전체 구조와 public kbuild interface를 알아야 합니다.
Arch developer는 sparc, x86 같은 architecture 전체를 담당해 arch Makefile과 kbuild Makefile을 모두 알아야 합니다. Kbuild developer는 build system 자체를 다루므로 모든 측면을 이해해야 합니다. 이 문서의 주 독자는 normal developer와 arch developer입니다.
Kernel 내부 Makefile 대부분은 kbuild infrastructure를 쓰는 kbuild Makefile입니다. 선호하는 file name은 `Makefile`이지만 `Kbuild`도 사용할 수 있고, 같은 directory에 둘 다 있으면 `Kbuild`가 선택됩니다. 뒤의 `Goal definitions`가 빠른 입문이며 이후 chapter가 실제 예제로 세부 문법을 설명합니다.
======================
Linux Kernel Makefiles
======================
This document describes the Linux kernel Makefiles.
Overview
========
The Makefiles have five parts::
Makefile the top Makefile.
.config the kernel configuration file.
arch/$(SRCARCH)/Makefile the arch Makefile.
scripts/Makefile.* common rules etc. for all kbuild Makefiles.
kbuild Makefiles exist in every subdirectory
The top Makefile reads the .config file, which comes from the kernel
configuration process.
The top Makefile is responsible for building two major products: vmlinux
(the resident kernel image) and modules (any module files).
It builds these goals by recursively descending into the subdirectories of
the kernel source tree.
The list of subdirectories which are visited depends upon the kernel
configuration. The top Makefile textually includes an arch Makefile
with the name arch/$(SRCARCH)/Makefile. The arch Makefile supplies
architecture-specific information to the top Makefile.
Each subdirectory has a kbuild Makefile which carries out the commands
passed down from above. The kbuild Makefile uses information from the
.config file to construct various file lists used by kbuild to build
any built-in or modular targets.
scripts/Makefile.* contains all the definitions/rules etc. that
are used to build the kernel based on the kbuild makefiles.
Who does what
=============
People have four different relationships with the kernel Makefiles.
*Users* are people who build kernels. These people type commands such as
``make menuconfig`` or ``make``. They usually do not read or edit
any kernel Makefiles (or any other source files).
*Normal developers* are people who work on features such as device
drivers, file systems, and network protocols. These people need to
maintain the kbuild Makefiles for the subsystem they are
working on. In order to do this effectively, they need some overall
knowledge about the kernel Makefiles, plus detailed knowledge about the
public interface for kbuild.
*Arch developers* are people who work on an entire architecture, such
as sparc or x86. Arch developers need to know about the arch Makefile
as well as kbuild Makefiles.
*Kbuild developers* are people who work on the kernel build system itself.
These people need to know about all aspects of the kernel Makefiles.
This document is aimed towards normal developers and arch developers.
The kbuild files
================
Most Makefiles within the kernel are kbuild Makefiles that use the
kbuild infrastructure. This chapter introduces the syntax used in the
kbuild makefiles.
The preferred name for the kbuild files are ``Makefile`` but ``Kbuild`` can
be used and if both a ``Makefile`` and a ``Kbuild`` file exists, then the ``Kbuild``
file will be used.
Section `Goal definitions`_ is a quick intro; further chapters provide
more details, with real examples.
Goal 정의와 built-in·module object
79-190Goal definition은 kbuild Makefile의 핵심입니다. Build할 file, 특별한 compile option, 재귀적으로 들어갈 subdirectory를 정의합니다. 가장 단순한 `obj-y += foo.o`는 현재 directory의 `foo.c` 또는 `foo.S`에서 `foo.o`를 build하라고 알립니다.
Module로 build하려면 `obj-m`을 사용합니다. 흔한 `obj-$(CONFIG_FOO) += foo.o`는 `CONFIG_FOO=y`이면 built-in, `m`이면 module이 되며, 둘 다 아니면 compile도 link도 하지 않습니다.
Configuration 값에 따른 object 처리입니다.
`$(obj-y)`는 `vmlinux`에 들어갈 object list를 지정합니다. Kbuild는 모두 compile한 뒤 `$(AR) rcSTP`로 하나의 `built-in.a`에 합칩니다. 이는 symbol table이 없는 thin archive이며 나중에 `scripts/link-vmlinux.sh`가 `vmlinux`에 link합니다.
`obj-y` 안의 file 순서는 중요합니다. 중복은 허용되지만 첫 instance만 `built-in.a`에 link하고 뒤의 instance는 무시합니다. `module_init()`과 `__initcall` 같은 function은 나타난 link 순서대로 boot 중 호출되므로 순서를 바꾸면 SCSI controller 감지 순서와 disk 번호까지 바뀔 수 있습니다.
ISDN 예제의 `obj-$(CONFIG_ISDN_I4L) += isdn.o`와 `obj-$(CONFIG_ISDN_PPP_BSDCOMP) += isdn_bsdcomp.o`는 각 config option이 해당 object list를 enable하는 전형적인 형태입니다.
`$(obj-m)`은 loadable kernel module로 build할 object를 지정합니다. Source file 하나로 만든 module은 `obj-m`에 object를 직접 더합니다. 예제에서 `CONFIG_ISDN_PPP_BSDCOMP=m`이면 `isdn_bsdcomp.c`에서 `isdn_bsdcomp.o` module을 만듭니다.
여러 source file로 module 하나를 만들 때도 module 이름은 `obj-*`에 넣고, 구성 object는 `$(<module_name>-y)`에 나열합니다. `obj-$(CONFIG_ISDN_I4L) += isdn.o`와 `isdn-y := isdn_net_lib.o isdn_v110.o isdn_common.o`를 쓰면 Kbuild가 세 object를 compile하고 `$(LD) -r`로 `isdn.o`를 만듭니다.
Kbuild가 composite object의 `$(<module_name>-y)`를 인식하므로 `CONFIG_` 값을 이용해 일부 object를 조건부 포함할 수 있습니다. ext2 예제에서 기본 object는 `ext2-y`에, xattr object는 `ext2-$(CONFIG_EXT2_FS_XATTR)`에 더합니다. 해당 config가 `y`일 때만 `xattr.o`, `xattr_user.o`, `xattr_trusted.o`가 composite `ext2.o`에 들어갑니다.
같은 syntax는 built-in에도 동작합니다. `CONFIG_EXT2_FS=y`이면 Kbuild가 구성 요소에서 `ext2.o`를 만든 뒤 예상대로 `built-in.a`에 link합니다.
Built-in과 module 모두 같은 구성 문법을 공유합니다.
Goal definitions
----------------
Goal definitions are the main part (heart) of the kbuild Makefile.
These lines define the files to be built, any special compilation
options, and any subdirectories to be entered recursively.
The most simple kbuild makefile contains one line:
Example::
obj-y += foo.o
This tells kbuild that there is one object in that directory, named
foo.o. foo.o will be built from foo.c or foo.S.
If foo.o shall be built as a module, the variable obj-m is used.
Therefore the following pattern is often used:
Example::
obj-$(CONFIG_FOO) += foo.o
$(CONFIG_FOO) evaluates to either y (for built-in) or m (for module).
If CONFIG_FOO is neither y nor m, then the file will not be compiled
nor linked.
Built-in object goals - obj-y
-----------------------------
The kbuild Makefile specifies object files for vmlinux
in the $(obj-y) lists. These lists depend on the kernel
configuration.
Kbuild compiles all the $(obj-y) files. It then calls
``$(AR) rcSTP`` to merge these files into one built-in.a file.
This is a thin archive without a symbol table. It will be later
linked into vmlinux by scripts/link-vmlinux.sh
The order of files in $(obj-y) is significant. Duplicates in
the lists are allowed: the first instance will be linked into
built-in.a and succeeding instances will be ignored.
Link order is significant, because certain functions
(module_init() / __initcall) will be called during boot in the
order they appear. So keep in mind that changing the link
order may e.g. change the order in which your SCSI
controllers are detected, and thus your disks are renumbered.
Example::
#drivers/isdn/i4l/Makefile
# Makefile for the kernel ISDN subsystem and device drivers.
# Each configuration option enables a list of files.
obj-$(CONFIG_ISDN_I4L) += isdn.o
obj-$(CONFIG_ISDN_PPP_BSDCOMP) += isdn_bsdcomp.o
Loadable module goals - obj-m
-----------------------------
$(obj-m) specifies object files which are built as loadable
kernel modules.
A module may be built from one source file or several source
files. In the case of one source file, the kbuild makefile
simply adds the file to $(obj-m).
Example::
#drivers/isdn/i4l/Makefile
obj-$(CONFIG_ISDN_PPP_BSDCOMP) += isdn_bsdcomp.o
Note: In this example $(CONFIG_ISDN_PPP_BSDCOMP) evaluates to "m"
If a kernel module is built from several source files, you specify
that you want to build a module in the same way as above; however,
kbuild needs to know which object files you want to build your
module from, so you have to tell it by setting a $(<module_name>-y)
variable.
Example::
#drivers/isdn/i4l/Makefile
obj-$(CONFIG_ISDN_I4L) += isdn.o
isdn-y := isdn_net_lib.o isdn_v110.o isdn_common.o
In this example, the module name will be isdn.o. Kbuild will
compile the objects listed in $(isdn-y) and then run
``$(LD) -r`` on the list of these files to generate isdn.o.
Due to kbuild recognizing $(<module_name>-y) for composite objects,
you can use the value of a ``CONFIG_`` symbol to optionally include an
object file as part of a composite object.
Example::
#fs/ext2/Makefile
obj-$(CONFIG_EXT2_FS) += ext2.o
ext2-y := balloc.o dir.o file.o ialloc.o inode.o ioctl.o \
namei.o super.o symlink.o
ext2-$(CONFIG_EXT2_FS_XATTR) += xattr.o xattr_user.o \
xattr_trusted.o
In this example, xattr.o, xattr_user.o and xattr_trusted.o are only
part of the composite object ext2.o if $(CONFIG_EXT2_FS_XATTR)
evaluates to "y".
Note: Of course, when you are building objects into the kernel,
the syntax above will also work. So, if you have CONFIG_EXT2_FS=y,
kbuild will build an ext2.o file for you out of the individual
parts and then link this into built-in.a, as you would expect.
Library·subdirectory·항상 build되는 goal
191-318`obj-*`에 나열한 object는 module로 사용되거나 해당 directory의 `built-in.a`에 합쳐집니다. 별도의 `lib-y`에는 `lib.a`에 넣을 object를 나열할 수 있으며, 이 directory의 모든 `lib-y` object를 하나의 library로 합칩니다.
`obj-y`와 `lib-y`에 동시에 있는 object는 이미 접근 가능하므로 library에는 넣지 않습니다. 일관성을 위해 `lib-m`에 나열한 object는 `lib.a`에 포함됩니다. 하나의 kbuild Makefile이 built-in file과 library file을 함께 선언할 수 있어 같은 directory에 `built-in.a`와 `lib.a`가 모두 생길 수 있습니다.
`arch/x86/lib/Makefile`의 `lib-y := delay.o`는 `delay.o` 기반 `lib.a`를 만듭니다. Kbuild가 이 library를 실제로 인식하려면 directory가 `libs-y`에도 나열되어야 합니다. `lib-y`는 보통 `lib/`와 `arch/*/lib`에서만 사용합니다.
Makefile은 자기 directory의 object만 담당하고 subdirectory file은 그 안의 Makefile이 담당합니다. 상위 Makefile이 directory를 알려 주면 build system이 재귀적으로 make를 호출합니다. 이 목적에도 `obj-y`, `obj-m`을 사용합니다.
`fs/Makefile`의 `obj-$(CONFIG_EXT2_FS) += ext2/`는 config가 `y` 또는 `m`일 때 ext2 directory로 내려갑니다. Kbuild는 방문 여부뿐 아니라 그 directory의 object를 `vmlinux`에 link할지도 결정합니다.
`y`로 내려가면 directory의 built-in object를 `built-in.a`에 합쳐 최종 `vmlinux`에 link합니다. `m`으로 내려가면 그 directory의 어떤 것도 `vmlinux`에 link하지 않습니다. 그런데 하위 Makefile이 `obj-y`를 선언하면 그 object가 고립되므로 Makefile 또는 Kconfig dependency의 bug일 가능성이 큽니다.
Kernel-space object가 전혀 없는 tool directory처럼 단순히 방문만 해야 할 때는 `subdir-y`, `subdir-m` 전용 syntax를 사용할 수 있습니다. `scripts/Makefile`은 GCC plugin, genksyms, SELinux tool directory를 config에 따라 방문합니다. `obj-y/m`과 달리 directory 전용 문법이라 trailing slash가 필요 없습니다.
Directory 이름을 넣을 때 `CONFIG_` variable을 쓰는 것이 좋습니다. Option이 `y`도 `m`도 아니면 Kbuild가 directory 전체를 건너뛸 수 있습니다.
하위 directory의 kernel object link 여부를 구분합니다.
`extra-y`는 `vmlinux` build에는 필요하지만 `built-in.a`에 합치지 않는 target을 지정합니다. 대표적으로 `arch/$(SRCARCH)/kernel/vmlinux.lds` linker script가 있습니다. 현재 `extra-y`는 deprecated이며 `always-$(KBUILD_BUILTIN) += vmlinux.lds`와 같습니다.
`extra-y`에는 `vmlinux`에만 필요한 target을 넣어야 합니다. `make modules`나 external module build처럼 `vmlinux`가 최종 goal이 아니면 Kbuild가 건너뜁니다. 무조건 build할 target은 `always-y`가 맞습니다.
`always-y`는 Kbuild가 해당 Makefile을 방문할 때 문자 그대로 항상 build할 target을 지정합니다. 예제의 `offsets-file := include/generated/asm-offsets.h`와 `always-y += $(offsets-file)`는 generated offsets header를 항상 만듭니다.
Library file goals - lib-y
--------------------------
Objects listed with obj-* are used for modules, or
combined in a built-in.a for that specific directory.
There is also the possibility to list objects that will
be included in a library, lib.a.
All objects listed with lib-y are combined in a single
library for that directory.
Objects that are listed in obj-y and additionally listed in
lib-y will not be included in the library, since they will
be accessible anyway.
For consistency, objects listed in lib-m will be included in lib.a.
Note that the same kbuild makefile may list files to be built-in
and to be part of a library. Therefore the same directory
may contain both a built-in.a and a lib.a file.
Example::
#arch/x86/lib/Makefile
lib-y := delay.o
This will create a library lib.a based on delay.o. For kbuild to
actually recognize that there is a lib.a being built, the directory
shall be listed in libs-y.
See also `List directories to visit when descending`_.
Use of lib-y is normally restricted to ``lib/`` and ``arch/*/lib``.
Descending down in directories
------------------------------
A Makefile is only responsible for building objects in its own
directory. Files in subdirectories should be taken care of by
Makefiles in these subdirs. The build system will automatically
invoke make recursively in subdirectories, provided you let it know of
them.
To do so, obj-y and obj-m are used.
ext2 lives in a separate directory, and the Makefile present in fs/
tells kbuild to descend down using the following assignment.
Example::
#fs/Makefile
obj-$(CONFIG_EXT2_FS) += ext2/
If CONFIG_EXT2_FS is set to either "y" (built-in) or "m" (modular)
the corresponding obj- variable will be set, and kbuild will descend
down in the ext2 directory.
Kbuild uses this information not only to decide that it needs to visit
the directory, but also to decide whether or not to link objects from
the directory into vmlinux.
When Kbuild descends into the directory with "y", all built-in objects
from that directory are combined into the built-in.a, which will be
eventually linked into vmlinux.
When Kbuild descends into the directory with "m", in contrast, nothing
from that directory will be linked into vmlinux. If the Makefile in
that directory specifies obj-y, those objects will be left orphan.
It is very likely a bug of the Makefile or of dependencies in Kconfig.
Kbuild also supports dedicated syntax, subdir-y and subdir-m, for
descending into subdirectories. It is a good fit when you know they
do not contain kernel-space objects at all. A typical usage is to let
Kbuild descend into subdirectories to build tools.
Examples::
# scripts/Makefile
subdir-$(CONFIG_GCC_PLUGINS) += gcc-plugins
subdir-$(CONFIG_MODVERSIONS) += genksyms
subdir-$(CONFIG_SECURITY_SELINUX) += selinux
Unlike obj-y/m, subdir-y/m does not need the trailing slash since this
syntax is always used for directories.
It is good practice to use a ``CONFIG_`` variable when assigning directory
names. This allows kbuild to totally skip the directory if the
corresponding ``CONFIG_`` option is neither "y" nor "m".
Non-builtin vmlinux targets - extra-y
-------------------------------------
extra-y specifies targets which are needed for building vmlinux,
but not combined into built-in.a.
Examples are:
1) vmlinux linker script
The linker script for vmlinux is located at
arch/$(SRCARCH)/kernel/vmlinux.lds
Example::
# arch/x86/kernel/Makefile
extra-y += vmlinux.lds
extra-y is now deprecated because this is equivalent to:
always-$(KBUILD_BUILTIN) += vmlinux.lds
$(extra-y) should only contain targets needed for vmlinux.
Kbuild skips extra-y when vmlinux is apparently not a final goal.
(e.g. ``make modules``, or building external modules)
If you intend to build targets unconditionally, always-y (explained
in the next section) is the correct syntax to use.
Always built goals - always-y
-----------------------------
always-y specifies targets which are literally always built when
Kbuild visits the Makefile.
Example::
# ./Kbuild
offsets-file := include/generated/asm-offsets.h
always-y += $(offsets-file)
Compilation flags
Compile flag와 dependency 추적
319-413`ccflags-y`, `asflags-y`, `ldflags-y`는 선언된 kbuild Makefile의 recursive build에서 수행하는 일반 compiler, assembler, linker 호출에만 적용됩니다. 각각 `$(CC)`, assembler, `$(LD)` option을 지정합니다.
`ccflags-y`는 tree 전체 compile flag를 소유하는 top Makefile의 `KBUILD_CFLAGS`와 별도로 현재 directory option을 추가할 때 필요합니다. ACPI 예제는 `-Os -D_LINUX -DBUILDING_ACPICA`를 기본으로 주고 `CONFIG_ACPI_DEBUG`일 때 `-DACPI_DEBUG_OUTPUT`을 더합니다.
`asflags-y`는 assembler option이며 sparc 예제는 `-ansi`를 지정합니다. `ldflags-y`는 linker option이며 CRIS compressed boot 예제는 source tree의 architecture별 linker script를 `-T`로 넘깁니다.
`subdir-ccflags-y`, `subdir-asflags-y`는 현재 kbuild file과 모든 subdirectory에 영향을 줍니다. `subdir-*` option은 non-subdir variant보다 command line 앞쪽에 추가됩니다. `subdir-ccflags-y := -Werror`는 전체 하위 tree에 warning-as-error를 적용합니다.
`ccflags-remove-y`, `asflags-remove-y`는 compiler·assembler 호출에서 특정 flag를 제거합니다. 예제의 `ccflags-remove-$(CONFIG_MCOUNT) += -pg`는 config에 따라 `-pg`를 뺍니다.
`CFLAGS_$@`, `AFLAGS_$@`는 현재 kbuild Makefile의 특정 file command에만 적용됩니다. `$@` 부분은 실제 target file 이름입니다. `CFLAGS_$@`는 `ccflags-remove-y`보다 우선순위가 높아 제거된 compiler flag를 다시 추가할 수 있고, `AFLAGS_$@`도 `asflags-remove-y`보다 높습니다.
SCSI 예제의 `CFLAGS_aha152x.o = -DAHA152X_STAT -DAUTOCONF`는 `aha152x.o` 전용 compile flag입니다. ARM 예제는 `head.o`, `crunch-bits.o`, `iwmmxt.o`에 각각 assembly option을 지정합니다.
Kbuild compile·assemble·link option의 범위입니다.
Kbuild는 모든 prerequisite file인 `*.c`, `*.h`, 그 file들에서 사용한 모든 `CONFIG_` option, target compile에 사용한 command line을 dependency로 추적합니다. 따라서 `$(CC)` option 하나를 바꾸어도 영향을 받는 file을 다시 compile합니다.
세 종류의 입력 중 하나라도 바뀌면 target을 갱신합니다.
-----------------
ccflags-y, asflags-y and ldflags-y
These three flags apply only to the kbuild makefile in which they
are assigned. They are used for all the normal cc, as and ld
invocations happening during a recursive build.
ccflags-y specifies options for compiling with $(CC).
Example::
# drivers/acpi/acpica/Makefile
ccflags-y := -Os -D_LINUX -DBUILDING_ACPICA
ccflags-$(CONFIG_ACPI_DEBUG) += -DACPI_DEBUG_OUTPUT
This variable is necessary because the top Makefile owns the
variable $(KBUILD_CFLAGS) and uses it for compilation flags for the
entire tree.
asflags-y specifies assembler options.
Example::
#arch/sparc/kernel/Makefile
asflags-y := -ansi
ldflags-y specifies options for linking with $(LD).
Example::
#arch/cris/boot/compressed/Makefile
ldflags-y += -T $(src)/decompress_$(arch-y).lds
subdir-ccflags-y, subdir-asflags-y
The two flags listed above are similar to ccflags-y and asflags-y.
The difference is that the subdir- variants have effect for the kbuild
file where they are present and all subdirectories.
Options specified using subdir-* are added to the commandline before
the options specified using the non-subdir variants.
Example::
subdir-ccflags-y := -Werror
ccflags-remove-y, asflags-remove-y
These flags are used to remove particular flags for the compiler,
assembler invocations.
Example::
ccflags-remove-$(CONFIG_MCOUNT) += -pg
CFLAGS_$@, AFLAGS_$@
CFLAGS_$@ and AFLAGS_$@ only apply to commands in current
kbuild makefile.
$(CFLAGS_$@) specifies per-file options for $(CC). The $@
part has a literal value which specifies the file that it is for.
CFLAGS_$@ has the higher priority than ccflags-remove-y; CFLAGS_$@
can re-add compiler flags that were removed by ccflags-remove-y.
Example::
# drivers/scsi/Makefile
CFLAGS_aha152x.o = -DAHA152X_STAT -DAUTOCONF
This line specify compilation flags for aha152x.o.
$(AFLAGS_$@) is a similar feature for source files in assembly
languages.
AFLAGS_$@ has the higher priority than asflags-remove-y; AFLAGS_$@
can re-add assembler flags that were removed by asflags-remove-y.
Example::
# arch/arm/kernel/Makefile
AFLAGS_head.o := -DTEXT_OFFSET=$(TEXT_OFFSET)
AFLAGS_crunch-bits.o := -Wa,-mcpu=ep9312
AFLAGS_iwmmxt.o := -Wa,-mcpu=iwmmxt
Dependency tracking
-------------------
Kbuild tracks dependencies on the following:
1) All prerequisite files (both ``*.c`` and ``*.h``)
2) ``CONFIG_`` options used in all prerequisite files
3) Command-line used to compile target
Thus, if you change an option to $(CC) all affected files will
be re-compiled.
Custom Rules
Custom rule과 command 변경 감지
414-550Kbuild infrastructure가 필요한 기능을 제공하지 않을 때 custom rule을 사용합니다. Build 중 생성하는 header나 architecture-specific boot image 준비가 대표적입니다. Custom rule은 일반 Make rule로 작성합니다.
Kbuild는 Makefile이 있는 directory에서 실행되지 않으므로 prerequisite와 target 경로를 상대 경로 variable로 명시해야 합니다. `$(src)`는 Makefile이 있는 source directory이며 source tree file을 참조할 때 항상 사용합니다. `$(obj)`는 target이 저장되는 object directory이며 generated file과 source·generated 모두에 적용할 pattern rule에 사용합니다. VPATH가 object tree와 source tree에서 prerequisite를 찾습니다.
SCSI 예제에서 `$(obj)/53c8xx_d.h`는 `$(src)/53c7,8xx.scr`와 `$(src)/script_asm.pl`에 의존합니다. Target은 generated file이라 `$(obj)` prefix를, prerequisite는 source file이라 `$(src)` prefix를 씁니다.
`$(srcroot)`는 build 중인 source root를 가리킵니다. `KBUILD_EXTMOD` 설정 여부에 따라 kernel source 또는 external module source가 되며 상대·절대 경로일 수 있습니다. `KBUILD_ABS_SRCTREE=1`이면 항상 absolute path입니다.
`$(srctree)`는 kernel source tree root입니다. Kernel 자체를 build할 때는 `$(srcroot)`와 같습니다. `$(objtree)`는 kernel object tree root이며 kernel build에서는 `.`이지만 external module build에서는 다릅니다.
Source, object, kernel root를 혼동하지 않도록 구분합니다.
Rule에서 user에게 정보를 출력하는 것은 좋지만 `make -s`에서는 warning과 error 외 출력이 없어야 합니다. `$(kecho)`는 평소 뒤의 text를 stdout으로 출력하고 `make -s`에서는 억제합니다. ARM boot target 예제는 image가 준비되었다는 문장을 `@$(kecho)`로 표시합니다.
`KBUILD_VERBOSE`가 설정되지 않으면 보통 command 전체 대신 짧은 표시만 보여 줍니다. Custom command도 이 동작을 쓰려면 `quiet_cmd_<command>`에 표시할 text를, `cmd_<command>`에 실제 command를 정의하고 `$(call cmd,<command>)`로 실행합니다.
CRC32 table 예제는 `quiet_cmd_crc32 = GEN $@`, `cmd_crc32 = $< > $@`를 정의합니다. `$(obj)/crc32table.h`를 갱신할 때 `make KBUILD_VERBOSE=`는 `GEN lib/crc32table.h`를 표시합니다.
일반 GNU Make는 target과 prerequisite timestamp를 비교해 더 새 prerequisite가 있을 때 target을 갱신합니다. 하지만 이전 호출 이후 command line이 바뀐 경우도 rebuild해야 하며 Make 자체는 이를 지원하지 않습니다. Kbuild는 meta-programming 성격의 `if_changed` macro로 해결합니다.
`if_changed` rule은 `quiet_cmd_<command>`, `cmd_<command>`를 정의하고 target에 source와 `FORCE` prerequisite를 둔 뒤 `$(call if_changed,<command>)`를 실행합니다.
`if_changed`를 쓰는 target은 반드시 `$(targets)`에 있어야 합니다. 그렇지 않으면 command line check가 실패해 항상 build됩니다. `obj-y/m`, `lib-y/m`, `extra-y/m`, `always-y/m`, `hostprogs`, `userprogs`처럼 인식되는 syntax에 이미 있으면 Kbuild가 자동 추가하며, 그 외에는 직접 `targets`에 넣습니다. Assignment에는 `$(obj)/` prefix를 쓰지 않습니다.
`FORCE` prerequisite 누락은 흔한 실수입니다. Whitespace도 의미가 있어 `$(call if_changed, objcopy)`처럼 comma 뒤에 space를 넣으면 실패합니다. 정확한 형태는 `$(call if_changed,objcopy)`입니다.
한 target에 `if_changed`를 두 번 이상 쓰면 안 됩니다. 실행 command를 대응 `.cmd` file에 저장하므로 여러 호출이 덮어쓰기를 일으키고, target timestamp는 최신인데 command change test만 실행을 촉발하는 경우 잘못된 결과를 냅니다.
Timestamp뿐 아니라 이전 command line까지 비교합니다.
------------
Custom rules are used when the kbuild infrastructure does
not provide the required support. A typical example is
header files generated during the build process.
Another example are the architecture-specific Makefiles which
need custom rules to prepare boot images etc.
Custom rules are written as normal Make rules.
Kbuild is not executing in the directory where the Makefile is
located, so all custom rules shall use a relative
path to prerequisite files and target files.
Two variables are used when defining custom rules:
$(src)
$(src) is the directory where the Makefile is located. Always use $(src) when
referring to files located in the src tree.
$(obj)
$(obj) is the directory where the target is saved. Always use $(obj) when
referring to generated files. Use $(obj) for pattern rules that need to work
for both generated files and real sources (VPATH will help to find the
prerequisites not only in the object tree but also in the source tree).
Example::
#drivers/scsi/Makefile
$(obj)/53c8xx_d.h: $(src)/53c7,8xx.scr $(src)/script_asm.pl
$(CPP) -DCHIP=810 - < $< | ... $(src)/script_asm.pl
This is a custom rule, following the normal syntax
required by make.
The target file depends on two prerequisite files. References
to the target file are prefixed with $(obj), references
to prerequisites are referenced with $(src) (because they are not
generated files).
$(srcroot)
$(srcroot) refers to the root of the source you are building, which can be
either the kernel source or the external modules source, depending on whether
KBUILD_EXTMOD is set. This can be either a relative or an absolute path, but
if KBUILD_ABS_SRCTREE=1 is set, it is always an absolute path.
$(srctree)
$(srctree) refers to the root of the kernel source tree. When building the
kernel, this is the same as $(srcroot).
$(objtree)
$(objtree) refers to the root of the kernel object tree. It is ``.`` when
building the kernel, but it is different when building external modules.
$(kecho)
echoing information to user in a rule is often a good practice
but when execution ``make -s`` one does not expect to see any output
except for warnings/errors.
To support this kbuild defines $(kecho) which will echo out the
text following $(kecho) to stdout except if ``make -s`` is used.
Example::
# arch/arm/Makefile
$(BOOT_TARGETS): vmlinux
$(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/$@
@$(kecho) ' Kernel: $(boot)/$@ is ready'
When kbuild is executing with KBUILD_VERBOSE unset, then only a shorthand
of a command is normally displayed.
To enable this behaviour for custom commands kbuild requires
two variables to be set::
quiet_cmd_<command> - what shall be echoed
cmd_<command> - the command to execute
Example::
# lib/Makefile
quiet_cmd_crc32 = GEN $@
cmd_crc32 = $< > $@
$(obj)/crc32table.h: $(obj)/gen_crc32table
$(call cmd,crc32)
When updating the $(obj)/crc32table.h target, the line::
GEN lib/crc32table.h
will be displayed with ``make KBUILD_VERBOSE=``.
Command change detection
------------------------
When the rule is evaluated, timestamps are compared between the target
and its prerequisite files. GNU Make updates the target when any of the
prerequisites is newer than that.
The target should be rebuilt also when the command line has changed
since the last invocation. This is not supported by Make itself, so
Kbuild achieves this by a kind of meta-programming.
if_changed is the macro used for this purpose, in the following form::
quiet_cmd_<command> = ...
cmd_<command> = ...
<target>: <source(s)> FORCE
$(call if_changed,<command>)
Any target that utilizes if_changed must be listed in $(targets),
otherwise the command line check will fail, and the target will
always be built.
If the target is already listed in the recognized syntax such as
obj-y/m, lib-y/m, extra-y/m, always-y/m, hostprogs, userprogs, Kbuild
automatically adds it to $(targets). Otherwise, the target must be
explicitly added to $(targets).
Assignments to $(targets) are without $(obj)/ prefix. if_changed may be
used in conjunction with custom rules as defined in `Custom Rules`_.
Note: It is a typical mistake to forget the FORCE prerequisite.
Another common pitfall is that whitespace is sometimes significant; for
instance, the below will fail (note the extra space after the comma)::
target: source(s) FORCE
**WRONG!** $(call if_changed, objcopy)
Note:
if_changed should not be used more than once per target.
It stores the executed command in a corresponding .cmd
file and multiple calls would result in overwrites and
unwanted results when the target is up to date and only the
tests on changed commands trigger execution of commands.
$(CC) support functions
Compiler·linker 지원 함수와 script 호출
551-722Kernel은 서로 다른 version의 `$(CC)`로 build될 수 있고 각 compiler가 지원하는 feature와 option이 다릅니다. Kbuild는 compiler option 유효성을 검사하는 기본 함수를 제공합니다. `$(CC)`는 보통 GCC지만 다른 compiler도 가능합니다.
`as-option`은 `*.S`를 compile할 때 `$(CC)`가 주어진 assembler option을 지원하는지 확인하고, 첫 option이 지원되지 않을 때 쓸 두 번째 option을 선택적으로 받습니다. SH 예제는 지원되는 경우 `-Wa$(comma)-isa=$(isa-y)`를 `cflags-y`에 넣습니다.
`as-instr`은 assembler가 특정 instruction을 받아들이는지 검사해 `option1` 또는 `option2`를 출력합니다. Test instruction에는 C escape를 쓸 수 있으며 `as-instr-option`은 assembler option으로 `KBUILD_AFLAGS`를 사용합니다.
`cc-option`은 `$(CC)`가 option을 지원하는지 검사하고, 미지원이면 선택적인 두 번째 option을 사용합니다. x86 예제는 `-march=pentium-mmx`가 가능하면 선택하고 아니면 `-march=i586`을 씁니다. 두 번째 인자를 생략하고 첫 option이 미지원이면 아무 값도 추가하지 않습니다. 이 함수는 compiler option에 `KBUILD_CFLAGS`를 사용합니다.
`cc-option-yn`은 option 지원 여부를 `y` 또는 `n`으로 반환합니다. PowerPC 예제는 `-m32` 지원 결과를 `biarch`에 넣고 `y`일 때 assembler `-a32`, compiler `-m32`를 추가합니다. 이 함수도 `KBUILD_CFLAGS`를 사용합니다.
`cc-disable-warning`은 compiler가 특정 warning을 인식할 때 이를 끄는 command-line switch를 반환합니다. GCC 4.4 이후는 알 수 없는 `-Wno-*` option을 받아들이고 source에 다른 warning이 있을 때만 경고하기 때문에 전용 검사가 필요합니다. 예제는 실제 지원할 때만 `-Wno-unused-but-set-variable`을 추가합니다.
`gcc-min-version`은 `CONFIG_GCC_VERSION`이 주어진 값 이상이면 `y`입니다. `110100`은 GCC 11.1 이상을 뜻합니다. `clang-min-version`도 `CONFIG_CLANG_VERSION`을 검사하며 `110000`은 Clang 11.0.0 이상입니다.
`cc-cross-prefix`는 나열한 prefix 가운데 `prefix$(CC)`가 PATH에 존재하는 첫 prefix를 반환하고 아무것도 없으면 빈 값을 반환합니다. Prefix는 space 하나로 구분합니다. Arch Makefile에서 알려진 여러 cross compiler prefix 중 하나를 고를 때 유용합니다.
`CROSS_COMPILE` 자동 설정은 host arch와 target arch가 다른 cross build에서만 시도하고, user가 이미 설정했다면 기존 값을 유지하는 것이 권장됩니다. m68k 예제는 `SUBARCH != ARCH`이고 `CROSS_COMPILE`이 비었을 때만 `m68k-linux-gnu-`를 찾습니다.
Rust의 `rustc-min-version`은 `CONFIG_RUSTC_VERSION`이 지정 값 이상인지 검사해 `y`를 반환합니다. `108500` 예제는 Rust 1.85.0 이상일 때 `rustflags-y := -Cfoo`를 설정합니다.
Linker의 `ld-option`은 `$(LD)`가 첫 option을 지원하는지 검사하고, 미지원 시 선택적 두 번째 option을 사용합니다. 예제는 `LDFLAGS_vmlinux`에 지원되는 `-X`를 추가합니다.
Compiler·assembler·linker version과 option을 안전하게 선택합니다.
Make rule이 kernel build script를 호출할 때는 항상 적절한 interpreter를 명시해야 합니다. Execute bit에 의존하거나 script를 직접 실행하면 안 됩니다. 다만 `./scripts/checkpatch.pl` 같은 수동 실행 편의를 위해 execute bit를 설정하는 것은 권장됩니다.
Kbuild는 각 script interpreter를 가리키는 `$(CONFIG_SHELL)`, `$(AWK)`, `$(PERL)`, `$(PYTHON3)` variable을 제공합니다. `depmod.sh` 예제는 `$(CONFIG_SHELL) $(srctree)/scripts/depmod.sh`로 명시적으로 실행합니다.
-----------------------
The kernel may be built with several different versions of
$(CC), each supporting a unique set of features and options.
kbuild provides basic support to check for valid options for $(CC).
$(CC) is usually the gcc compiler, but other alternatives are
available.
as-option
as-option is used to check if $(CC) -- when used to compile
assembler (``*.S``) files -- supports the given option. An optional
second option may be specified if the first option is not supported.
Example::
#arch/sh/Makefile
cflags-y += $(call as-option,-Wa$(comma)-isa=$(isa-y),)
In the above example, cflags-y will be assigned the option
-Wa$(comma)-isa=$(isa-y) if it is supported by $(CC).
The second argument is optional, and if supplied will be used
if first argument is not supported.
as-instr
as-instr checks if the assembler reports a specific instruction
and then outputs either option1 or option2
C escapes are supported in the test instruction
Note: as-instr-option uses KBUILD_AFLAGS for assembler options
cc-option
cc-option is used to check if $(CC) supports a given option, and if
not supported to use an optional second option.
Example::
#arch/x86/Makefile
cflags-y += $(call cc-option,-march=pentium-mmx,-march=i586)
In the above example, cflags-y will be assigned the option
-march=pentium-mmx if supported by $(CC), otherwise -march=i586.
The second argument to cc-option is optional, and if omitted,
cflags-y will be assigned no value if first option is not supported.
Note: cc-option uses KBUILD_CFLAGS for $(CC) options
cc-option-yn
cc-option-yn is used to check if $(CC) supports a given option
and return "y" if supported, otherwise "n".
Example::
#arch/ppc/Makefile
biarch := $(call cc-option-yn, -m32)
aflags-$(biarch) += -a32
cflags-$(biarch) += -m32
In the above example, $(biarch) is set to y if $(CC) supports the -m32
option. When $(biarch) equals "y", the expanded variables $(aflags-y)
and $(cflags-y) will be assigned the values -a32 and -m32,
respectively.
Note: cc-option-yn uses KBUILD_CFLAGS for $(CC) options
cc-disable-warning
cc-disable-warning checks if $(CC) supports a given warning and returns
the commandline switch to disable it. This special function is needed,
because gcc 4.4 and later accept any unknown -Wno-* option and only
warn about it if there is another warning in the source file.
Example::
KBUILD_CFLAGS += $(call cc-disable-warning, unused-but-set-variable)
In the above example, -Wno-unused-but-set-variable will be added to
KBUILD_CFLAGS only if $(CC) really accepts it.
gcc-min-version
gcc-min-version tests if the value of $(CONFIG_GCC_VERSION) is greater than
or equal to the provided value and evaluates to y if so.
Example::
cflags-$(call gcc-min-version, 110100) := -foo
In this example, cflags-y will be assigned the value -foo if $(CC) is gcc and
$(CONFIG_GCC_VERSION) is >= 11.1.
clang-min-version
clang-min-version tests if the value of $(CONFIG_CLANG_VERSION) is greater
than or equal to the provided value and evaluates to y if so.
Example::
cflags-$(call clang-min-version, 110000) := -foo
In this example, cflags-y will be assigned the value -foo if $(CC) is clang
and $(CONFIG_CLANG_VERSION) is >= 11.0.0.
cc-cross-prefix
cc-cross-prefix is used to check if there exists a $(CC) in path with
one of the listed prefixes. The first prefix where there exist a
prefix$(CC) in the PATH is returned - and if no prefix$(CC) is found
then nothing is returned.
Additional prefixes are separated by a single space in the
call of cc-cross-prefix.
This functionality is useful for architecture Makefiles that try
to set CROSS_COMPILE to well-known values but may have several
values to select between.
It is recommended only to try to set CROSS_COMPILE if it is a cross
build (host arch is different from target arch). And if CROSS_COMPILE
is already set then leave it with the old value.
Example::
#arch/m68k/Makefile
ifneq ($(SUBARCH),$(ARCH))
ifeq ($(CROSS_COMPILE),)
CROSS_COMPILE := $(call cc-cross-prefix, m68k-linux-gnu-)
endif
endif
$(RUSTC) support functions
--------------------------
rustc-min-version
rustc-min-version tests if the value of $(CONFIG_RUSTC_VERSION) is greater
than or equal to the provided value and evaluates to y if so.
Example::
rustflags-$(call rustc-min-version, 108500) := -Cfoo
In this example, rustflags-y will be assigned the value -Cfoo if
$(CONFIG_RUSTC_VERSION) is >= 1.85.0.
$(LD) support functions
-----------------------
ld-option
ld-option is used to check if $(LD) supports the supplied option.
ld-option takes two options as arguments.
The second argument is an optional option that can be used if the
first option is not supported by $(LD).
Example::
#Makefile
LDFLAGS_vmlinux += $(call ld-option, -X)
Script invocation
-----------------
Make rules may invoke scripts to build the kernel. The rules shall
always provide the appropriate interpreter to execute the script. They
shall not rely on the execute bits being set, and shall not invoke the
script directly. For the convenience of manual script invocation, such
as invoking ./scripts/checkpatch.pl, it is recommended to set execute
bits on the scripts nonetheless.
Kbuild provides variables $(CONFIG_SHELL), $(AWK), $(PERL),
and $(PYTHON3) to refer to interpreters for the respective
scripts.
Example::
#Makefile
cmd_depmod = $(CONFIG_SHELL) $(srctree)/scripts/depmod.sh $(DEPMOD) \
$(KERNELRELEASE)
Host program build
723-893Kbuild는 compile 단계에서 사용할 host executable build를 지원합니다. 첫째 `hostprogs`에 program 존재를 알리고, 둘째 executable에 명시적인 dependency를 추가해야 합니다. Dependency는 custom rule prerequisite 또는 `always-y`로 지정합니다.
단순 host program `hostprogs := bin2hex`는 Makefile과 같은 directory의 `bin2hex.c` 하나에서 build host용 `bin2hex`를 만든다고 가정합니다.
Composite host program은 kernel object와 비슷하게 `$(<executable>-objs)`에 최종 executable을 link할 object를 나열합니다. `lxdialog-objs := checklist.o lxdialog.o`는 각 C source를 compile한 뒤 두 object를 `lxdialog`로 link합니다. Host program에는 `<executable>-y` syntax를 사용할 수 없습니다.
Kbuild는 C++ host program도 지원하지만 kconfig 지원만을 위해 도입되었고 일반 사용에는 권장되지 않습니다. `qconf-cxxobjs := qconf.o`는 `qconf.cc`를 식별합니다. C와 C++를 섞으면 `qconf-cxxobjs`에 C++ object, `qconf-objs`에 C object를 나열합니다.
Rust host program도 지원합니다. Kernel compile에 Rust toolchain이 필수가 아니므로 `CONFIG_RUST`가 enable된 경우처럼 Rust가 반드시 있는 상황에서만 사용할 수 있습니다. `hostprogs := target`, `target-rust := y`는 같은 directory의 `target.rs`를 crate root로 compile합니다. Crate는 `samples/rust/hostprogs`처럼 여러 source file로 구성할 수 있습니다.
언어와 구성 방식에 따른 선언입니다.
Host program은 항상 `$(HOSTCC)`와 `$(KBUILD_HOSTCFLAGS)` option으로 compile합니다. 현재 Makefile에서 생성하는 모든 host program에 flag를 더하려면 `HOST_EXTRACFLAGS`를 사용합니다. `HOST_EXTRACFLAGS += -I/usr/include/ncurses`가 예입니다.
단일 file에는 `HOSTCFLAGS_<file>.o`를 사용합니다. `HOSTCFLAGS_piggyback.o := -DKERNELBASE=$(KERNELBASE)`가 예입니다. Linker 추가 option은 `HOSTLDLIBS_<executable>`에 두며 `HOSTLDLIBS_qconf := -L$(QTDIR)/lib`는 qconf link 시 library path를 추가합니다.
Kbuild는 host program이 prerequisite로 참조될 때만 build합니다. Custom rule에 명시하는 방법에서는 `$(obj)/devlist.h`가 `$(obj)/gen-devlist`에 의존해 generator가 먼저 갱신됩니다. Custom rule에서 host program reference는 반드시 `$(obj)` prefix를 붙입니다.
적합한 custom rule이 없고 Makefile 방문 시 host program을 build해야 하면 `always-y := $(hostprogs)`를 씁니다. Short-hand `hostprogs-always-y := lxdialog`도 같으며 다른 rule에서 참조하지 않아도 build합니다.
Generator 선언만으로는 build되지 않으므로 소비 target과 연결해야 합니다.
Host Program support
====================
Kbuild supports building executables on the host for use during the
compilation stage.
Two steps are required in order to use a host executable.
The first step is to tell kbuild that a host program exists. This is
done utilising the variable ``hostprogs``.
The second step is to add an explicit dependency to the executable.
This can be done in two ways. Either add the dependency in a rule,
or utilise the variable ``always-y``.
Both possibilities are described in the following.
Simple Host Program
-------------------
In some cases there is a need to compile and run a program on the
computer where the build is running.
The following line tells kbuild that the program bin2hex shall be
built on the build host.
Example::
hostprogs := bin2hex
Kbuild assumes in the above example that bin2hex is made from a single
c-source file named bin2hex.c located in the same directory as
the Makefile.
Composite Host Programs
-----------------------
Host programs can be made up based on composite objects.
The syntax used to define composite objects for host programs is
similar to the syntax used for kernel objects.
$(<executable>-objs) lists all objects used to link the final
executable.
Example::
#scripts/lxdialog/Makefile
hostprogs := lxdialog
lxdialog-objs := checklist.o lxdialog.o
Objects with extension .o are compiled from the corresponding .c
files. In the above example, checklist.c is compiled to checklist.o
and lxdialog.c is compiled to lxdialog.o.
Finally, the two .o files are linked to the executable, lxdialog.
Note: The syntax <executable>-y is not permitted for host-programs.
Using C++ for host programs
---------------------------
kbuild offers support for host programs written in C++. This was
introduced solely to support kconfig, and is not recommended
for general use.
Example::
#scripts/kconfig/Makefile
hostprogs := qconf
qconf-cxxobjs := qconf.o
In the example above the executable is composed of the C++ file
qconf.cc - identified by $(qconf-cxxobjs).
If qconf is composed of a mixture of .c and .cc files, then an
additional line can be used to identify this.
Example::
#scripts/kconfig/Makefile
hostprogs := qconf
qconf-cxxobjs := qconf.o
qconf-objs := check.o
Using Rust for host programs
----------------------------
Kbuild offers support for host programs written in Rust. However,
since a Rust toolchain is not mandatory for kernel compilation,
it may only be used in scenarios where Rust is required to be
available (e.g. when ``CONFIG_RUST`` is enabled).
Example::
hostprogs := target
target-rust := y
Kbuild will compile ``target`` using ``target.rs`` as the crate root,
located in the same directory as the ``Makefile``. The crate may
consist of several source files (see ``samples/rust/hostprogs``).
Controlling compiler options for host programs
----------------------------------------------
When compiling host programs, it is possible to set specific flags.
The programs will always be compiled utilising $(HOSTCC) passed
the options specified in $(KBUILD_HOSTCFLAGS).
To set flags that will take effect for all host programs created
in that Makefile, use the variable HOST_EXTRACFLAGS.
Example::
#scripts/lxdialog/Makefile
HOST_EXTRACFLAGS += -I/usr/include/ncurses
To set specific flags for a single file the following construction
is used:
Example::
#arch/ppc64/boot/Makefile
HOSTCFLAGS_piggyback.o := -DKERNELBASE=$(KERNELBASE)
It is also possible to specify additional options to the linker.
Example::
#scripts/kconfig/Makefile
HOSTLDLIBS_qconf := -L$(QTDIR)/lib
When linking qconf, it will be passed the extra option
``-L$(QTDIR)/lib``.
When host programs are actually built
-------------------------------------
Kbuild will only build host-programs when they are referenced
as a prerequisite.
This is possible in two ways:
(1) List the prerequisite explicitly in a custom rule.
Example::
#drivers/pci/Makefile
hostprogs := gen-devlist
$(obj)/devlist.h: $(src)/pci.ids $(obj)/gen-devlist
( cd $(obj); ./gen-devlist ) < $<
The target $(obj)/devlist.h will not be built before
$(obj)/gen-devlist is updated. Note that references to
the host programs in custom rules must be prefixed with $(obj).
(2) Use always-y
When there is no suitable custom rule, and the host program
shall be built when a makefile is entered, the always-y
variable shall be used.
Example::
#scripts/lxdialog/Makefile
hostprogs := lxdialog
always-y := $(hostprogs)
Kbuild provides the following shorthand for this::
hostprogs-always-y := lxdialog
This will tell kbuild to build lxdialog even if not referenced in
any rule.
Target userspace program과 clean
894-1051Kbuild는 host program과 마찬가지로 kernel target architecture용 userspace executable도 build합니다. 문법은 비슷하지만 `hostprogs` 대신 `userprogs`를 사용합니다.
`userprogs := bpf-direct`는 Makefile과 같은 directory의 `bpf-direct.c` 하나에서 target architecture용 program을 만든다고 가정합니다. Composite program은 `$(<executable>-objs)`에 object를 나열합니다. seccomp 예제의 `bpf-fancy-objs := bpf-fancy.o bpf-helper.o`는 두 C source를 compile해 `bpf-fancy`로 link합니다. `<executable>-y`는 허용되지 않습니다.
Userspace program은 `$(CC)`와 `$(KBUILD_USERCFLAGS)` option으로 compile합니다. 현재 Makefile의 모든 userspace program에 적용할 flag는 `userccflags`, 특정 file flag는 `<file>-userccflags`에 둡니다.
Linker 추가 option은 `<executable>-userldflags`를 사용합니다. `bpfilter_umh-userldflags += -static`은 static link를 요청합니다. 특정 executable library는 `<executable>-userldlibs`, 현재 Makefile의 모든 userspace program library는 `userldlibs`에 지정합니다. Command line의 `USERCFLAGS`, `USERLDFLAGS`도 사용됩니다.
Target architecture용 executable의 compile·link 설정입니다.
Userspace program도 명시적으로 요청할 때만 build합니다. 다른 file의 prerequisite로 추가하면 먼저 build됩니다. `$(obj)/bpfilter_umh_blob.o: $(obj)/bpfilter_umh`가 예입니다.
또는 `always-y := $(userprogs)`를 쓰며 short-hand는 `userprogs-always-y := binderfs_example`입니다. Kbuild가 해당 Makefile을 방문할 때 program을 build합니다.
`make clean`은 kernel을 compile한 object tree의 generated file 대부분을 지웁니다. Host program도 포함됩니다. Kbuild는 `hostprogs`, `always-y`, `always-m`, `always-`, `extra-y`, `extra-`, `targets`에 나열된 target을 알고 모두 삭제합니다.
또한 kernel source tree 전체에서 `*.[oas]`, `*.ko` pattern과 Kbuild가 생성한 일부 추가 file을 지웁니다. 더 지울 file이나 directory는 `clean-files`에 지정합니다. `clean-files := crc32table.h`는 Makefile과 같은 상대 directory의 file을 삭제합니다.
Clean에서 제외할 file이나 directory는 `no-clean-files`를 사용합니다. 보통 `obj-* := dir/` 때문에 subdirectory를 방문하지만 architecture Makefile에서 infrastructure가 부족하면 명시해야 할 수 있습니다. `arch/x86/boot/Makefile`의 `subdir- := compressed`는 clean 시 `compressed/`로 내려갑니다.
Top-level에 include되는 `arch/$(SRCARCH)/Makefile`은 `subdir-`를 쓸 수 없고 `arch/$(SRCARCH)/Kbuild`에서 사용해야 합니다. `core-y`, `libs-y`, `drivers-y`, `net-y`에 나열된 모든 directory는 `make clean` 중 방문합니다.
Userspace Program support
=========================
Just like host programs, Kbuild also supports building userspace executables
for the target architecture (i.e. the same architecture as you are building
the kernel for).
The syntax is quite similar. The difference is to use ``userprogs`` instead of
``hostprogs``.
Simple Userspace Program
------------------------
The following line tells kbuild that the program bpf-direct shall be
built for the target architecture.
Example::
userprogs := bpf-direct
Kbuild assumes in the above example that bpf-direct is made from a
single C source file named bpf-direct.c located in the same directory
as the Makefile.
Composite Userspace Programs
----------------------------
Userspace programs can be made up based on composite objects.
The syntax used to define composite objects for userspace programs is
similar to the syntax used for kernel objects.
$(<executable>-objs) lists all objects used to link the final
executable.
Example::
#samples/seccomp/Makefile
userprogs := bpf-fancy
bpf-fancy-objs := bpf-fancy.o bpf-helper.o
Objects with extension .o are compiled from the corresponding .c
files. In the above example, bpf-fancy.c is compiled to bpf-fancy.o
and bpf-helper.c is compiled to bpf-helper.o.
Finally, the two .o files are linked to the executable, bpf-fancy.
Note: The syntax <executable>-y is not permitted for userspace programs.
Controlling compiler options for userspace programs
---------------------------------------------------
When compiling userspace programs, it is possible to set specific flags.
The programs will always be compiled utilising $(CC) passed
the options specified in $(KBUILD_USERCFLAGS).
To set flags that will take effect for all userspace programs created
in that Makefile, use the variable userccflags.
Example::
# samples/seccomp/Makefile
userccflags += -I usr/include
To set specific flags for a single file the following construction
is used:
Example::
bpf-helper-userccflags += -I user/include
It is also possible to specify additional options to the linker.
Example::
# net/bpfilter/Makefile
bpfilter_umh-userldflags += -static
To specify libraries linked to a userspace program, you can use
``<executable>-userldlibs``. The ``userldlibs`` syntax specifies libraries
linked to all userspace programs created in the current Makefile.
When linking bpfilter_umh, it will be passed the extra option -static.
From command line, :ref:`USERCFLAGS and USERLDFLAGS <userkbuildflags>` will also be used.
When userspace programs are actually built
------------------------------------------
Kbuild builds userspace programs only when told to do so.
There are two ways to do this.
(1) Add it as the prerequisite of another file
Example::
#net/bpfilter/Makefile
userprogs := bpfilter_umh
$(obj)/bpfilter_umh_blob.o: $(obj)/bpfilter_umh
$(obj)/bpfilter_umh is built before $(obj)/bpfilter_umh_blob.o
(2) Use always-y
Example::
userprogs := binderfs_example
always-y := $(userprogs)
Kbuild provides the following shorthand for this::
userprogs-always-y := binderfs_example
This will tell Kbuild to build binderfs_example when it visits this
Makefile.
Kbuild clean infrastructure
===========================
``make clean`` deletes most generated files in the obj tree where the kernel
is compiled. This includes generated files such as host programs.
Kbuild knows targets listed in $(hostprogs), $(always-y), $(always-m),
$(always-), $(extra-y), $(extra-) and $(targets). They are all deleted
during ``make clean``. Files matching the patterns ``*.[oas]``, ``*.ko``, plus
some additional files generated by kbuild are deleted all over the kernel
source tree when ``make clean`` is executed.
Additional files or directories can be specified in kbuild makefiles by use of
$(clean-files).
Example::
#lib/Makefile
clean-files := crc32table.h
When executing ``make clean``, the file ``crc32table.h`` will be deleted.
Kbuild will assume files to be in the same relative directory as the
Makefile.
To exclude certain files or directories from make clean, use the
$(no-clean-files) variable.
Usually kbuild descends down in subdirectories due to ``obj-* := dir/``,
but in the architecture makefiles where the kbuild infrastructure
is not sufficient this sometimes needs to be explicit.
Example::
#arch/x86/boot/Makefile
subdir- := compressed
The above assignment instructs kbuild to descend down in the
directory compressed/ when ``make clean`` is executed.
Note 1: arch/$(SRCARCH)/Makefile cannot use ``subdir-``, because that file is
included in the top level makefile. Instead, arch/$(SRCARCH)/Kbuild can use
``subdir-``.
Note 2: All directories listed in core-y, libs-y, drivers-y and net-y will
be visited during ``make clean``.
Architecture Makefile과 build 변수
1052-1262Top-level Makefile은 각 directory로 내려가기 전에 environment 설정과 준비를 담당합니다. Generic 부분은 top Makefile에, architecture별 kbuild 설정은 `arch/$(SRCARCH)/Makefile`에 있습니다. Arch Makefile은 여러 variable을 설정하고 일부 target을 정의합니다.
대략적인 순서는 다음과 같습니다. Kernel configuration으로 `.config`를 만들고, kernel version을 `include/linux/version.h`에 저장하며, `prepare` target의 다른 prerequisite를 갱신합니다. 추가 prerequisite는 arch Makefile에 지정합니다.
그 다음 `init-*`, `core*`, `drivers-*`, `net-*`, `libs-*`에 나열된 모든 directory로 재귀 하강해 target을 build합니다. 이 variable 값은 arch Makefile에서 확장됩니다. 모든 object를 link한 `vmlinux`는 object tree root에 생기며 `scripts/head-object-list.txt`의 object가 가장 먼저 link됩니다.
마지막으로 architecture-specific 후처리와 최종 boot image를 만듭니다. Boot record 생성과 initrd image 준비 등이 포함됩니다.
Generic 준비에서 architecture boot image까지의 순서입니다.
`KBUILD_LDFLAGS`는 모든 linker 호출의 generic `$(LD)` option이며 보통 emulation 지정이면 충분합니다. s390 예제는 `-m elf_s390`을 사용합니다. 추가 customization에는 `ldflags-y`를 쓸 수 있습니다.
`LDFLAGS_vmlinux`는 최종 `vmlinux` image link 시 추가 option이며 `LDFLAGS_$@` 지원을 사용합니다. x86 예제는 entry를 `stext`로 지정합니다.
`OBJCOPYFLAGS`는 `$(call if_changed,objcopy)`로 `.o`를 변환할 때 사용하며 `vmlinux`에서 raw binary를 만드는 데 흔히 쓰입니다. s390 예제는 `-O binary`로 `$(obj)/image`를 생성합니다.
`KBUILD_AFLAGS`, `KBUILD_CFLAGS`, `KBUILD_RUSTFLAGS`는 각각 assembler, C compiler, Rust compiler의 architecture별 기본 option을 추가·수정합니다. 기본값은 top-level Makefile에 있습니다. Rust `--target` specification file 생성은 `scripts/generate_rust_target.rs`가 처리합니다.
`KBUILD_CFLAGS`는 configuration에 따라 달라지는 경우가 많습니다. x86 compressed boot는 32-bit에 `-march=i386`, 64-bit에 `-mcmodel=small`을 선택합니다. 많은 arch Makefile은 target compiler를 실행해 `cc-option`으로 지원 option을 동적으로 탐색합니다.
Built-in 전용 assembler·compiler·Rust option은 `KBUILD_AFLAGS_KERNEL`, `KBUILD_CFLAGS_KERNEL`, `KBUILD_RUSTFLAGS_KERNEL`에 둡니다. Resident kernel code compile에 추가됩니다.
Module 전용 option은 `KBUILD_AFLAGS_MODULE`, `KBUILD_CFLAGS_MODULE`, `KBUILD_RUSTFLAGS_MODULE`, `KBUILD_LDFLAGS_MODULE`입니다. Architecture-specific assemble, compile, Rust compile, module link option을 더합니다. Command line에서는 각각 `AFLAGS_MODULE`, `CFLAGS_MODULE`, `RUSTFLAGS_MODULE`, `LDFLAGS_MODULE`을 사용합니다. Linker option은 흔히 linker script입니다.
`KBUILD_LDS`는 top-level Makefile이 지정한 full-path linker script입니다. `KBUILD_VMLINUX_OBJS`는 `vmlinux`의 모든 object를 link 순서대로 나열합니다. 단 `scripts/head-object-list.txt` object는 앞에 놓입니다. `KBUILD_VMLINUX_LIBS`는 `vmlinux`용 모든 `.a` library이며 두 variable이 link할 전체 object를 결정합니다.
Link·compile 단계와 built-in/module 구분입니다.
Architecture Makefiles
======================
The top level Makefile sets up the environment and does the preparation,
before starting to descend down in the individual directories.
The top level makefile contains the generic part, whereas
arch/$(SRCARCH)/Makefile contains what is required to set up kbuild
for said architecture.
To do so, arch/$(SRCARCH)/Makefile sets up a number of variables and defines
a few targets.
When kbuild executes, the following steps are followed (roughly):
1) Configuration of the kernel => produce .config
2) Store kernel version in include/linux/version.h
3) Updating all other prerequisites to the target prepare:
- Additional prerequisites are specified in arch/$(SRCARCH)/Makefile
4) Recursively descend down in all directories listed in
init-* core* drivers-* net-* libs-* and build all targets.
- The values of the above variables are expanded in arch/$(SRCARCH)/Makefile.
5) All object files are then linked and the resulting file vmlinux is
located at the root of the obj tree.
The very first objects linked are listed in scripts/head-object-list.txt.
6) Finally, the architecture-specific part does any required post processing
and builds the final bootimage.
- This includes building boot records
- Preparing initrd images and the like
Set variables to tweak the build to the architecture
----------------------------------------------------
KBUILD_LDFLAGS
Generic $(LD) options
Flags used for all invocations of the linker.
Often specifying the emulation is sufficient.
Example::
#arch/s390/Makefile
KBUILD_LDFLAGS := -m elf_s390
Note: ldflags-y can be used to further customise
the flags used. See `Non-builtin vmlinux targets - extra-y`_.
LDFLAGS_vmlinux
Options for $(LD) when linking vmlinux
LDFLAGS_vmlinux is used to specify additional flags to pass to
the linker when linking the final vmlinux image.
LDFLAGS_vmlinux uses the LDFLAGS_$@ support.
Example::
#arch/x86/Makefile
LDFLAGS_vmlinux := -e stext
OBJCOPYFLAGS
objcopy flags
When $(call if_changed,objcopy) is used to translate a .o file,
the flags specified in OBJCOPYFLAGS will be used.
$(call if_changed,objcopy) is often used to generate raw binaries on
vmlinux.
Example::
#arch/s390/Makefile
OBJCOPYFLAGS := -O binary
#arch/s390/boot/Makefile
$(obj)/image: vmlinux FORCE
$(call if_changed,objcopy)
In this example, the binary $(obj)/image is a binary version of
vmlinux. The usage of $(call if_changed,xxx) will be described later.
KBUILD_AFLAGS
Assembler flags
Default value - see top level Makefile.
Append or modify as required per architecture.
Example::
#arch/sparc64/Makefile
KBUILD_AFLAGS += -m64 -mcpu=ultrasparc
KBUILD_CFLAGS
$(CC) compiler flags
Default value - see top level Makefile.
Append or modify as required per architecture.
Often, the KBUILD_CFLAGS variable depends on the configuration.
Example::
#arch/x86/boot/compressed/Makefile
cflags-$(CONFIG_X86_32) := -march=i386
cflags-$(CONFIG_X86_64) := -mcmodel=small
KBUILD_CFLAGS += $(cflags-y)
Many arch Makefiles dynamically run the target C compiler to
probe supported options::
#arch/x86/Makefile
...
cflags-$(CONFIG_MPENTIUMII) += $(call cc-option,\
-march=pentium2,-march=i686)
...
# Disable unit-at-a-time mode ...
KBUILD_CFLAGS += $(call cc-option,-fno-unit-at-a-time)
...
The first example utilises the trick that a config option expands
to "y" when selected.
KBUILD_RUSTFLAGS
$(RUSTC) compiler flags
Default value - see top level Makefile.
Append or modify as required per architecture.
Often, the KBUILD_RUSTFLAGS variable depends on the configuration.
Note that target specification file generation (for ``--target``)
is handled in ``scripts/generate_rust_target.rs``.
KBUILD_AFLAGS_KERNEL
Assembler options specific for built-in
$(KBUILD_AFLAGS_KERNEL) contains extra C compiler flags used to compile
resident kernel code.
KBUILD_AFLAGS_MODULE
Assembler options specific for modules
$(KBUILD_AFLAGS_MODULE) is used to add arch-specific options that
are used for assembler.
From commandline AFLAGS_MODULE shall be used (see kbuild.rst).
KBUILD_CFLAGS_KERNEL
$(CC) options specific for built-in
$(KBUILD_CFLAGS_KERNEL) contains extra C compiler flags used to compile
resident kernel code.
KBUILD_CFLAGS_MODULE
Options for $(CC) when building modules
$(KBUILD_CFLAGS_MODULE) is used to add arch-specific options that
are used for $(CC).
From commandline CFLAGS_MODULE shall be used (see kbuild.rst).
KBUILD_RUSTFLAGS_KERNEL
$(RUSTC) options specific for built-in
$(KBUILD_RUSTFLAGS_KERNEL) contains extra Rust compiler flags used to
compile resident kernel code.
KBUILD_RUSTFLAGS_MODULE
Options for $(RUSTC) when building modules
$(KBUILD_RUSTFLAGS_MODULE) is used to add arch-specific options that
are used for $(RUSTC).
From commandline RUSTFLAGS_MODULE shall be used (see kbuild.rst).
KBUILD_LDFLAGS_MODULE
Options for $(LD) when linking modules
$(KBUILD_LDFLAGS_MODULE) is used to add arch-specific options
used when linking modules. This is often a linker script.
From commandline LDFLAGS_MODULE shall be used (see kbuild.rst).
KBUILD_LDS
The linker script with full path. Assigned by the top-level Makefile.
KBUILD_VMLINUX_OBJS
All object files for vmlinux. They are linked to vmlinux in the same
order as listed in KBUILD_VMLINUX_OBJS.
The objects listed in scripts/head-object-list.txt are exceptions;
they are placed before the other objects.
KBUILD_VMLINUX_LIBS
All .a ``lib`` files for vmlinux. KBUILD_VMLINUX_OBJS and
KBUILD_VMLINUX_LIBS together specify all the object files used to
link vmlinux.
Arch prerequisite·directory·boot image
1263-1380`archheaders` rule은 `make header_install`로 userspace에 설치될 수 있는 header file을 생성합니다. 해당 architecture에서 실행할 때 `make archprepare`보다 먼저 수행됩니다.
`archprepare` rule에는 subdirectory로 내려가기 전에 build해야 할 prerequisite를 나열합니다. 보통 assembler constant를 담은 header file에 사용합니다. ARM 예제의 `archprepare: maketools`는 하강 전에 `maketools` target을 처리합니다. Offset header 생성 설명은 아직 TODO로 남아 있습니다.
Arch Makefile은 top Makefile과 협력해 `vmlinux` build directory variable을 정의합니다. Module build machinery는 architecture-independent이므로 대응하는 arch-specific module section은 없습니다.
`libs-y`는 `lib.a` archive가 있는 directory를 나열하고 `core-y`, `drivers-y`는 `built-in.a`가 있는 directory를 나열합니다. Link 순서는 `$(core-y)`, `$(libs-y)`, `$(drivers-y)`입니다. Top Makefile이 generic directory 값을 정의하고 arch Makefile은 architecture-specific directory만 추가합니다.
Sparc 예제는 `core-y += arch/sparc/`, `libs-y += arch/sparc/prom/`, `libs-y += arch/sparc/lib/`를 추가하고 `CONFIG_PM`일 때 `drivers-y`에 `arch/sparc/power/`를 더합니다.
Archive 종류와 최종 처리 순서입니다.
Arch Makefile은 `vmlinux`를 압축하고 bootstrap code로 감싸며 결과를 복사하는 goal을 정의합니다. Install command도 포함됩니다. 실제 goal 이름은 architecture마다 표준화되어 있지 않고, 추가 처리는 보통 `arch/$(SRCARCH)/boot/`에 둡니다.
Kbuild는 `boot/` 안 target을 자동으로 똑똑하게 build하지 않으므로 arch Makefile이 make를 직접 호출해야 합니다. Arch Makefile에는 shortcut을 두고 하위 boot Makefile을 호출할 때 full path를 쓰는 것이 권장됩니다.
x86 예제는 `boot := arch/x86/boot`, `bzImage: vmlinux`를 정의하고 `$(Q)$(MAKE) $(build)=$(boot) $(boot)/$@`로 하강합니다. `$(Q)$(MAKE) $(build)=<dir>`가 subdirectory make 호출의 권장 방식입니다.
Architecture-specific target naming rule은 없지만 `make help`가 관련 target을 모두 보여 줘야 하므로 `$(archhelp)`를 정의해야 합니다. x86 예제는 `bzImage`가 compressed kernel image임을 출력합니다.
Argument 없이 `make`를 실행하면 처음 만난 goal이 build되며 top Makefile의 첫 goal은 `all:`입니다. Architecture는 기본적으로 항상 bootable image를 build해야 하고 `make help`에서 default goal은 `*`로 강조됩니다.
`vmlinux`가 아닌 default goal을 선택하려면 `all:`에 새 prerequisite를 추가합니다. `all: bzImage`를 정의하면 argument 없는 `make`가 `bzImage`를 build합니다.
Top-level `all`에서 boot directory의 실제 target까지 연결합니다.
Add prerequisites to archheaders
--------------------------------
The archheaders: rule is used to generate header files that
may be installed into user space by ``make header_install``.
It is run before ``make archprepare`` when run on the
architecture itself.
Add prerequisites to archprepare
--------------------------------
The archprepare: rule is used to list prerequisites that need to be
built before starting to descend down in the subdirectories.
This is usually used for header files containing assembler constants.
Example::
#arch/arm/Makefile
archprepare: maketools
In this example, the file target maketools will be processed
before descending down in the subdirectories.
See also chapter XXX-TODO that describes how kbuild supports
generating offset header files.
List directories to visit when descending
-----------------------------------------
An arch Makefile cooperates with the top Makefile to define variables
which specify how to build the vmlinux file. Note that there is no
corresponding arch-specific section for modules; the module-building
machinery is all architecture-independent.
core-y, libs-y, drivers-y
$(libs-y) lists directories where a lib.a archive can be located.
The rest list directories where a built-in.a object file can be
located.
Then the rest follows in this order:
$(core-y), $(libs-y), $(drivers-y)
The top level Makefile defines values for all generic directories,
and arch/$(SRCARCH)/Makefile only adds architecture-specific
directories.
Example::
# arch/sparc/Makefile
core-y += arch/sparc/
libs-y += arch/sparc/prom/
libs-y += arch/sparc/lib/
drivers-$(CONFIG_PM) += arch/sparc/power/
Architecture-specific boot images
---------------------------------
An arch Makefile specifies goals that take the vmlinux file, compress
it, wrap it in bootstrapping code, and copy the resulting files
somewhere. This includes various kinds of installation commands.
The actual goals are not standardized across architectures.
It is common to locate any additional processing in a boot/
directory below arch/$(SRCARCH)/.
Kbuild does not provide any smart way to support building a
target specified in boot/. Therefore arch/$(SRCARCH)/Makefile shall
call make manually to build a target in boot/.
The recommended approach is to include shortcuts in
arch/$(SRCARCH)/Makefile, and use the full path when calling down
into the arch/$(SRCARCH)/boot/Makefile.
Example::
#arch/x86/Makefile
boot := arch/x86/boot
bzImage: vmlinux
$(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
``$(Q)$(MAKE) $(build)=<dir>`` is the recommended way to invoke
make in a subdirectory.
There are no rules for naming architecture-specific targets,
but executing ``make help`` will list all relevant targets.
To support this, $(archhelp) must be defined.
Example::
#arch/x86/Makefile
define archhelp
echo '* bzImage - Compressed kernel image (arch/x86/boot/bzImage)'
endif
When make is executed without arguments, the first goal encountered
will be built. In the top level Makefile the first goal present
is all:.
An architecture shall always, per default, build a bootable image.
In ``make help``, the default goal is highlighted with a ``*``.
Add a new prerequisite to all: to select a default goal different
from vmlinux.
Example::
#arch/x86/Makefile
all: bzImage
When ``make`` is executed without arguments, bzImage will be built.
Commands useful for building a boot image
Boot image command·linker script·post-link
1381-1508Kbuild는 boot image build에 유용한 `ld`, `objcopy`, `gzip`, `dtc` macro를 제공합니다.
`ld`는 target을 link하며 target별 option은 흔히 `LDFLAGS_$@`로 지정합니다. x86 boot 예제는 `bootsect`와 `setup`에 서로 다른 text address, output format, entry option을 줍니다. 모든 잠재 target은 `targets`에 넣어 Kbuild가 command-line change를 검사하고 `make clean`에서 삭제하도록 합니다.
Rule의 `: %: %.o`는 `setup.o`, `bootsect.o`를 각각 나열하지 않아도 되는 shorthand입니다. `targets :=` assignment를 빼먹으면 이유 없이 target이 반복 compile되는 흔한 문제가 생깁니다.
`objcopy`는 binary를 복사하며 보통 arch Makefile의 `OBJCOPYFLAGS`를 사용합니다. Target별 추가 option은 `OBJCOPYFLAGS_$@`에 둘 수 있습니다. `gzip`은 최대 compression으로 target을 압축합니다. x86 예제는 `$(call if_changed,gzip)`으로 `vmlinux.bin.gz`를 만듭니다.
`dtc`는 `vmlinux`에 link할 수 있는 flattened device tree blob object를 만듭니다. Image의 init section에 들어가므로 platform code는 `unflatten_device_tree()` 호출 전에 blob을 non-init memory로 복사해야 합니다.
`*.dtb`를 `obj-y`나 `targets`에 넣거나 다른 target이 `%.dtb`에 의존하게 하면 됩니다. `$(src)/%.dts`에서 `$(obj)/%.dtb`를 만드는 central rule이 있으므로 arch Makefile이 직접 rule을 쓸 필요가 없습니다. 예제는 `targets += $(dtb-y)`와 `DTC_FLAGS ?= -p 1024`를 사용합니다.
Architecture boot Makefile에서 흔히 쓰는 네 macro입니다.
`vmlinux` build에는 `arch/$(SRCARCH)/kernel/vmlinux.lds` linker script를 사용합니다. 같은 directory의 `vmlinux.lds.S`를 preprocess한 결과이며 Kbuild는 `.lds`를 인식해 `*lds.S`에서 `*lds`를 만드는 rule을 제공합니다.
x86 kernel Makefile의 `extra-y := vmlinux.lds`는 target build를 알립니다. `CPPFLAGS_vmlinux.lds`는 target-specific option을 지정합니다. `.lds` build에는 top-level `KBUILD_CPPFLAGS`, 현재 kbuild file의 `cppflags-y`, full filename을 쓰는 `CPPFLAGS_$(@F)`를 적용합니다.
`include/asm-generic`에는 architecture 사이에 공유할 수 있는 header가 있습니다. Generic header를 쓰는 권장 방식은 Kbuild file에 나열하는 것이며 문법은 뒤의 `generic-y` 절에서 설명합니다.
`arch/xxx/Makefile.postlink`가 존재하면 architecture post-link pass를 위해 `vmlinux`와 `modules.ko`에 호출됩니다. 이 Makefile은 `clean` target도 처리해야 합니다.
Post-link pass는 kallsyms 생성 뒤 실행됩니다. Architecture가 symbol location을 바꿔야 한다면 kallsyms를 조작하기보다 `link-vmlinux.sh`에서 호출할 `.tmp_vmlinux?`용 별도 postlink target을 두는 편이 쉬울 수 있습니다. PowerPC는 linked `vmlinux`의 relocation sanity를 검사하는 데 사용합니다.
-----------------------------------------
Kbuild provides a few macros that are useful when building a
boot image.
ld
Link target. Often, LDFLAGS_$@ is used to set specific options to ld.
Example::
#arch/x86/boot/Makefile
LDFLAGS_bootsect := -Ttext 0x0 -s --oformat binary
LDFLAGS_setup := -Ttext 0x0 -s --oformat binary -e begtext
targets += setup setup.o bootsect bootsect.o
$(obj)/setup $(obj)/bootsect: %: %.o FORCE
$(call if_changed,ld)
In this example, there are two possible targets, requiring different
options to the linker. The linker options are specified using the
LDFLAGS_$@ syntax - one for each potential target.
$(targets) are assigned all potential targets, by which kbuild knows
the targets and will:
1) check for commandline changes
2) delete target during make clean
The ``: %: %.o`` part of the prerequisite is a shorthand that
frees us from listing the setup.o and bootsect.o files.
Note:
It is a common mistake to forget the ``targets :=`` assignment,
resulting in the target file being recompiled for no
obvious reason.
objcopy
Copy binary. Uses OBJCOPYFLAGS usually specified in
arch/$(SRCARCH)/Makefile.
OBJCOPYFLAGS_$@ may be used to set additional options.
gzip
Compress target. Use maximum compression to compress target.
Example::
#arch/x86/boot/compressed/Makefile
$(obj)/vmlinux.bin.gz: $(vmlinux.bin.all-y) FORCE
$(call if_changed,gzip)
dtc
Create flattened device tree blob object suitable for linking
into vmlinux. Device tree blobs linked into vmlinux are placed
in an init section in the image. Platform code *must* copy the
blob to non-init memory prior to calling unflatten_device_tree().
To use this command, simply add ``*.dtb`` into obj-y or targets, or make
some other target depend on ``%.dtb``
A central rule exists to create ``$(obj)/%.dtb`` from ``$(src)/%.dts``;
architecture Makefiles do no need to explicitly write out that rule.
Example::
targets += $(dtb-y)
DTC_FLAGS ?= -p 1024
Preprocessing linker scripts
----------------------------
When the vmlinux image is built, the linker script
arch/$(SRCARCH)/kernel/vmlinux.lds is used.
The script is a preprocessed variant of the file vmlinux.lds.S
located in the same directory.
kbuild knows .lds files and includes a rule ``*lds.S`` -> ``*lds``.
Example::
#arch/x86/kernel/Makefile
extra-y := vmlinux.lds
The assignment to extra-y is used to tell kbuild to build the
target vmlinux.lds.
The assignment to $(CPPFLAGS_vmlinux.lds) tells kbuild to use the
specified options when building the target vmlinux.lds.
When building the ``*.lds`` target, kbuild uses the variables::
KBUILD_CPPFLAGS : Set in top-level Makefile
cppflags-y : May be set in the kbuild makefile
CPPFLAGS_$(@F) : Target-specific flags.
Note that the full filename is used in this
assignment.
The kbuild infrastructure for ``*lds`` files is used in several
architecture-specific files.
Generic header files
--------------------
The directory include/asm-generic contains the header files
that may be shared between individual architectures.
The recommended approach how to use a generic header file is
to list the file in the Kbuild file.
See `generic-y`_ for further info on syntax etc.
Post-link pass
--------------
If the file arch/xxx/Makefile.postlink exists, this makefile
will be invoked for post-link objects (vmlinux and modules.ko)
for architectures to run post-link passes on. Must also handle
the clean target.
This pass runs after kallsyms generation. If the architecture
needs to modify symbol locations, rather than manipulate the
kallsyms, it may be easier to add another postlink target for
.tmp_vmlinux? targets to be called from link-vmlinux.sh.
For example, powerpc uses this to check relocation sanity of
the linked vmlinux file.
Export header Kbuild 문법
1509-1591Kernel은 userspace에 export하는 header 집합을 포함합니다. 많은 header는 그대로 export할 수 있지만 일부는 최소한의 preprocessing이 필요합니다.
Preprocessing은 kernel-specific annotation을 제거하고, `compiler.h` include를 제거하며, `ifdef __KERNEL__`로 보호된 kernel-internal section을 모두 제거합니다.
`include/uapi/`, `include/generated/uapi/`, `arch/<arch>/include/uapi/`, `arch/<arch>/include/generated/uapi/` 아래의 모든 header가 export됩니다.
`arch/<arch>/include/uapi/asm/`과 `arch/<arch>/include/asm/` 아래에 Kbuild file을 정의해 `asm-generic`에서 가져올 asm file을 나열할 수 있습니다.
`no-export-headers`는 주로 `include/uapi/linux/Kbuild`에서 특정 architecture가 지원하지 않는 `kvm.h` 같은 header의 export를 막는 데 씁니다. 가능한 한 사용을 피해야 합니다.
Architecture가 `include/asm-generic` header의 verbatim copy를 사용한다면 `arch/$(SRCARCH)/include/asm/Kbuild`의 `generic-y`에 나열합니다. x86 예제는 `termios.h`, `rtc.h`를 추가합니다.
Build prepare 단계에서 `arch/$(SRCARCH)/include/generated/asm`에 wrapper include file을 생성합니다. Generic header를 쓰는 exported header에도 `usr/include/asm`에 비슷한 wrapper가 생깁니다. `termios.h` wrapper 내용은 `#include <asm-generic/termios.h>`입니다.
Architecture가 `generic-y` wrapper와 나란히 다른 header도 생성한다면 `generated-y`에 지정합니다. 그러면 stale asm-generic wrapper로 오인해 삭제하지 않습니다. x86 예제는 `syscalls_32.h`를 나열합니다.
`mandatory-y`는 `include/(uapi/)asm-generic/Kbuild`에서 모든 architecture가 반드시 가져야 할 최소 ASM header 집합을 정의합니다. Optional `generic-y`처럼 동작하며 `arch/$(SRCARCH)/include/(uapi/)/asm`에 mandatory header가 없으면 Kbuild가 asm-generic wrapper를 자동 생성합니다.
Generic header wrapper의 생성과 제외를 제어합니다.
Architecture-specific path에 wrapper를 만들고 userspace용 사본도 생성합니다.
Kbuild syntax for exported headers
==================================
The kernel includes a set of headers that is exported to userspace.
Many headers can be exported as-is but other headers require a
minimal pre-processing before they are ready for user-space.
The pre-processing does:
- drop kernel-specific annotations
- drop include of compiler.h
- drop all sections that are kernel internal (guarded by ``ifdef __KERNEL__``)
All headers under include/uapi/, include/generated/uapi/,
arch/<arch>/include/uapi/ and arch/<arch>/include/generated/uapi/
are exported.
A Kbuild file may be defined under arch/<arch>/include/uapi/asm/ and
arch/<arch>/include/asm/ to list asm files coming from asm-generic.
See subsequent chapter for the syntax of the Kbuild file.
no-export-headers
-----------------
no-export-headers is essentially used by include/uapi/linux/Kbuild to
avoid exporting specific headers (e.g. kvm.h) on architectures that do
not support it. It should be avoided as much as possible.
generic-y
---------
If an architecture uses a verbatim copy of a header from
include/asm-generic then this is listed in the file
arch/$(SRCARCH)/include/asm/Kbuild like this:
Example::
#arch/x86/include/asm/Kbuild
generic-y += termios.h
generic-y += rtc.h
During the prepare phase of the build a wrapper include
file is generated in the directory::
arch/$(SRCARCH)/include/generated/asm
When a header is exported where the architecture uses
the generic header a similar wrapper is generated as part
of the set of exported headers in the directory::
usr/include/asm
The generated wrapper will in both cases look like the following:
Example: termios.h::
#include <asm-generic/termios.h>
generated-y
-----------
If an architecture generates other header files alongside generic-y
wrappers, generated-y specifies them.
This prevents them being treated as stale asm-generic wrappers and
removed.
Example::
#arch/x86/include/asm/Kbuild
generated-y += syscalls_32.h
mandatory-y
-----------
mandatory-y is essentially used by include/(uapi/)asm-generic/Kbuild
to define the minimum set of ASM headers that all architectures must have.
This works like optional generic-y. If a mandatory header is missing
in arch/$(SRCARCH)/include/(uapi/)/asm, Kbuild will automatically
generate a wrapper of the asm-generic one.
Top Makefile이 export하는 변수
1592-1665Top Makefile은 kernel version, architecture, install path 관련 variable을 export합니다.
`VERSION`, `PATCHLEVEL`, `SUBLEVEL`, `EXTRAVERSION`은 현재 kernel version을 정의합니다. 일부 arch Makefile이 직접 사용하지만 `$(KERNELRELEASE)`를 쓰는 편이 맞습니다. 앞의 세 값은 `2`, `4`, `0`처럼 항상 숫자인 기본 3-part version이고 `EXTRAVERSION`은 `-pre4` 같은 non-numeric pre-patch·추가 patch sublevel이며 비어 있는 경우가 많습니다.
`KERNELRELEASE`는 `2.4.0-pre4` 같은 단일 string으로 install directory 이름이나 version string에 적합합니다.
`ARCH`는 `i386`, `arm`, `sparc` 같은 target architecture입니다. 일부 kbuild Makefile이 compile할 file을 결정하는 데 검사합니다. 기본은 host architecture이며 cross build에서는 `make ARCH=m68k ...`처럼 command line에서 override합니다.
`SRCARCH`는 build할 `arch/` 아래 directory를 지정합니다. `ARCH`와 반드시 같지는 않습니다. 하나의 arch directory가 32-bit와 64-bit를 모두 지원하는 biarch일 수 있습니다. `ARCH=i386`, `ARCH=x86_64`, `ARCH=x86` 모두 `SRCARCH=x86`을 사용합니다.
`INSTALL_PATH`는 architecture Makefile이 resident kernel image와 `System.map`을 설치할 위치이며 architecture-specific install target에 사용합니다.
`INSTALL_MOD_PATH`는 module install directory `MODLIB` 앞에 붙는 prefix입니다. Makefile에 정의되어 있지 않지만 user가 넘길 수 있습니다. `MODLIB`는 module 설치 directory이며 기본값은 `$(INSTALL_MOD_PATH)/lib/modules/$(KERNELRELEASE)`이고 command line에서 override할 수 있습니다.
`INSTALL_MOD_STRIP`을 지정하면 설치 뒤 module을 strip합니다. 값이 `1`이면 기본 `--strip-debug` option을 쓰고, 그 외 값은 strip command option으로 그대로 사용합니다.
`INSTALL_DTBS_PATH`는 build root relocation을 위한 prefix이자 device tree blob 설치 위치입니다. `INSTALL_MOD_PATH`처럼 Makefile에 정의되지 않지만 user가 넘길 수 있고, 생략하면 kernel install path가 기본입니다.
Version, target architecture와 설치 위치를 제어합니다.
Kbuild Variables
================
The top Makefile exports the following variables:
VERSION, PATCHLEVEL, SUBLEVEL, EXTRAVERSION
These variables define the current kernel version. A few arch
Makefiles actually use these values directly; they should use
$(KERNELRELEASE) instead.
$(VERSION), $(PATCHLEVEL), and $(SUBLEVEL) define the basic
three-part version number, such as "2", "4", and "0". These three
values are always numeric.
$(EXTRAVERSION) defines an even tinier sublevel for pre-patches
or additional patches. It is usually some non-numeric string
such as "-pre4", and is often blank.
KERNELRELEASE
$(KERNELRELEASE) is a single string such as "2.4.0-pre4", suitable
for constructing installation directory names or showing in
version strings. Some arch Makefiles use it for this purpose.
ARCH
This variable defines the target architecture, such as "i386",
"arm", or "sparc". Some kbuild Makefiles test $(ARCH) to
determine which files to compile.
By default, the top Makefile sets $(ARCH) to be the same as the
host system architecture. For a cross build, a user may
override the value of $(ARCH) on the command line::
make ARCH=m68k ...
SRCARCH
This variable specifies the directory in arch/ to build.
ARCH and SRCARCH may not necessarily match. A couple of arch
directories are biarch, that is, a single ``arch/*/`` directory supports
both 32-bit and 64-bit.
For example, you can pass in ARCH=i386, ARCH=x86_64, or ARCH=x86.
For all of them, SRCARCH=x86 because arch/x86/ supports both i386 and
x86_64.
INSTALL_PATH
This variable defines a place for the arch Makefiles to install
the resident kernel image and System.map file.
Use this for architecture-specific install targets.
INSTALL_MOD_PATH, MODLIB
$(INSTALL_MOD_PATH) specifies a prefix to $(MODLIB) for module
installation. This variable is not defined in the Makefile but
may be passed in by the user if desired.
$(MODLIB) specifies the directory for module installation.
The top Makefile defines $(MODLIB) to
$(INSTALL_MOD_PATH)/lib/modules/$(KERNELRELEASE). The user may
override this value on the command line if desired.
INSTALL_MOD_STRIP
If this variable is specified, it will cause modules to be stripped
after they are installed. If INSTALL_MOD_STRIP is "1", then the
default option --strip-debug will be used. Otherwise, the
INSTALL_MOD_STRIP value will be used as the option(s) to the strip
command.
INSTALL_DTBS_PATH
This variable specifies a prefix for relocations required by build
roots. It defines a place for installing the device tree blobs. Like
INSTALL_MOD_PATH, it isn't defined in the Makefile, but can be passed
by the user if desired. Otherwise it defaults to the kernel install
path.
GNU Make 언어·기여자·TODO
1666-1698Kernel Makefile은 GNU Make로 실행하도록 설계되었습니다. Documented GNU Make feature만 사용하지만 많은 GNU extension을 활용합니다.
GNU Make는 기본적인 list-processing function을 지원합니다. Kernel Makefile은 `if` statement를 거의 쓰지 않고 list를 구축하고 조작하는 독특한 style을 사용합니다.
GNU Make의 두 assignment operator `:=`와 `=`는 평가 시점이 다릅니다. `:=`는 우변을 즉시 평가해 실제 string을 좌변에 저장합니다. `=`는 formula definition처럼 평가하지 않은 우변을 저장했다가 좌변을 사용할 때마다 평가합니다.
`=`가 적절한 경우도 있지만 보통은 `:=`가 올바른 선택입니다.
Kbuild Makefile에서 variable 평가 시점을 선택합니다.
원본은 Michael Elizabeth Chastain이 작성했고 Kai Germaschewski와 Sam Ravnborg가 갱신했으며 Jan Engelhardt가 language QA를 맡았습니다.
남은 TODO는 offset header file 생성 설명을 추가하는 것과 chapter 7 또는 9에 더 많은 variable을 추가할지 검토하는 것입니다.
Makefile language
=================
The kernel Makefiles are designed to be run with GNU Make. The Makefiles
use only the documented features of GNU Make, but they do use many
GNU extensions.
GNU Make supports elementary list-processing functions. The kernel
Makefiles use a novel style of list building and manipulation with few
``if`` statements.
GNU Make has two assignment operators, ``:=`` and ``=``. ``:=`` performs
immediate evaluation of the right-hand side and stores an actual string
into the left-hand side. ``=`` is like a formula definition; it stores the
right-hand side in an unevaluated form and then evaluates this form each
time the left-hand side is used.
There are some cases where ``=`` is appropriate. Usually, though, ``:=``
is the right choice.
Credits
=======
- Original version made by Michael Elizabeth Chastain, <mailto:mec@shout.net>
- Updates by Kai Germaschewski <kai@tp1.ruhr-uni-bochum.de>
- Updates by Sam Ravnborg <sam@ravnborg.org>
- Language QA by Jan Engelhardt <jengelh@gmx.de>
TODO
====
- Generating offset header files.
- Add more variables to chapters 7 or 9?
요약·해설
makefiles.rst:1-1698Kbuild Makefile은 `obj-y`, `obj-m`, `<name>-y`, `lib-y`로 built-in·module·library 구성을 선언하고, directory suffix 또는 `subdir-*`로 재귀 build 범위를 정합니다. Link 순서는 boot-time init order에 영향을 줄 수 있습니다.
Custom rule은 source에 `$(src)`, generated target에 `$(obj)`를 사용하고, command 변화까지 추적하려면 target 등록·`FORCE`·`if_changed`를 함께 써야 합니다.
Host와 target userspace generator는 각각 `hostprogs`, `userprogs`로 선언하되 prerequisite나 `*-always-y`로 실제 build를 요청합니다. Architecture Makefile은 generic build를 확장해 `vmlinux`, boot image, exported header와 install path를 조정합니다.
Directory 선언에서 최종 boot image까지 이어지는 핵심 관계입니다.