Linux Kernel Makefiles
This document describes the Linux kernel Makefiles.
=== Table of Contents
=== 1 Overview
=== 2 Who does what
=== 3 The kbuild files
--- 3.1 Goal definitions
--- 3.2 Built-in object goals - obj-y
--- 3.3 Loadable module goals - obj-m
--- 3.4 Objects which export symbols
--- 3.5 Library file goals - lib-y
--- 3.6 Descending down in directories
--- 3.7 Compilation flags
--- 3.8 Command line dependency
--- 3.9 Dependency tracking
--- 3.10 Special Rules
=== 4 Host Program support
--- 4.1 Simple Host Program
--- 4.2 Composite Host Programs
--- 4.3 Defining shared libraries
--- 4.4 Using C++ for host programs
--- 4.5 Controlling compiler options for host programs
--- 4.6 When host programs are actually built
--- 4.7 Using hostprogs-$(CONFIG_FOO)
=== 5 Kbuild clean infrastructure
=== 6 Architecture Makefiles
--- 6.1 Set variables to tweak the build to the architecture
--- 6.2 Add prerequisites to prepare:
--- 6.3 List directories to visit when descending
--- 6.4 Architecture specific boot images
--- 6.5 Building non-kbuild targets
--- 6.6 Commands useful for building a boot image
--- 6.7 Custom kbuild commands
--- 6.8 Preprocessing linker scripts
--- 6.9 $(CC) support functions
=== 7 Kbuild Variables
=== 8 Makefile language
=== 9 Credits
=== 10 TODO
=== 1 Overview
The Makefiles have five parts:
Makefile the top Makefile.
.config the kernel configuration file.
arch/$(ARCH)/Makefile the arch Makefile.
scripts/Makefile.* common rules etc. for all kbuild Makefiles.
kbuild Makefiles there are about 500 of these.
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/$(ARCH)/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.
(译)
=== 1 概述
Makefiles 分为五部分:
Makefile 顶层的Makefile.
.config 内核配置文件.
arch/$(ARCH)/Makefile 体系Makefile.
scripts/Makefile.* 公共规则等等. 供给所有的kbuild Makefiles.
kbuild Makefiles 大约有500这样的Makefiles.
顶层的Makefile读入.config文件,这文件来自内核配置处理。
顶层Makefile是负责建立两个主要的产物:vmlinux(常驻内核镜像)和模块 (任何模块文件)。
它建立这些目标通过递归向下的进入内核源码树的子目录来实现的。
这些子目录列表根据内核的配置来被访问。顶层Makefile原文地包含体系的Makefile
"arch/$(ARCH)/Makefile". 这个体系的Makefile 提供指定的体系信息给顶层的Makefile.
每个子目录都有一个kbuild Makefile 来执行从上层传递下来的命令。这些kbuild Makefile使用
来自.config文件的信息来构造各种文件列表,用来给kbuild建立各种build-in或模块目标。
scripts/Makefile.* 包含所有的定义/规则等等。用以基于kbuild Makefiles来建立内核。
=== 2 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 that 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 ia64. 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.
(译)
=== 2 人们与Makefile。
人们与kernel Makefiles的之间分为4种不同的关系。
*用户* 是一类建立内核的人们。 这些人只是敲命令例如"make menuconfig" 或者 "make".
他们通常不需要阅读或者编辑任何内核Makefiles(或者任何其他的源文件)。
*普通的开发者* 是一类工作在例如设备驱动,文件系统和网络协议的人们。这些人需要
维护他们工作的子系统的kbuild Makefiles。为了使到这些更高效,他们需要一些全面
的知识关于内核Makefiles, 和详细的知识关于kbuild公共接口。
*体系开发者* 是一类工作在整个体系的人们,例如 sparc或者ia64的。体系开发者既需要
理解体系Makefile,也需要理解kbuild Makefiles.
*kbuild开发者* 是一类工作在建立内核build系统的人们。这些人们需要理解内核Makefiles
的各个方面知识。
这个文档是面向普通的开发人员和体系开发者。
=== 3 The kbuild files
Most Makefiles within the kernel are kbuild Makefiles that use the
kbuild infrastructure. This chapter introduce the syntax used in the
kbuild makefiles.
The preferred name for the kbuild files is 'Kbuild' but 'Makefile' will
continue to be supported. All new developmen is expected to use the
Kbuild filename.
Section 3.1 "Goal definitions" is a quick intro, further chapters provide
more details, with real examples.
(译)
=== 3 kbuild文件
大部分处在内核中的Makefiles都是kbuild Makefiles, 用来kbuild的下部构造。这章介绍
kbuild makefiles用到的语法。
给kbuild files个更好的称呼是'Kbuild',而不是'Makefile',这会继续被使用。希望所有新
的开发者都去使用Kbuild这个名字。
3.1 节 “目标定义”是一个快速介绍,后面的章节提供更详细的信息和真实的例子。
--- 3.1 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 tell 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.
(译)
--- 3.1 目标定义
目标定义是kbuild Makefile主要(核心)部分。这些行定义了建立这些文件,任何特殊的
编译选项,和递归地进入任何子目录。
最简单的kbuild makefile包含一行:
例子:
obj-y += foo.o
这告诉kbuild在这个目录下有一个目标叫做foo.o. 这个foo.o将被建立通过foo.c或者foo.S.
如果foo.o应该被作为模块来建立,变量obj-m被使用。因此下面模式经常被使用:
例子:
obj-$(CONFIG_FOO) += foo.o
$(CONFIG_FOO) 评估为y(built-in)或者m(模块)。如果CONFIG_FOO既不是y也不是m,那么该文件
将会不被编译也不被链接。
--- 3.2 Built-in object goals - obj-y
The kbuild Makefile specifies object files for vmlinux
in the lists $(obj-y). These lists depend on the kernel
configuration.
Kbuild compiles all the $(obj-y) files. It then calls
"$(LD) -r" to merge these files into one built-in.o file.
built-in.o is later linked into vmlinux by the parent Makefile.
The order of files in $(obj-y) is significant. Duplicates in
the lists are allowed: the first instance will be linked into
built-in.o 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 you 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) += isdn.o
obj-$(CONFIG_ISDN_PPP_BSDCOMP) += isdn_bsdcomp.o
(译)
--- 3.2 Built-in object 目标 - obj-y
这个kbuild Makefile 在$(obj-y)列表里为vmlinux指定了object文件。这些列表在
内核配置的时候将被使用到。
Kbuild 编译所有的$(obj-y)文件。它然后调用"$(LD) -r" 去合并这些文件成一个built-in.o
文件。built-in.o将会被父目录的Makefile链接到vmlinux去。
在$(obj-y)列表里的文件顺序是非常重要的。在列表里重复出现是允许的:最前面的实例将被
链接到built-in.o, 而后面同名的实例将会被忽略掉。
链接的顺序也是至关重要的,因为某些函数 (module_init()/ __initcall)将会在依赖他们
出现的顺序在boot的时候被调用。所以一定要记住改变链接顺序可能发生这样事情,例如:当你
改变SCSI控制器顺序被侦测到后,因此你的硬盘被重编号。
例子:
#drivers/isdn/i4l/Makefile
# Makefile for the kernel ISDN subsystem and device drivers.
# Each configuration option enables a list of files.
obj-$(CONFIG_ISDN) += isdn.o
obj-$(CONFIG_ISDN_PPP_BSDCOMP) += isdn_bsdcomp.o
--- 3.3 Loadable module goals - obj-m
$(obj-m) specify 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.
Kbuild needs to know which the parts that you want to build your
module from, so you have to tell it by setting an
$(-objs) variable.
Example:
#drivers/isdn/i4l/Makefile
obj-$(CONFIG_ISDN) += isdn.o
isdn-objs := 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-objs) and then run
"$(LD) -r" on the list of these files to generate isdn.o.
Kbuild recognises objects used for composite objects by the suffix
-objs, and the suffix -y. This allows the Makefiles to use
the value of a CONFIG_ symbol to determine if an object is part
of a composite object.
Example:
#fs/ext2/Makefile
obj-$(CONFIG_EXT2_FS) += ext2.o
ext2-y := balloc.o bitmap.o
ext2-$(CONFIG_EXT2_FS_XATTR) += xattr.o
In this example xattr.o is 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.o, as you would expect.
(译)
--- 3.3 可加载模块目标 - obj-m
$(obj-m) 指定的object文件,这些文件可以作为可加载的内核模块。
一个模块可能由一个源文件或几个源文件建立。在由一个源文件建立的情况,kbuild makefile
简单的添加文件到目标$(obj-m)。
例子:
#drivers/isdn/i4l/Makefile
obj-$(CONFIG_ISDN_PPP_BSDCOMP) += isdn_bsdcomp.o
注意:这个例子里的$(CONFIG_ISDN_PPP_BSDCOMP)被评估为'm'
如果内核模块由几个源文件建立的,你只需要使用上面相同方法指定它们到要建立的目标里。
Kbuild 需要知道从哪一部分你想建立你的模块,所以你必须通过$(-objs)变量来告诉它。
例子:
#drivers/isdn/i4l/Makefile
obj-$(CONFIG_ISDN) += isdn.o
isdn-objs := isdn_net_lib.o isdn_v110.o isdn_common.o
在这个例子里,模块名将是isdn.o。Kbuild将编译这些$(isdn-objs)里的objects, 然后运行"$(LD) -r"
通过这些列表文件来产生isdn.o。
Kbuild 通过后缀-objs和-y来识别objects构造objects,它允许Makefiles去使用CONFIG_符号值去决定这个
object是否属于组合object的一部分。
例子:
#fs/ext2/Makefile
obj-$(CONFIG_EXT2_FS) += ext2.o
ext2-y := balloc.o bitmap.o
ext2-$(CONFIG_EXT2_FS_XATTR) += xattr.o
在这个例子里xattr.o是组合目标ext2.o的一部分,紧且如果$(CONFIG_EXT2_FS_XATTR)被评估为'y'。
注意:当然,当你建立这些objects到内核,上面所说的语法同样能工作。所以,如果你的
CONFIG_EXT2_FS=y,Kbuild将为你建立ext2.o为独立的部分,然后链接它到built-in.o,如你所盼望的那样。
--- 3.4 Objects which export symbols
No special notation is required in the makefiles for
modules exporting symbols.
(译)
--- 3.4 导出Objects符号
没有特殊的标记法,在makefiles被请求模块导出符号的。
--- 3.5 Library file goals - lib-y
Objects listed with obj-* are used for modules or
combined in a built-in.o 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 additional listed in
lib-y will not be included in the library, since they will anyway
be accessible.
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.o and a lib.a file.
Example:
#arch/i386/lib/Makefile
lib-y := checksum.o delay.o
This will create a library lib.a based on checksum.o and delay.o.
For kbuild to actually recognize that there is a lib.a being build
the directory shall be listed in libs-y.
See also "6.3 List directories to visit when descending".
Usage of lib-y is normally restricted to lib/ and arch/*/lib.
(译)
--- 3.5 库文件目标 - lib-y
Objects以obj-*列表的形式被模块使用,或者被联合到指定目录的build-in.o里。同样也有可能
去列表objects,这些object被包含到一个库,lib.a。
所有objects以lib-y列表的形式被合并成一个简单的库供给这个目录。
在obj-y里面的排列的Objects和在lib-y里的附加列表将不会被包含进库里,因为它们将经常的
被访问到。
为了使到objects列表一致性,被包含到lib-m里的同时也会被包含进lib.a中。
注意同样的kbuild makefile 可能列表文件为built-in形式和库的一部分。因此同一个目录下可能
同时包含built-in.o和lib.a文件。
例子:
#arch/i386/lib/Makefile
lib-y := checksum.o delay.o
这将基于checksum.o和delay.o创建一个库lib.a。为了kbuild去真实的明白到有这样一个lib.a库来建立
这个目录,这个目录的包含信息应该在lib-y里被列出来。
同样参见 "6.3 List directories to visit when descending".
lib-y的用法被普遍的限制到lib/和arch/*/lib里。
--- 3.6 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 only uses this information to decide that it needs to visit
the directory, it is the Makefile in the subdirectory that
specifies what is modules and what is built-in.
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'.
(译)
--- 3.6 下降到子目录
一个Makefile只是负责建立它自己目录下的objects。子目录下的文件因该有这些子目录下的
makefiles来处理。build系统将在子目录里自动的递归调用,你应该提供足够信息给它去处理。
To do so obj-y and obj-m are used.
ext2处在一个独立的目录里,在fs/里的Makefile会告诉kbuild去下降处理下面的赋值。
例子:
#fs/Makefile
obj-$(CONFIG_EXT2_FS) += ext2/
如果CONFIG_EXT2_FS被赋值为'y' (built-in) 或者 'm' (模块),那么相应的obj-变量将会被赋值,
kbuild将下降到ext2目录。
Kbuild仅仅使用这些信息去决定它需要去访问这个目录,在这个子目录里的Makefile指示那些是模块
和那些是built-in。
这是一个很好的实例去使用CONFIG_变量,这个变量被赋值目录名。这样允许kbuild去全部跳过那些
CONFIG_选项既不是'y'又不是'm'的目录。
--- 3.7 Compilation flags
EXTRA_CFLAGS, EXTRA_AFLAGS, EXTRA_LDFLAGS, EXTRA_ARFLAGS
All the EXTRA_ variables apply only to the kbuild makefile
where they are assigned. The EXTRA_ variables apply to all
commands executed in the kbuild makefile.
$(EXTRA_CFLAGS) specifies options for compiling C files with
$(CC).
Example:
# drivers/sound/emu10k1/Makefile
EXTRA_CFLAGS += -I$(obj)
ifdef DEBUG
EXTRA_CFLAGS += -DEMU10K1_DEBUG
endif
This variable is necessary because the top Makefile owns the
variable $(CFLAGS) and uses it for compilation flags for the
entire tree.
$(EXTRA_AFLAGS) is a similar string for per-directory options
when compiling assembly language source.
Example:
#arch/x86_64/kernel/Makefile
EXTRA_AFLAGS := -traditional
$(EXTRA_LDFLAGS) and $(EXTRA_ARFLAGS) are similar strings for
per-directory options to $(LD) and $(AR).
Example:
#arch/m68k/fpsp040/Makefile
EXTRA_LDFLAGS := -x
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.
Example:
# drivers/scsi/Makefile
CFLAGS_aha152x.o = -DAHA152X_STAT -DAUTOCONF
CFLAGS_gdth.o = # -DDEBUG_GDTH=2 -D__SERIAL__ -D__COM2__ \
-DGDTH_STATISTICS
CFLAGS_seagate.o = -DARBITRATE -DPARITY -DSEAGATE_USE_ASM
These three lines specify compilation flags for aha152x.o,
gdth.o, and seagate.o
$(AFLAGS_$@) is a similar feature for source files in assembly
languages.
Example:
# arch/arm/kernel/Makefile
AFLAGS_head-armv.o := -DTEXTADDR=$(TEXTADDR) -traditional
AFLAGS_head-armo.o := -DTEXTADDR=$(TEXTADDR) -traditional
(译)
--- 3.7 编译标记
EXTRA_CFLAGS, EXTRA_AFLAGS, EXTRA_LDFLAGS, EXTRA_ARFLAGS
所有的EXTRA_变量被使用,仅且仅当在这些kbuild makefile中它们被赋值。EXTRA_变量
被应用到所有在kbuild makefile里被执行到的命令。
$(EXTRA_CFLAGS) 为使用$(CC)来编译C文件提供指定选项。
例子:
# drivers/sound/emu10k1/Makefile
EXTRA_CFLAGS += -I$(obj)
ifdef DEBUG
EXTRA_CFLAGS += -DEMU10K1_DEBUG
endif
这些变量是很必要的,因为顶层的Makefile拥有变量$(CFLAGS)和使用它作为整个树的编译标志。
$(EXTRA_AFLAGS) 是一个类似的字符串作为每个目录的选项,当编译汇编语言源文件的时候。
例子:
#arch/x86_64/kernel/Makefile
EXTRA_AFLAGS := -traditional
$(EXTRA_LDFLAGS) 和 $(EXTRA_ARFLAGS) 都是类似的字符串为每个目录下的$(LD)和$(AR)提供选项。
例子:
#arch/m68k/fpsp040/Makefile
EXTRA_LDFLAGS := -x
--- 3.9 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.
(译)
--- 3.9 依赖跟踪
Kbuild跟踪依赖性如下所示:
1)所有的依赖文件(*.c和*.h)
2)CONFIG_选项被应用到所有的依赖文件中。
3)命令行常用来编译目标。
因此,如果你改变了$(CC)选项,那么所有受影响的文件将被重编。
--- 3.10 Special Rules
Special 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 is the architecture specific Makefiles which
needs special rules to prepare boot images etc.
Special rules are written as normal Make rules.
Kbuild is not executing in the directory where the Makefile is
located, so all special rules shall provide a relative
path to prerequisite files and target files.
Two variables are used when defining special rules:
$(src)
$(src) is a relative path which points to the directory
where the Makefile is located. Always use $(src) when
referring to files located in the src tree.
$(obj)
$(obj) is a relative path which points to the directory
where the target is saved. Always use $(obj) when
referring to generated files.
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 special 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).
(译)
--- 3.10 特殊规则
特殊规则在kbuild的下层结构不提供所需要的支持时被使用到。一个典型的例子是头文件在
build过程期间被产生。另一个例子是是体系指定的Makefiles,而这些Makefiles需要特殊的
规则去准备boot镜像等等。
写特殊规则跟普通的Make规则一样。Kbuild不会再Makefile所在的目录下被执行,所以所有的特殊
规则应该提供相对的路径给依赖文件和目标文件。
当定义特殊规则的时候,两个变量将被使用到:
$(src)
$(src) 是一个指向Makefile所在目录的相对路径,当引用src树下的本地文件时应该总是使用$(src)。
$(obj)
$(obj) 是一个指向存储目标目录的相对路径,当引用被产生的文件时应该总是使用$(obj)。
例子:
#drivers/scsi/Makefile
$(obj)/53c8xx_d.h: $(src)/53c7,8xx.scr $(src)/script_asm.pl
$(CPP) -DCHIP=810 - < $< | ... $(src)/script_asm.pl
=== 4 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-y.
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).
Both possibilities are described in the following.
(译)
=== 4 主机程序支持
Kbuild支持在编译阶段建立主机可执行程序。
下面两步是在使用可执行的主机程序时是必须的。
第一步是告诉kbuild主机程序存在。这里利用变量hostprogs-y来完成。
第二步是添加一个精确的依赖到可执行程序。这些有2种方法来完成。或者在规则
添加一个依赖,或者利用变量 $(always)。
这些可能事情的被描述如下面所示:
--- 4.1 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-y := 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.
(译)
--- 4.1 简单的主机程序
有一些情况是需要在主机上去编译和运行一个程序,当build正在运行的时候。
下面的行告诉了kbuild程序bin2hex在build的主机上应该被构建。
例子:
hostprogs-y := bin2hex
如上面的例子,Kbuild假定bin2hex由一个跟Makefile同在一个目录的名字为bin2hex.c的c源码文件构成。
--- 4.2 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.
$(-objs) list all objects used to link the final
executable.
Example:
#scripts/lxdialog/Makefile
hostprogs-y := 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 -y is not permitted for host-programs.
(译)
--- 4.2 构造主机程序
主机程序能够由基于混合objects组成。这些语法常用来为主机程序定义混合objects,类似于语法
被用来定义内核objects的用法。
$(-objs) 列出的所有objects是常用来链接成最终的可执行程序。
例子:
#scripts/lxdialog/Makefile
hostprogs-y := lxdialog
lxdialog-objs := checklist.o lxdialog.o
带有扩展名.o的Objects由相应的.c文件来编译。在上面的例子checklist.c被编译成checklist.o和
lxdialog.c被编译成lxdialog.o。
最后这两个.o文件都被链接成可执行文件lxdialog。
注意:语法 -y 是在主机程序里不允许的。
--- 4.3 Defining shared libraries
Objects with extension .so are considered shared libraries, and
will be compiled as position independent objects.
Kbuild provides support for shared libraries, but the usage
shall be restricted.
In the following example the libkconfig.so shared library is used
to link the executable conf.
Example:
#scripts/kconfig/Makefile
hostprogs-y := conf
conf-objs := conf.o libkconfig.so
libkconfig-objs := expr.o type.o
Shared libraries always require a corresponding -objs line, and
in the example above the shared library libkconfig is composed by
the two objects expr.o and type.o.
expr.o and type.o will be built as position independent code and
linked as a shared library libkconfig.so. C++ is not supported for
shared libraries.
(译)
--- 4.3 定义共享库
带有扩展名为.so的Objects被认为是共享库,将被编译为独立的objects。Kbuild提供支持共享库,
不过用法应该被限制。
在下面的例子,libkconfig.so共享库被链接为可执行文件conf。
例子:
#scripts/kconfig/Makefile
hostprogs-y := conf
conf-objs := conf.o libkconfig.so
libkconfig-objs := expr.o type.o
共享库总是需要一个相应的-objs行,在例子里上面的共享库libkconfig由两个objects expr.o和type.o组成。
expr.o和type.o将被建立为以位置独立的代码和被链接成共享库libkconfig.so。C++不被共享库所支持。
--- 4.4 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-y := 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 by a mixture of .c and .cc files, then an
additional line can be used to identify this.
Example:
#scripts/kconfig/Makefile
hostprogs-y := qconf
qconf-cxxobjs := qconf.o
qconf-objs := check.o
(译)
--- 4.4 在主机程序里使用C++
kbuild提供在主机上使用C++编程的支持。这将被独立的介绍去支持kconfig,但不推荐一般的使用。
例子:
#scripts/kconfig/Makefile
hostprogs-y := qconf
qconf-cxxobjs := qconf.o
上面例子里的可执行文件由C++文件qconf.cc来构成 - 通过$(qconf-cxxobjs)被鉴别。
如果qconf由混合的.c和.cc文件构成,那么附加一行能被用来鉴别这个。
例子:
#scripts/kconfig/Makefile
hostprogs-y := qconf
qconf-cxxobjs := qconf.o
qconf-objs := check.o
--- 4.5 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 $(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
HOSTLOADLIBES_qconf := -L$(QTDIR)/lib
When linking qconf it will be passed the extra option "-L$(QTDIR)/lib".
(译)
--- 4.5 为主机程序控制编译器选项
当编译主机程序时,很可能要设定指定的标志。程序将总是使用$(HOSTCC)来编译,$(HOSTCC)被传递
的选项在$(HOSTCFLAGS)里被指定。
去设置标志将影响所有的主机程序,这些程序在Makefile里使用变量HOST_EXTRACFLAGS被创建。
例子:
#scripts/lxdialog/Makefile
HOST_EXTRACFLAGS += -I/usr/include/ncurses
为一个简单的文件设置指定的标志,下面的构造被使用:
例子:
#arch/ppc64/boot/Makefile
HOSTCFLAGS_piggyback.o := -DKERNELBASE=$(KERNELBASE)
它同样可能给连接器指定附加的选项。
例子:
#scripts/kconfig/Makefile
HOSTLOADLIBES_qconf := -L$(QTDIR)/lib
当链接qconf时,它将被传递额外的选项 "-L$(QTDIR)/lib"。
--- 4.6 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 special rule.
Example:
#drivers/pci/Makefile
hostprogs-y := 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 special rules must be prefixed with $(obj).
(2) Use $(always)
When there is no suitable special rule, and the host program
shall be built when a makefile is entered, the $(always)
variable shall be used.
Example:
#scripts/lxdialog/Makefile
hostprogs-y := lxdialog
always := $(hostprogs-y)
This will tell kbuild to build lxdialog even if not referenced in
any rule.
(译)
--- 4.6 什么时候主机程序真正的被创建
Kbuild将建立主机程序,当且仅当他们作为一个依赖来被引用。
这是可能如下的两步:
(1)在一个特殊的规则里精确的列出这些依赖文件。
例子:
#drivers/pci/Makefile
hostprogs-y := gen-devlist
$(obj)/devlist.h: $(src)/pci.ids $(obj)/gen-devlist
( cd $(obj); ./gen-devlist ) < $<
目标$(obj)/devlist.h在$(obj)/gen-devlist更新之前将不被建立。注意在特殊的
规则里引用主机程序必须带有前缀$(obj)。
(2)使用 $(always)
当没有特殊的规则,主机程序在进入makefile时应该被建立,变量$(always)应该被使用。
例子:
#scripts/lxdialog/Makefile
hostprogs-y := lxdialog
always := $(hostprogs-y)
这个将告诉kbuild去建立lxdialog甚至如果没在任何的规则里被引用到。
--- 4.7 Using hostprogs-$(CONFIG_FOO)
A typcal pattern in a Kbuild file lok like this:
Example:
#scripts/Makefile
hostprogs-$(CONFIG_KALLSYMS) += kallsyms
Kbuild knows about both 'y' for built-in and 'm' for module.
So if a config symbol evaluate to 'm', kbuild will still build
the binary. In other words Kbuild handle hostprogs-m exactly
like hostprogs-y. But only hostprogs-y is recommend used
when no CONFIG symbol are involved.
(译)
--- 4.7 使用 hostprogs-$(CONFIG_FOO)
在Kbuild里, 一个典型的模式看起来像这样:
例子:
#scripts/Makefile
hostprogs-$(CONFIG_KALLSYMS) += kallsyms
Kbuild知道关于'y' 是供给 built-in 和 'm' 供给 module 使用的。
所以如果一个配置符号被评估为'm',kbuild将仍然建立这个二进制文件。换句话来说
Kbuild处理hostprogs-m非常像hostprogs-y那样。但是当没有CONFIG符号被调用的时候,
仅仅hostprogs-y被推荐使用。
=== 5 Kbuild clean infrastructure
"make clean" deletes most generated files in the src tree where the kernel
is compiled. This includes generated files such as host programs.
Kbuild knows targets listed in $(hostprogs-y), $(hostprogs-m), $(always),
$(extra-y) 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 src tree when
"make clean" is executed.
Additional files can be specified in kbuild makefiles by use of $(clean-files).
Example:
#drivers/pci/Makefile
clean-files := devlist.h classlist.h
When executing "make clean", the two files "devlist.h classlist.h" will
be deleted. Kbuild will assume files to be in same relative directory as the
Makefile except if an absolute path is specified (path starting with '/').
(译)
=== 5 Kbuild 清除下层结构
"make clean"删除大部分在内核编译的源码树里被产生的文件。这包含被产生的文件如主机程序。
Kbuild 知道在$(hostprogs-y), $(hostprogs-m), $(always),$(extra-y) 和 $(targets)里目标列表。
它们在"make clean"期间将区别被删除。与模式"*.[oas]", "*.ko",匹配的文件,加上附加被kbuild产生
的文件在整个内核源码树立被删除,当"make clean"被执行。
附加的文件能够在kbuild makefile里通过使用$(clean-files)来指定。
例子:
#drivers/pci/Makefile
clean-files := devlist.h classlist.h
当执行"make clean",这两个文件"devlist.h classlist.h"将被删除。 Kbuild将假定文件处在跟makefile同样
的相对目录,除非如果一个绝对路径被指定(路径以'/'开头)。
To delete a directory hirachy use:
Example:
#scripts/package/Makefile
clean-dirs := $(objtree)/debian/
This will delete the directory debian, including all subdirectories.
Kbuild will assume the directories to be in the same relative path as the
Makefile if no absolute path is specified (path does not start with '/').
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/i386/boot/Makefile
subdir- := compressed/
The above assignment instructs kbuild to descend down in the
directory compressed/ when "make clean" is executed.
To support the clean infrastructure in the Makefiles that builds the
final bootimage there is an optional target named archclean:
Example:
#arch/i386/Makefile
archclean:
$(Q)$(MAKE) $(clean)=arch/i386/boot
When "make clean" is executed, make will descend down in arch/i386/boot,
and clean as usual. The Makefile located in arch/i386/boot/ may use
the subdir- trick to descend further down.
Note 1: arch/$(ARCH)/Makefile cannot use "subdir-", because that file is
included in the top level makefile, and the kbuild infrastructure
is not operational at that point.
Note 2: All directories listed in core-y, libs-y, drivers-y and net-y will
be visited during "make clean".
(译)
去删除一个目录层使用:
例子:
#scripts/package/Makefile
clean-dirs := $(objtree)/debian/
这将删除目录debian,包括所有的子目录们。Kuild将假定这些目录跟makefile具有相同的
相对路径,如果没有绝对路径被指定(路径以'/'开头)。
通常kbuild下降到子目录因为这个"obj-* := dir/",但是在这个体系结构里的makefiles,在
某些地方kbuild下层结构不是很充分,这样有时需要被精确指出。
例子:
#arch/i386/boot/Makefile
subdir- := compressed/
上面的赋值指示了kbuild去下降到目录compressed/,当"make clean"被执行。
为了支持在makefile里清除建立最终bootimage的下层结构,有个可选的目标叫做archclean。
例子:
#arch/i386/Makefile
archclean:
$(Q)$(MAKE) $(clean)=arch/i386/boot
当"make clean"被执行,make将下降到arch/i386/boot里,像普通那样清楚目标。
处在arch/i386/boot/目录下的makefile可能使用subdir-的技巧来下降到更深的目录。
注意 1:arch/$(ARCH)/Makefile不能够使用"subdir-",因为这文件被包含到顶层makefile,
这个kbuild的下层结构在这个位置不可运作。
注意 2:所有在core-y, libs-y, drivers-y 和 net-y列表里的目录将在"make clean"时被访问到。
=== 6 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 the
arch/$(ARCH)/Makefile contains what is required to set-up kbuild
to the said architecture.
To do so arch/$(ARCH)/Makefile sets a number of variables, and defines
a few targets.
When kbuild executes the following steps are followed (roughly):
1) Configuration of the kernel => produced .config
2) Store kernel version in include/linux/version.h
3) Symlink include/asm to include/asm-$(ARCH)
4) Updating all other prerequisites to the target prepare:
- Additional prerequisites are specified in arch/$(ARCH)/Makefile
5) Recursively descend down in all directories listed in
init-* core* drivers-* net-* libs-* and build all targets.
- The value of the above variables are extended in arch/$(ARCH)/Makefile.
6) All object files are then linked and the resulting file vmlinux is
located at the root of the src tree.
The very first objects linked are listed in head-y, assigned by
arch/$(ARCH)/Makefile.
7) 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
(译)
=== 6 体系 Makefiles
顶层的Makefile在开始下降进入个别目录之前设置环境和做好一切的准备工作。
顶层Makefile包含通用的部分,然而arch/$(ARCH)/Makefile包含所需求的设置kbuild
为所说的体系。
去完成这样的arch/$(ARCH)/Makefile,设置大量变量和定义一些目标。
kbuild依次地执行下面步骤(粗略地):
1)配置内核 => 产生.config文件
2)存储内核版本到include/linux/version.h。
3)建立符号链接 include/asm 链接到 include/asm-$(ARCH)
4)更新目标所有其他依赖准备:
-- 附加的依赖在arch/$(ARCH)/Makefile里被指定。
5)递归下降到所有的目录,这些目录被列表在init-* core* drivers-* net-* libs-*,
里面, 和建立所有的目标。
6) 所有的object文件都然后被链接和结果文件vmlinux被放置在源码树的根目录里。
在head-y列表里的最先的objects在arch/$(ARCH)/Makefile里被赋值。
7) 最后,这个体系指定部分完成所有需要的后置处理和建立最终的bootimage。
- 这包括建立boot记录
- 准备initrd 镜像和the like
--- 6.1 Set variables to tweak the build to the architecture
LDFLAGS Generic $(LD) options
Flags used for all invocations of the linker.
Often specifying the emulation is sufficient.
Example:
#arch/s390/Makefile
LDFLAGS := -m elf_s390
Note: EXTRA_LDFLAGS and LDFLAGS_$@ can be used to further customise
the flags used. See chapter 7.
LDFLAGS_MODULE Options for $(LD) when linking modules
LDFLAGS_MODULE is used to set specific flags for $(LD) when
linking the .ko files used for modules.
Default is "-r", for relocatable output.
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.
LDFLAGS_vmlinux uses the LDFLAGS_$@ support.
Example:
#arch/i386/Makefile
LDFLAGS_vmlinux := -e stext
OBJCOPYFLAGS objcopy flags
When $(call if_changed,objcopy) is used to translate a .o file,
then 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.
AFLAGS $(AS) assembler flags
Default value - see top level Makefile
Append or modify as required per architecture.
Example:
#arch/sparc64/Makefile
AFLAGS += -m64 -mcpu=ultrasparc
CFLAGS $(CC) compiler flags
Default value - see top level Makefile
Append or modify as required per architecture.
Often the CFLAGS variable depends on the configuration.
Example:
#arch/i386/Makefile
cflags-$(CONFIG_M386) += -march=i386
CFLAGS += $(cflags-y)
Many arch Makefiles dynamically run the target C compiler to
probe supported options:
#arch/i386/Makefile
...
cflags-$(CONFIG_MPENTIUMII) += $(call cc-option,\
-march=pentium2,-march=i686)
...
# Disable unit-at-a-time mode ...
CFLAGS += $(call cc-option,-fno-unit-at-a-time)
...
The first examples utilises the trick that a config option expands
to 'y' when selected.
CFLAGS_KERNEL $(CC) options specific for built-in
$(CFLAGS_KERNEL) contains extra C compiler flags used to compile
resident kernel code.
CFLAGS_MODULE $(CC) options specific for modules
$(CFLAGS_MODULE) contains extra C compiler flags used to compile code
for loadable kernel modules.
(译)
--- 6.1 设置变量,调节build来适应体系
LDFLAGS 通用的 $(LD) 选项
这些标志被所有链接器使用。经常指定仿真器是充要的。
例子:
#arch/s390/Makefile
LDFLAGS := -m elf_s390
注意: EXTRA_LDFLAGS 和 LDFLAGS_$@ 能够在今后定制标志被使用。见第7章。
LDFLAGS_MODULE 选项 $(LD) 当链接模块时使用
LDFLAGS_MODULE 常常为$(LD)设置指定标志,当链接.ko文件称模块时。默认是 "-r",
表示可重定位输出。
LDFLAGS_vmlinux 选项$(LD) 当链接vmlinux时使用
LDFLAGS_vmlinux 常常指定附加标志传递给链接器,当链接最终vmlinux时。LDFLAGS_vmlinux
使用 LDFLAGS_$@ 来支持。
例子:
#arch/i386/Makefile
LDFLAGS_vmlinux := -e stext
OBJCOPYFLAGS objcopy 标志
当$(call if_changed,objcopy)常常用来转换.o文件,那么使用在OBJCOPYFLAGS里指定标志。
$(call if_changed,objcopy) 是经常用来在vmlinux里产生原始二进制。
例子:
#arch/s390/Makefile
OBJCOPYFLAGS := -O binary
#arch/s390/boot/Makefile
$(obj)/image: vmlinux FORCE
$(call if_changed,objcopy)
在这个例子里,二进制目标$(obj)/image是vmlinux的二进制版本。$(call if_changed,xxx)
的用法将在后面被描述。
AFLAGS $(AS) 汇编标志
默认值 - 见顶层Makefile,根据不同的体系需求添加或修改。
例子:
#arch/sparc64/Makefile
AFLAGS += -m64 -mcpu=ultrasparc
CFLAGS $(CC) 编译标志
默认值 - 见顶层Makefile,根据不同的体系需求添加或修改。经常 CFLAGS 变量取决于配置。
例子:
#arch/i386/Makefile
cflags-$(CONFIG_M386) += -march=i386
CFLAGS += $(cflags-y)
许多体系Makefiles动态地运行C编译器去探测被支持的选项:
#arch/i386/Makefile
...
cflags-$(CONFIG_MPENTIUMII) += $(call cc-option,\
-march=pentium2,-march=i686)
...
# Disable unit-at-a-time mode ...
CFLAGS += $(call cc-option,-fno-unit-at-a-time)
...
第一个例子利用技巧,当被选择时配置选项被扩展为'y'。
CFLAGS_KERNEL $(CC) 为built-in指定选项
$(CFLAGS_KERNEL) 包含额外的C编译标志用来编译居处在内核里的代码。
CFLAGS_MODULE $(CC) 为modules指定选项
$(CFLAGS_MODULE) 包含额外的 C 编译标志来用编译可重加载的内核模块代码。
--- 6.2 Add prerequisites to prepare:
The prepare: rule is used to list prerequisites that needs to be
built before starting to descend down in the subdirectories.
This is usual header files containing assembler constants.
Example:
#arch/s390/Makefile
prepare: include/asm-$(ARCH)/offsets.h
In this example the file include/asm-$(ARCH)/offsets.h will
be built before descending down in the subdirectories.
See also chapter XXX-TODO that describe how kbuild supports
generating offset header files.
(译)
--- 6.2 添加依赖文件到 prepare目标:
目标prepare:这规则被用来在下降访问子目录前建立必要文件的列表。这里是普通的头文件包含
汇编实例。
例子:
#arch/s390/Makefile
prepare: include/asm-$(ARCH)/offsets.h
在这个例子里, 文件include/asm-$(ARCH)/offsets.h 将在下降访问子目录之前被建立。
参见XXX-TODO章节,描述如何kbuild支持产生头文件编译。
--- 6.3 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.
head-y, init-y, core-y, libs-y, drivers-y, net-y
$(head-y) list objects to be linked first in vmlinux.
$(libs-y) list directories where a lib.a archive can be located.
The rest list directories where a built-in.o object file can be located.
$(init-y) objects will be located after $(head-y).
Then the rest follows in this order:
$(core-y), $(libs-y), $(drivers-y) and $(net-y).
The top level Makefile define values for all generic directories,
and arch/$(ARCH)/Makefile only adds architecture specific directories.
Example:
#arch/sparc64/Makefile
core-y += arch/sparc64/kernel/
libs-y += arch/sparc64/prom/ arch/sparc64/lib/
drivers-$(CONFIG_OPROFILE) += arch/sparc64/oprofile/
(译)
--- 6.3 下降访问列表目录
一个体系Makefile协同顶层的Makefile去定义变量如何去建立vmlinux文件。注意没有给模块相应的
指定体系段;基于建立模块的机器都是体系独立的。
head-y, init-y, core-y, libs-y, drivers-y, net-y
$(head-y) 列表 objects 是最先被链接到vmlinux的。
$(libs-y) 列表目录存储lib.a库信息。
其余列表目录存储着built-in.o object文件。
$(init-y) objects被安排在紧跟$(head-y)之后。
那么其余的服从下面的顺序:
$(core-y), $(libs-y), $(drivers-y) 和 $(net-y).
顶层Makefile为所有的普通目录定义值和 arch/$(ARCH)/Makefile 紧紧添加指定体系的目录。
例子:
#arch/sparc64/Makefile
core-y += arch/sparc64/kernel/
libs-y += arch/sparc64/prom/ arch/sparc64/lib/
drivers-$(CONFIG_OPROFILE) += arch/sparc64/oprofile/
--- 6.4 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/$(ARCH)/.
Kbuild does not provide any smart way to support building a
target specified in boot/. Therefore arch/$(ARCH)/Makefile shall
call make manually to build a target in boot/.
The recommended approach is to include shortcuts in
arch/$(ARCH)/Makefile, and use the full path when calling down
into the arch/$(ARCH)/boot/Makefile.
Example:
#arch/i386/Makefile
boot := arch/i386/boot
bzImage: vmlinux
$(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
"$(Q)$(MAKE) $(build)=" is the recommended way to invoke
make in a subdirectory.
There are no rules for naming of the architecture specific targets,
but executing "make help" will list all relevant targets.
To support this $(archhelp) must be defined.
Example:
#arch/i386/Makefile
define archhelp
echo '* bzImage - Image (arch/$(ARCH)/boot/bzImage)'
endef
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/i386/Makefile
all: bzImage
When "make" is executed without arguments, bzImage will be built.
(译)
--- 6.4 体系特定的 boot images
一个体系的Makefile指定目标,取 vmlinux 文件,压缩它,封装它到bootstrapping代码里,在某处复制结果文件。
这包括各类的安装命令。实际的目标还没在体系中标准化。
通常在本地的arch/$(ARCH)/boot/目录做一些附加的处理。
Kbuild不提供任何智能的方法支持建立在boot/目录下被指定的目标。因此在boot/目录下,
arch/$(ARCH)/Makefile应该调用手动地调用make去建立目录。
推荐的方法是在arch/$(ARCH)/Makefile里包含快捷方式,使用全路径当向下进入arch/$(ARCH)/boot/Makefile时。
例子:
#arch/i386/Makefile
boot := arch/i386/boot
bzImage: vmlinux
$(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
"$(Q)$(MAKE) $(build)=" 是一种推荐方法在子目录里调用make。
没有规则用来命名指定目标的体系,但是执行"make help" 将列出所有相关的目标。
为了支持这个, $(archhelp)必须被定义。
例子:
#arch/i386/Makefile
define archhelp
echo '* bzImage - Image (arch/$(ARCH)/boot/bzImage)'
endef
当make不带任何参数的被执行,第一个被遇到目标将被创建。在顶层的makefile里,第一个目标呈现的是all:。
一个体系应当总是每次默认的建立一个可启动的镜像。在"make help"默认的目标用'*'来标注。增加一个新的依赖文件
给all: 去选择一个跟vmlinux不同的默认目标。
例子:
#arch/i386/Makefile
all: bzImage
当"make"不带参数的执行时,bzImage将被建立。
--- 6.5 Building non-kbuild targets
extra-y
extra-y specify additional targets created in the current
directory, in addition to any targets specified by obj-*.
Listing all targets in extra-y is required for two purposes:
1) Enable kbuild to check changes in command lines
- When $(call if_changed,xxx) is used
2) kbuild knows what files to delete during "make clean"
Example:
#arch/i386/kernel/Makefile
extra-y := head.o init_task.o
In this example extra-y is used to list object files that
shall be built, but shall not be linked as part of built-in.o.
(译)
--- 6.5 建立non-kbuild目标
extra-y
extra-y 指定附加的目标,在当前的目录被创建,又加到通过obj-*任何指定的目标。
在extra-y里列出所有目标是有需要的,因为如下两个目的:
1) 使到kbuild能在命令行里去检查改变,当$(call if_changed,xxx)被使用。
2) kbuild知道什么文件在"make clean"的时候被删除
例子:
#arch/i386/kernel/Makefile
extra-y := head.o init_task.o
在这个例子里,extra-y 被用来列出应当被建立object文件,但是不应该被链接成 built-in.o 的一部分。
--- 6.6 Commands useful for building a boot image
Kbuild provides a few macros that are useful when building a
boot image.
if_changed
if_changed is the infrastructure used for the following commands.
Usage:
target: source(s) FORCE
$(call if_changed,ld/objcopy/gzip)
When the rule is evaluated it is checked to see if any files
needs an update, or the commandline has changed since last
invocation. The latter will force a rebuild if any options
to the executable have changed.
Any target that utilises if_changed must be listed in $(targets),
otherwise the command line check will fail, and the target will
always be built.
Assignments to $(targets) are without $(obj)/ prefix.
if_changed may be used in conjunction with custom commands as
defined in 6.7 "Custom kbuild commands".
Note: It is a typical mistake to forget the FORCE prerequisite.
ld
Link target. Often LDFLAGS_$@ is used to set specific options to ld.
objcopy
Copy binary. Uses OBJCOPYFLAGS usually specified in
arch/$(ARCH)/Makefile.
OBJCOPYFLAGS_$@ may be used to set additional options.
gzip
Compress target. Use maximum compression to compress target.
Example:
#arch/i386/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 assinged all potential targets, herby 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
free us from listing the setup.o and bootsect.o files.
Note: It is a common mistake to forget the "target :=" assignment,
resulting in the target file being recompiled for no
obvious reason.
(译)
--- 6.6 建立boot image的有用的命令
Kbuild提供一些宏,当建立boot image时它们非常有用。
if_changed
if_changed 是基础宏被用在如下的命令:
Usage:
target: source(s) FORCE
$(call if_changed,ld/objcopy/gzip)
当规则被评估,它被检查是否有任何的文件需要更新,或者命令行因为最后的调用而改变了。
后面的将被强制的重建,如果给可执行文件的任何选项改变了。
任何目标使用必须在$(targets)里被列出来。否则命令行检查将失败,目标将总是被建立。
赋值到$(targets)是不需要前缀 $(obj)/ 的,if_changed可能在联合定制命令(例如6.7 "Custom kbuild commands") 被使用到。
注意:这是一个典型的错误由于忘记添加 FORCE 这个依赖。
ld
链接目标。通常LDFLAGS_$@被用来设定指定的参数给 ld 。
objcopy
复制二进制。使用 OBJCOPYFLAGS,通常在arch/$(ARCH)/Makefile里被指定。OBJCOPYFLAGS_$@ 可以被用来设定附加选项。
gzip
压缩目标。使用最大压缩去压缩目标。
例子:
#arch/i386/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)
在这个例子里,有两个可能的目标,需要不同的选项供给链接器,链接器选项通过使用LDFLAGS_$@语法来
指定 - 一个是给每个可能的目标。$(targets)被赋值给所有可能的目标,因此kbuild知道这些目标,将要:
1) 命令行改变检查
2) 在make clean期间删除目标
依赖部分": %: %.o"是一种速记帮助我们列出setup.o和bootsect.o文件。
注意:有个一公共的错误是忘记了"target :="赋值,导致很不明显的理由在目标文件里被重编。
--- 6.7 Custom kbuild commands
When kbuild is executing with KBUILD_VERBOSE=0 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_ - what shall be echoed
cmd_ - the command to execute
Example:
#
quiet_cmd_image = BUILD $@
cmd_image = $(obj)/tools/build $(BUILDFLAGS) \
$(obj)/vmlinux.bin > $@
targets += bzImage
$(obj)/bzImage: $(obj)/vmlinux.bin $(obj)/tools/build FORCE
$(call if_changed,image)
@echo 'Kernel: $@ is ready'
When updating the $(obj)/bzImage target the line:
BUILD arch/i386/boot/bzImage
will be displayed with "make KBUILD_VERBOSE=0".
(译)
--- 6.7 定制kbuild命令
当kbuild使用KBUILD_VERBOSE=0执行时,那么仅仅命令速记正常被显示。
为了激活这行为去定制命令kbuild需要两个变量被设置:
quiet_cmd_ - what shall be echoed
cmd_ - the command to execute
例子:
#
quiet_cmd_image = BUILD $@
cmd_image = $(obj)/tools/build $(BUILDFLAGS) \
$(obj)/vmlinux.bin > $@
targets += bzImage
$(obj)/bzImage: $(obj)/vmlinux.bin $(obj)/tools/build FORCE
$(call if_changed,image)
@echo 'Kernel: $@ is ready'
当更新$(obj)/bzImage目标, 所示:
BUILD arch/i386/boot/bzImage
将显示为 "make KBUILD_VERBOSE=0"。
--- 6.8 Preprocessing linker scripts
When the vmlinux image is build the linker script:
arch/$(ARCH)/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 file and includes a rule *lds.S -> *lds.
Example:
#arch/i386/kernel/Makefile
always := vmlinux.lds
#Makefile
export CPPFLAGS_vmlinux.lds += -P -C -U$(ARCH)
The assigment to $(always) is used to tell kbuild to build the
target: vmlinux.lds.
The assignment to $(CPPFLAGS_vmlinux.lds) tell kbuild to use the
specified options when building the target vmlinux.lds.
When building the *.lds target kbuild used the variakles:
CPPFLAGS : Set in top-level Makefile
EXTRA_CPPFLAGS : 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 file are used in several
architecture specific files.
(译)
--- 6.8 预处理链接器脚本
当vmlinux镜像被建立,使用链接脚本arch/$(ARCH)/kernel/vmlinux.lds。
这脚本被放置在共同的目录下,是文件vmlinux.lds.S预处理后的变种。
kbuild知道.lds文件和包含规则 *lds.S -> *lds.
例子:
#arch/i386/kernel/Makefile
always := vmlinux.lds
#Makefile
export CPPFLAGS_vmlinux.lds += -P -C -U$(ARCH)
赋值到 $(always)被用来告诉kbuild去建立目标:vmlinux.lds 。
赋值到 $(CPPFLAGS_vmlinux.lds)告诉kbuild使用指定的选项,当建立vmlinux.lds目标时。
当建立目标 *.lds时, kbuild 使用变量:
CPPFLAGS : 设置最高层的makefile
EXTRA_CPPFLAGS : 可以在kbuild makefile里被设置
CPPFLAGS_$(@F) : 目标指定的标志
注意这里的赋值使用到全路径名。
建立*lds的kubild组织在几个指定文件的体系里被用到。
--- 6.9 $(CC) support functions
The kernel may be build with several different versions of
$(CC), each supporting a unique set of features and options.
kbuild provide basic support to check for valid options for $(CC).
$(CC) is useally the gcc compiler, but other alternatives are
available.
cc-option
cc-option is used to check if $(CC) support a given option, and not
supported to use an optional second option.
Example:
#arch/i386/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.
cc-option-yn
cc-option-yn is used to check if gcc 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 to y the expanded variables $(aflags-y)
and $(cflags-y) will be assigned the values -a32 and -m32.
cc-option-align
gcc version >= 3.0 shifted type of options used to speify
alignment of functions, loops etc. $(cc-option-align) whrn used
as prefix to the align options will select the right prefix:
gcc < 3.00
cc-option-align = -malign
gcc >= 3.00
cc-option-align = -falign
Example:
CFLAGS += $(cc-option-align)-functions=4
In the above example the option -falign-functions=4 is used for
gcc >= 3.00. For gcc < 3.00 -malign-functions=4 is used.
cc-version
cc-version return a numerical version of the $(CC) compiler version.
The format is where both are two digits. So for example
gcc 3.41 would return 0341.
cc-version is useful when a specific $(CC) version is faulty in one
area, for example the -mregparm=3 were broken in some gcc version
even though the option was accepted by gcc.
Example:
#arch/i386/Makefile
GCC_VERSION := $(call cc-version)
cflags-y += $(shell \
if [ $(GCC_VERSION) -ge 0300 ] ; then echo "-mregparm=3"; fi ;)
In the above example -mregparm=3 is only used for gcc version greater
than or equal to gcc 3.0.
(译)
--- 6.9 $(CC) 支持函数
内核可能由几个不同版本的$(CC)来建立,每个支持一个唯一的功能集和选项。
kbuild提供基本的支持,去检查$(CC)的有效选项。
$(CC) 通常是gcc编译器,但是其他的代替也是有效的。
cc-option
cc-option 被用来检查 $(CC)是否支持一个给出的选项和不支持去使用一个可选的第二选项。
例子:
#arch/i386/Makefile
cflags-y += $(call cc-option,-march=pentium-mmx,-march=i586)
在上面的例子里,cflags-y将被赋值给选项-march=pentium-mmx 如果被$(CC)所支持。否则是-march-i586。
第二参数给cc-option是可选的,如果被省略,cflags-y将被赋值为空,假如第一个选项不支持的话。
cc-option-yn
cc-option-yn 被用来检查gcc 是否支持一个给出的选项,和返回'y'如果被支持,否则返回 'n'。
例子:
#arch/ppc/Makefile
biarch := $(call cc-option-yn, -m32)
aflags-$(biarch) += -a32
cflags-$(biarch) += -m32
在上面的例子,$(biarch) 被赋值为 y 如果 $(CC) 支持选项 -m32。当 $(biarch) 等于 y,扩展变量$(aflags-y)
和 $(cflags-y) 将被赋值为 -a32 和 -m32。
cc-option-align
gcc version >= 3.0 转变选项的类型被用来指定功能的赋值,循环等等。$(cc-option-align) 当被
使用作为前缀给赋值选项将选择右边的前缀:
gcc < 3.00
cc-option-align = -malign
gcc >= 3.00
cc-option-align = -falign
例子:
CFLAGS += $(cc-option-align)-functions=4
在上面的例子,选项-falign-functions=4供gcc >= 3.00使用。由于gcc < 3.00 -malign-functions=4 将被取用。
cc-version
cc-version 返回$(CC)编译器的数字版本。它的格式是 ,这两个地方都由数字组成。因此例如
gcc 3.41 将返回0341。
cc-version 是非常有用当指定 $(CC) 版本在一处有毛病,例如 -mregparm=3 被分为一些gcc的版本,甚至尽管这些选项
都被gcc所接受。
例子:
#arch/i386/Makefile
GCC_VERSION := $(call cc-version)
cflags-y += $(shell \
if [ $(GCC_VERSION) -ge 0300 ] ; then echo "-mregparm=3"; fi ;)
在上面的例子里,-mregparm=3 仅仅供大于或等于gcc 3.0的版本使用。
=== 7 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 ...
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.
(译)
=== 7 Kbuild 变量
顶层的Makefile导出下面的变量:
VERSION, PATCHLEVEL, SUBLEVEL, EXTRAVERSION
这些变量定义了当前的版本号。一些体系makefiles真实地直接地使用这些值;他们应该使用$(KERNELRELEASE)来代替。
$(VERSION), $(PATCHLEVEL), 和 $(SUBLEVEL) 定义了基本的三部分的版本号,例如 "2", "4", 和 "0"。这三个值总是数字。
$(EXTRAVERSION) 定义了一个非常细微的子级别给预补丁或者附加的补丁。它通常是一些非数字的串,例如 "-pre4",经常是空白。
KERNELRELEASE
$(KERNELRELEASE) 是一个简单的字符串如 "2.4.0-pre4"。适合去构造安装目录名或
在版本串里显示。一些体系Makefiles为这个目的而使用它。
ARCH
这个变量定义了目标体系,例如"i386","arm",或 "sparc"。一些kbuild makefiles测试$(ARCH)来
侦测哪一些文件需要被编译。
默认地,顶层的Makefile设置$(ARCH)跟主机系统体系相同。如果是交叉编译,那么用户在命令行里重载这个$(ARCH)值:
make ARCH=m68k ...
INSTALL_PATH
这个变量定义一个地方给体系Makefiles去安装内核的image和System.map文件。使用这个给体系指定安装目标。
INSTALL_MOD_PATH, MODLIB
$(INSTALL_MOD_PATH) 为模块安装指定一个前缀到$(MODLIB)。这个变量在Makefile里没有被定义,但可以被用户传进来,如何需要的话。
$(MODLIB) 指定模块的安装目录。顶层的Makefile定义了$(MODLIB)到$(INSTALL_MOD_PATH)/lib/modules/$(KERNELRELEASE)。用户可能
要在命令行里重载这个值,如果需要的话。
=== 8 Makefile language
The kernel Makefiles are designed to 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.
(译)
=== 8 Makefile语言
内核Makefiles被设置给GNU Make运行。这个Makefiles使用仅仅使用到GNU Make里文档里
有记录的功能,但是他们使用了许多GNU扩展的功能。
GNU Make支持基本的列表处理函数。内核Makefiles使用了一个奇异的列表风格利用一些"if"
语句来建立和操作。
GNU Make 有两种赋值操作,":="和"="。":="立即执行右边的评估和存储一个实际的字符串到左边。
"="就像一个公式的定义;它以已评估的格式存储右边内容,然后每次评估这个格式,左边的会被使用到。
有一些情况在那里的"=" 是可以适合的,通常,尽管":="是最恰当的选择。
=== 9 Credits
Original version made by Michael Elizabeth Chastain,
Updates by Kai Germaschewski
Updates by Sam Ravnborg
(译)
=== 9 Credits
原始的版本是由Michael Elizabeth Chastain来完成的,
被Kai Germaschewski 更新。
被Sam Ravnborg 更新。
=== 10 TODO
- Describe how kbuild support shipped files with _shipped.
- Generating offset header files.
- Add more variables to section 7?
(译)
=== 10 TODO
- 描述kbuild如何支持使用_shipped来搬运文件。
- 产生偏移头文件。
- 在第7章立增加更多的变量。
阅读(1500) | 评论(0) | 转发(0) |