冷烟花
哎呀哎呀哎呀我的妈~蜗牛背着那重重的壳呀,一步一步地往上爬~

--译自Linux3.9.5 Kernel Makefiles(内核目录documention/kbuild/makefiles.txt)

kbuild(kernel build)

内核编译器

This document describes the Linux kernel Makefiles

本文档介绍了Linux内核的Makefile

=== Table of Contents
===
目录

=== 1 Overview

=== 1 概述

=== 2 Who does what

=== 2 角色分工

=== 3 The kbuild files

              === 3 内核编译文件

--- 3.1 Goal definitions

                            --- 3.1 目标定义

--- 3.2 Built-in object goals - obj-y

--- 3.2 内嵌对象 - obj-y

--- 3.3 Loadable module goals - obj-m

--- 3.3 可加载模块 - obj-m

--- 3.4 Objects which export symbols

--- 3.4 导出符号

--- 3.5 Library file goals - lib-y

--- 3.5 库文件 - lib-y

--- 3.6 Descending down in directories

--- 3.6 目录递归

--- 3.7 Compilation flags

--- 3.7 编译标记

--- 3.8 Command line dependency

--- 3.8 命令依赖

--- 3.9 Dependency tracking

--- 3.9 依赖关系

--- 3.10 Special Rules

--- 3.10 特殊规则

--- 3.11 $(CC) support functions

--- 3.11 $(CC) 支持的函数

--- 3.12 $(LD) support functions

--- 3.12 $(LD) 支持的函数

=== 4 Host Program support

=== 4 辅助程序
       
        
--- 4.1 Simple Host Program

--- 4.1 简单辅助程序

--- 4.2 Composite Host Programs
        --- 4.2
组合辅助程序

--- 4.3 Defining shared libraries
        --- 4.3
定义共享库 

--- 4.4 Using C++ for host programs
        --- 4.4 C++
语言编写的辅助程序使用方法

--- 4.5 Controlling compiler options for host programs
        --- 4.5
辅助程序编译控制选项

--- 4.6 When host programs are actually built
        --- 4.6
何时建立辅助程序

--- 4.7 Using hostprogs-$(CONFIG_FOO)
        --- 4.7
使用hostprogs-$(CONFIG_FOO)

=== 5 Kbuild clean infrastructure

=== 5 编译清除机制

=== 6 Architecture Makefiles
=== 6
架构Makefile文件

         --- 6.1 Set variables to tweak the build to the architecture

--- 6.1 设置变量调整构建的体系结构

--- 6.2 Add prerequisites to archheaders:

--- 6.2 增加预设置项到archheaders

--- 6.3 Add prerequisites to archprepare:

--- 6.3 增加预设置项到archprepare

--- 6.4 List directories to visit when descending
        --- 6.4
递归向下访问的目录列表

--- 6.5 Architecture-specific boot images
        --- 6.5
具体架构的引导映像

--- 6.6 Building non-kbuild targets
        --- 6.6
编译非内核目标

--- 6.7 Commands useful for building a boot image
        --- 6.7
构建引导映像的命令

--- 6.8 Custom kbuild commands
        --- 6.8
自定义内核编译命令

--- 6.9 Preprocessing linker scripts
        --- 6.9
预处理连接脚本

--- 6.10 Generic header files
        --- 6.10
通用头文件

         === 7 Kbuild syntax for exported headers

=== 7 导出头文件的Kbuild语法

                   --- 7.1 header-y

                   --- 7.2 genhdr-y

                   --- 7.3 destination-y

                   --- 7.4 generic-y

=== 8 Kbuild Variables

=== 8 Kbuild变量

=== 9 Makefile language

=== 9 Makefile语言
        === 10 Credits

=== 11 TODO

===  Contents

=== 正文

=== 1 Overview

=== 1 概述


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.

Makefile包括五部分:
     Makefile                       
顶层Makefile文件

     .config                           
内核配置文件
     arch/$(ARCH)/Makefile     
机器体系结构相关Makefile文件
     scripts/Makefile.*     
所有内核Makefiles共用规则
     kbuild Makefiles
其它makefile
文件
The top Makefile reads the .config file, which comes from the kernel configuration process.

通过内核配置操作产生.config文件,顶层Makefile文件读取该文件的配置.

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.

顶层Makefile文件负责产生两个主要的程序:vmlinux (内核image)和模块.顶层Makefile文件根据内核配置,通过递归编译内核代码树子目录建立这两个文件.顶层Makefile文件里包含一个名为 arch/$(ARCH)/Makefile的架构makefile文件.架构Makefile文件为顶层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.

每一个子目录有一个makefile文件,子目录makefile文件根据上级目录makefile文件命令启动编译.这些makefile使用.config文件配置数据构建各种文件列表,并使用这些文件列表编译内嵌或模块目标文件.scripts/Makefile.*包含了所有的定义和规则,makefile文件一起编译出内核程序.

=== 2 Who does what

=== 2 角色分工


People have four different relationships with the kernel Makefiles.

用户与内核makefile存在四种不同的关系:
*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).

*用户* 用户使用"make menuconfig""make"命令编译内核.他们通常不读或编辑内核makefile文件或其他源文件.
*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.

*普通开发者* 普通开发者维护设备驱动程序、文件系统和网络协议代码,他们维护相关子系统的makefile文件,因此他们需要内核makefile文件整体性的一般知识和关于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.

*体系开发者* 体系开发者关注一个整体的体系架构,比如sparc或者ia64.体系开发者既需要掌握关于体系的makefile文件,也要熟悉内核makefile文件.
*Kbuild developers* are people who work on the kernel build system itself. These people need to know about all aspects of the kernel Makefiles.

*内核开发者* 内核开发者关注内核编译系统本身.他们需要清楚内核makefile文件的所有方面.
This document is aimed towards normal developers and arch developers.

本文档的读者对象是普通开发者和系统开发者.

=== 3 The kbuild files

=== 3 内核编译文件


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.

内核中大多数makefile文件是使用kbuild基础架构的makefile文件.本章介绍 kbuildmakefile中的语法.

Kbuild文件倾向于"Makefile"这个名字,但使用"Kbuild"也可以.如果"Makefile"和"Kbuild"同时出现的话,则使用"Kbuild"文件.

Section 3.1 "Goal definitions" is a quick intro, further chapters provide more details, with real examples.
3.1
目标定义是一个快速导引,后面各章有详细介绍和实例.

--- 3.1 Goal definitions
--- 3.1
目标定义
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.

目标定义是makefile文件的主要部分(核心).这些目标定义行定义了如何编译文件,特殊的兼容选项和递归子目录.
The most simple kbuild makefile contains one line:

最简单的makefile文件只包含一行:

例如: 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:

这行告诉kbuild在该目录下名为foo.o的目标文件(object),foo.o通过编译foo.c或者foo.S而得到.如果foo.o编译成一个模块,则使用obj-m变量,因此常见写法如下:

例如: 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.

$(CONFIG_FOO)可以代表y(built-in对象)m(module对象).

如果CONFIG_FOO不是ym,那么这个文件不会被编译和链接.
--- 3.2 Built-in object goals - obj-y

--- 3.2 内嵌对象 - obj-y
The kbuild Makefile specifies object files for vmlinux in the $(obj-y) lists. These lists depend on the kernel configuration.

Kbuild Makefile规定所有编译进vmlinux的目标文件都在$(obj-y)列表中,这些列表依赖于内核配置.
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.

Kbuild编译所有的$(obj-y)文件,然后调用"$(LD) -r"合并这些文件到一个built-in.o文件中. built-in.o之后通过父makefile文件链接到vmlinux. $(obj-y)中的文件顺序很重要.列表中文件允许重复,文件第一次出现将被链接到built-in.o,后续出现该文件将被忽略.

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
链接顺序之所以重要是因为某些函数在内核引导时将按照他们出现的顺序被调用,如函数(module_init() / __initcall).所以请记住改变链接顺序的同时也可能会改变SCSI控制器的检测次序,从而导致磁盘重新编号.

例如: #drivers/isdn/i4l/Makefile

# 内核ISDN子系统和设备驱动程序Makefile

# 每个配置项都会使能一个文件列表
        obj-$(CONFIG_ISDN)         += isdn.o
        obj-$(CONFIG_ISDN_PPP_BSDCOMP) += isdn_bsdcomp.o

--- 3.3 Loadable module goals - obj-m

--- 3.3 可加载模块 - obj-m
$(obj-m) specify object files which are built as loadable kernel modules.

$(obj-m)指定了那些能被编译为可加载的内核模块的目标文件.

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).

一个模块可以从一个源文件或几个源文件编译而成.在一个源文件的情况下, kbuild makefile只需简单地它加到$(obj-m).
例如
:#drivers/isdn/i4l/Makefile
         obj-$(CONFIG_ISDN_PPP_BSDCOMP) += isdn_bsdcomp.o

Note: In this example $(CONFIG_ISDN_PPP_BSDCOMP) evaluates to 'm'

注意:在这个例子中$(CONFIG_ISDN_PPP_BSDCOMP)含义是'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.
如果内核模块是通过几个源文件编译而成的,您可以使用和上面同样的方法指定您想要编译的模块.然而此时Kbuild需要知道编译模块时是基于那些目标文件的,因此您需要设置一个$(<module_name>-objs)变量来告诉编译器.
例如
:#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-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.

在这个例子中,模块名isdn.o. Kbuild首先编译$(isdn-objs)中的object文件,然后运行"$(LD) -r"将列表中文件生成isdn.o.
由于Kbuild能够识别$(<module_name>-y)的复合文件,因此您可以使用CONFIG_符号值来有选择加入一些目标文件作为一个符合对象的一部分
.
例如
: #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'.

在这个例子中,如果$(CONFIG_EXT2_FS_XATTR)表示'y',xattr.o xattr_user.oxattr_trusted.o都将是复合对象ext2.o的一部分.
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.

注意: 当然,当你将编译目标文件到内核时,以上语法同样有效.因此,如果CONFIG_EXT2_FS=y,Kbuild将建立一个ext2.o来输出各个部分,然后将其链接到 built-in.o,正如您期望的那样.
--- 3.4 Objects which export symbols

--- 3.4 导出符号
No special notation is required in the makefiles for modules exporting symbols.         

makefile文件中的模块导出符号不需要特别的标记.
--- 3.5 Library file goals - lib-y

--- 3.5 库文件 - 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.

对于指定的目录, obj-*列表中的object文件编译成模块或复合进built-in.o. 也有可能指定这些目标文件到编译到库文件中--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.

所有罗列在lib-y中的object文件都将编译到该目录下的一个单一的库文件中.
包含在0bj-y中的object文件如果也列举在lib-y中将不会包含到库文件中,因为他们不能被访问.lib-m中的object文件将被编译进 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.

注意在相同的makefile中可以列举文件到buit-in内核中也可以作为库文件的一个组成部分.因此在同一个目录下既可以有built-in.o也可以有lib.a文件.
例如
: #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 "6.4 List directories to visit when descending". Use of lib-y is normally restricted to lib/ and arch/*/lib.

这样将基于delay.o创建一个lib.a文件.为了让Kbuild意识到有一个lib.a被创建,其所在的目录要加入到libs-y.

参看”6.4递归向下访问的目录列表”.lib-y通常被限制使用在lib/arch/*/lib目录中.
--- 3.6 Descending down in directories

--- 3.6 目录递归
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.

makefile文件负责编译当前目录下的目标文件,子目录中的文件由子目录中的makefile文件负责编译.编译系统将使用obj-yobj-m动递归编译各个子目录中文件.
如果ext2是一个子目录,fs目录下的makefile将使用以下赋值语句是编译系统编译ext2子目录
.
    
例如
: #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.

如果将CONFIG_EXT2_FS设置成'y(built-in)'m'(modular),则对应的obj-变量也要设置,内核编译系统将进入 ext2目录编译文件.
内核编译系统只使用这些信息来决定是否需要编译这个目录,子目录中makefile文件规定了哪些文件编译为模块,哪些是内核内嵌对象
.
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'.

当指定目录名时使用CONFIG_变量是一种比较好的做法.如果CONFIG_选项不为'y''m',内核编译系统就会跳过这个目录.
--- 3.7 Compilation flags

--- 3.7 编译标记
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, asflags-y and ldflags-y这三个标记只是用于定义它们的makefile.在递归构建时它们被用在所有的正规cc/as/ld指令调用中.

Note: Flags with the same behaviour were previously named:

EXTRA_CFLAGS, EXTRA_AFLAGS and EXTRA_LDFLAGS.

They are still supported but their usage is deprecated.

ccflags-y specifies options for compiling with $(CC). 

注意:之前的名为EXTRA_CFLAGS, EXTRA_AFLAGS, EXTRA_LDFLAGS这些标记都具有相同的行为它们的用法已经过时了,但是内核仍然支持它们.
ccflags-y
指定了使用$(CC)编译时的选项
.

例如:# drivers/acpi/Makefile

ccflags-y := -Os

         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.

这个变量是必须的,因为顶层makefile定义了$(KBUILD_CFLAGS)变量并使用该变量编译整个代码树.

asflags-y specifies options for assembling with $(AS).

ccflags-y指定了使用$(AS)汇编时的选项.

例如:#arch/sparc/kernel/Makefile

asflags-y := -ansi

ldflags-y specifies options for linking with $(LD).

ccflags-y指定了使用$(LD)链接时的选项.

例如: #arch/cris/boot/compressed/Makefile

ldflags-y += -T $(srctree)/$(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.

subdir-ccflags-y, subdir-asflags-y这两个标记和ccflags-y, asflags-y很相似.不同的是subdir-变量对于有它们出现的kbuild文件和所有的子目录都会有影响.使用subdir-*指定的选项将在使用non-subdir变量指定的选项之前被添加到命令行.

例如:

subdir-ccflags-y := -Werror

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

       CFLAGS_$@, AFLAGS_$@

CFLAGS_$@ and AFLAGS_$@ only apply to commands in current kbuild makefile.

CFLAGS_$@AFLAGS_$@只使用到当前makefile文件的命令中.

$(CFLAGS_$@) specifies per-file options for $(CC). The $@ part has a literal value which specifies the file that it is for.

$(CFLAGS_$@)指定了每个使用$(CC)文件的选项.$@部分有一个文本值,这个值指定了具体操作的文件.
例如
: # drivers/scsi/Makefile

CFLAGS_aha152x.o =   -DAHA152X_STAT -DAUTOCONF

         CFLAGS_gdth.o   = # -DDEBUG_GDTH=2 -D__SERIAL__ -D__COM2__ \

                                 -DGDTH_STATISTICS
These two lines specify compilation flags for aha152x.o and gdth.o.

这两行定义了aha152x.ogdth.o文件的编译选项.

$(AFLAGS_$@) is a similar feature for source files in assembly languages.
$(AFLAGS_$@)
使用在汇编文件中,具有类似的功能.
例如
: # arch/arm/kernel/Makefile

         AFLAGS_head.o       := -DTEXT_OFFSET=$(TEXT_OFFSET)

         AFLAGS_crunch-bits.o    := -Wa,-mcpu=ep9312

         AFLAGS_iwmmxt.o      := -Wa,-mcpu=iwmmxt
--- 3.8 Command line dependency

--- 3.8 命令依赖

--- 3.9 Dependency tracking

--- 3.9 依赖关系
Kbuild tracks dependencies on the following:

Kbuild记录如下依赖关系:

1) All prerequisite files (both *.c and *.h)
1)
所有的前提文件(both *.c and *.h)

2) CONFIG_ options used in all prerequisite files
2) CONFIG_
选项影响到的所有文件

3) Command-line used to compile target
3)
编译目标文件使用的命令行

Thus, if you change an option to $(CC) all affected files will be re-compiled.
因此,假如改变$(CC)的一个选项,所有相关的文件都要重新编译.
--- 3.10 Special Rules

--- 3.10 特殊规则
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 are the architecture-specific Makefiles which need special rules to prepare boot images etc. Special rules are written as normal Make rules.     

kbuild规则不能提供编译所需的支持时就需要使用一些特殊规则了.一个典型的例子就是在编译期间自动生成头文件.

其他例子有比如特定体系架构的makefile需要特殊规则来制作引导映像.特殊规则写法同普通的Make规则.

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:

Makefile所在的目录中,Kbuild不能执行,因此所有的特殊规则需要提供必备文件和目标文件的相对路径.定义特殊规则时将使用到两个变量:

$(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.

$(src)指定Makefile文件所在的相对路径,当使用代码树中的文件时使用该变量$(src).

$(obj)

$(obj) is a relative path which points to the directory where the target is saved. Always use $(obj) when referring to generated files.

$(obj)指定保存目标文件的相对路径.生成文件使用$(obj)变量.

例如: #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).    

这就特殊规则,其语法规则和make要求的普通语法一样.目标文件依赖于两个必备文件.引用目标文件的前缀是$(obj), 引用必备文件的前缀是$(src)(因为它们不是生成文件).

$(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.

在规则中打印提示信息给用户通常是一个很好的做法,但是当执行”make -s”的时候人们将看不到任何信息,除了错误和警告信息之外.

To support this kbuild define $(kecho) which will echo out the text following $(kecho) to stdout except if "make -s" is used.

为了支持该功能(打印提示信息),kbuild定义了$(kecho)来打印如下的文本信息,除非”make -s”被使用.

例如:#arch/blackfin/boot/Makefile

         $(obj)/vmImage: $(obj)/vmlinux.gz

                   $(call if_changed,uimage)

                   @$(kecho) 'Kernel: $@ is ready'

--- 3.11 $(CC) support functions

--- 3.11 $(CC) 支持的函数

The kernel may be built 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 usually the gcc compiler, but other alternatives are available.

内核可能由一些不同版本的$(CC)编译,每个版本的编译器都支持一些的功能与选项.Kbuild提供了一些基本支持,可以来检查 $(CC) 的选项是否有效.$(CC)一般情况下是gcc编译器,但也可以使用其它编译器来代替gcc.

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.

as-option该函数使用在当使用$(CC)来编译汇编文件(*.S),用来检查$(CC)是否支持特定选项.如果第一个选项不支持的话,则可以指定一个选项(第二个选项将被使用).

例如:#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.

在上面的例子中,如果$(CC)支持选项-Wa$(comma)-isa=$(isa-y),cflags-y标记选项列表中就会加上该值.第二个参数是可选的,当第一个参数不支持时,就会使用该值.

cc-ldoption

cc-ldoption is used to check if $(CC) when used to link object files supports the given option. An optional second option may be specified if first option are not supported.

cc-ldoption函数用来检查当联接目标文件时使用的$(CC)是否支持特定选项.如果第一个选项不支持的话,则可以指定一个选项(第二个选项将被使用).
例如
:#arch/x86/kernel/Makefile

         vsyscall-flags += $(call cc-ldoption, -Wl$(comma)--hash-style=sysv)

In the above example, vsyscall-flags will be assigned the option -Wl$(comma)--hash-style=sysv if it is supported by $(CC).The second argument is optional, and if supplied will be used if first argument is not supported.

在上面的例子中,如果$(CC)支持选项-Wl$(comma)--hash-style=sysv, vsyscall-flags标记选项列表中就会加上该值.第二个参数是可选的,当第一个参数不支持时,就会使用该值.

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

as-instr函数用来检测在测试指令中汇编器是否支持报告并输出C转义字符,无论是选项1还是选项2.

Note: as-instr-option uses KBUILD_AFLAGS for $(AS) options

注意: as-instr-option$(AS)选项中使用KBUILD_AFLAGS变量.

cc-option

cc-option is used to check if $(CC) supports a given option, and not supported to use an optional second option.

cc-option函数用来检查$(CC)是否支持特定选项,并且不支持使用可选的第二项.

例如:#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.

在上面的例子中,如果$(CC)支持选项-march=pentium-mmx,cc-option标记选项列表中就会加上该值,否则就使用-march=i586. cc-option的第二个参数是可选的,如果省略,当第一个选项不支持时cflags-y不会被赋值.

Note: cc-option uses KBUILD_CFLAGS for $(CC) options

注意:cc-option$(CC)选项中使用KBUILD_CFLAGS变量.

cc-option-yn

cc-option-yn is used to check if gcc supports a given option and return 'y' if supported, otherwise 'n'.

cc-option-yn函数用来检查gcc是否支持特定选项,如果支持则返回'y',否则为'n'.

例如:#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)支持-m32选项时,$(biarch)会被设置为y.$(biarch)y,扩展的$(aflags-y)$(cflags-y)变量就会分别被赋值为-a32-m32.

注意: cc-option-yn$(CC)选项中使用KBUILD_CFLAGS

cc-option-align

gcc versions >= 3.0 changed the type of options used to specify alignment of functions, loops etc. $(cc-option-align), when used as prefix to the align options, will select the right prefix:

大于3.0版本的gcc编译器,改变了对函数/循环中用于指定内存对齐的选项类型. $(cc-option-align)就作为对齐选项的前缀出现,当用到对齐选项时,$(cc-option-align)用来选择正确的前缀:

gcc < 3.00

         cc-option-align = -malign

gcc >= 3.00

cc-option-align = -falign

例如:KBUILD_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.

在上面的例子中,选项-falign-funcions=4被用在gcc >= 3.00的时候,对于小于3.00,使用 -malign-funcions=4.

Note: cc-option-align uses KBUILD_CFLAGS for $(CC) options

注意: cc-option-align$(CC)选项中使用KBUILD_CFLAGS

cc-disable-warning

cc-disable-warning checks if gcc 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.

cc-disable-warning函数检测gcc是否支持一个给定的警告并且返回命令行改观去禁用该选项.这个特殊的函数也是需要的,因为gcc4.4和之后更高的版本都接受任何未知的以-Wno*标识的选项,并且发出警告,如果在源文件中有其他警告的话.

例如: 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 gcc really accepts it.

在上面的例子中,只有在gcc真正接受unused-but-set-variable的时候, -Wno-unused-but-set-variable变量才被加入到KBUILD_CFLAGS编译列表中去.

cc-version

cc-version returns a numerical version of the $(CC) compiler version. The format is <major><minor> 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 -mregparm=3 was broken in some gcc versions even though the option was accepted by gcc.

cc-version以数学形式返回$(CC)编译器的版本号.其格式是:<major><minor>,二者都是数学.比如,gcc 3.41会返回0341.当某版本的$(CC)在某方面有缺陷时,cc-version就会很有用.比如,选项
-mregparm=3
虽然会被gcc接受,但其实现是有问题的
.

例如: #arch/x86/Makefile

         cflags-y += $(shell \

         if [ $(call cc-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.

在上面的例子中,-mregparm=3只会在gcc的版本大于等于3.0的时候使用.

cc-ifversion

cc-ifversion tests the version of $(CC) and equals last argument if version expression is true.

cc-ifversion测试$(CC)的版本号,如果版本表达式为真,就赋值为最后的参数.

例如:#fs/reiserfs/Makefile

         ccflags-y := $(call cc-ifversion, -lt, 0402, -O1)

In this example, ccflags-y will be assigned the value -O1 if the $(CC) version is less than 4.2. cc-ifversion takes all the shell operators:

-eq, -ne, -lt, -le, -gt, and –ge The third parameter may be a text as in this example, but it may also be an expanded variable or a macro.

在这个例子中,如果$(CC)的版本小于4.2, ccflags-y就被赋值-O1. cc-ifversion可使用所有的shell操作符:-eq,-ne,-lt,-le,-gt,-ge.第三个参数可以像上面例子一样是个文本,也可以是个扩展的变量或宏.

cc-fullversion

cc-fullversion is useful when the exact version of gcc is needed.One typical use-case is when a specific GCC version is broken. cc-fullversion points out a more specific version than cc-version does.

当需要精确的gcc版本时,cc-fullversion函数是很有用的.一个典型的例子是当一个特定的GCC版本不可用, cc-fullversion指定一个比cc-version更精确的版本.

例如:#arch/powerpc/Makefile

         $(Q)if test "$(call cc-fullversion)" = "040200" ; then \

                   echo -n '*** GCC-4.2.0 cannot compile the 64-bit powerpc ' ; \

                   false ; \

         fi

In this example for a specific GCC version the build will error out explaining to the user why it stops.

在这个使用特定版本GCC编译的时候会产生错误,并向用户解释了为何会停止.

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.

cc-cross-prefix函数用来检测指定目录中是否存在$(CC)使用前缀列表之一.若存在则返回第一个prefix$(CC)这样的前缀,否则什么也不返回.

Additional prefixes are separated by a single space in the call of cc-cross-prefix.

附加前缀通过在调用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.

这个函数是很有用的,在架构相关makefile中会试着设置CROSS_COMPILE为一个众所周知的值,但一般会有好几个值供选择.

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.

因此建议只有在交叉编译(主机和目标机不同的架构)的时候再去设置CROSS_COMPILE.如果CROSS_COMPILE已经被设置好了,那就保留它吧.

例如: #arch/m68k/Makefile

         ifneq ($(SUBARCH),$(ARCH))

ifeq ($(CROSS_COMPILE),)

CROSS_COMPILE := $(call cc-cross-prefix, m68k-linux-gnu-)

                   endif

         endif

--- 3.12 $(LD) support functions
--- 3.12 $(LD)
支持的函数

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).

ld-option函数是用来检查$(LD)是否支持提供的选项. ld-option函数有有两个选项作为参数.第二个参数是一个可选项,当第一个选项不被$(LD)支持时就使用它.

例如:#Makefile

         LDFLAGS_vmlinux += $(call really-ld-option, -X)

=== 4 Host Program support

=== 4 辅助程序


Kbuild supports building executables on the host for use during the compilation stage.Two steps are required in order to use a host executable.

内核编译系统支持在编译(compliation)阶段编译主机可执行程序.为了使用主机程序需要两个步骤.

The first step is to tell kbuild that a host program exists. This is done utilising the variable hostprogs-y.

第一个步骤使用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).

第二步给主机程序添加潜在的依赖关系.有两种方法可以做到,在规则中增加依赖关系,或使用$(always)变量.

Both possibilities are described in the following.   

具体描述如下.

--- 4.1 Simple Host Program
--- 4.1
简单辅助程序
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.    

在某些情况下,当编译正在运行时,需要在主机上编译和运行主机程序.下面这行告诉kbuild应该在主机上建立bin2hex程序.

例如: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.
上例中,Kbuild假定bin2hex程序是使用makefile相同目录下的单一C代码文件bin2hex.c编译出来的.
--- 4.2 Composite Host Programs

--- 4.2 组合辅助程序
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.    

主机程序也可以由多个object文件组成.定义组合辅助程序的语法同内核对象的定义方法.

$(<executeable>-objs)包含了所有的用于链接最终可执行程序的对象.

例如: #scripts/lxdialog/Makefile
        hostprogs-y   := lxdialog 
        lxdialog-objs := checklist.o lxdialog.o

Objects with extension .o are compiled from the corresponding .cfiles. 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.

扩展名.o的目标文件都是编译自对应的.c文件得来的.在上面的例子中checklist.c编译成checklist.o,lxdialog.c编译为 lxdialog.o.最后两个.o文件链接成可执行文件lxdialog.

注意:语法<executable>-y不能用于定义主机程序.
--- 4.3 Defining shared libraries

--- 4.3 定义共享库

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.

扩展名为.so的对象是共享库文件,这是位置无关的object文件.Kbuild对共享库提供支持,但使用方法有限制.在下面例子中 libkconfig.so库文件被链接到可执行文件conf.

例如: #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.

共享库文件需要对应的-objs定义,在上面例子中库libkconfig由两个对象组成:expr.otype.o. expr.otype.o将被编译为位置无关代码并被链接为共享库 libkconfig.so. 共享库不支持C++语言.

--- 4.4 Using C++ for host programs
--- 4.4 C++
语言编写的辅助程序使用方法
kbuild offers support for host programs written in C++. This was introduced solely to support kconfig, and is not recommended for general use. 

Kbuild提供了对C++主机程序的支持以用于内核配置,该功能被引入主要是来为了支持kconfig,因此一般不建议使用.

例如: #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.

在上面例子中可执行文件由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

--- 4.5 辅助程序编译控制选项
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.    

当编译主机程序的时候,仍可以设置特定的标志.程序始终会使用$(HOSTCC)变量,该变量中的选项是从$(HOSTCFLAGS)变量传来的.设置这些选项将影响所有使用了变量$(HOSTCFLAGS)makefile创建的主机程序.

例如: #scripts/lxdialog/Makefile

HOST_EXTRACFLAGS += -I/usr/include/ncurses
To set specific flags for a single file the following construction is used:

为单个文件设置选项使用下面方式:

例如: #arch/ppc64/boot/Makefile

HOSTCFLAGS_piggyback.o := -DKERNELBASE=$(KERNELBASE)

It is also possible to specify additional options to the linker.

也可以使用附加链接选项:

例如: #scripts/kconfig/Makefile

HOSTLOADLIBES_qconf := -L$(QTDIR)/lib

When linking qconf, it will be passed the extra option "-L$(QTDIR)/lib".

当链接qconf时将使用外部选项"-L$(QTDIR)/lib".
--- 4.6 When host programs are actually built

--- 4.6 何时建立辅助程序
Kbuild will only build host-programs when they are referenced as a prerequisite. This is possible in two ways:

只有当该辅助程序作为一个先决条件(必备文件)被引用时,Kbuild才会去编译它.有两种方式:

(1) List the prerequisite explicitly in a special rule. 

(1) 在特殊规则中作为隐式的前提需求

例如: #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). 

编译目标文件$(obj)/devlist.h需要先建立$(obj)/gen-devlist.注意在特殊规则中使用主机程序必须加前缀$(obj).

(2) Use $(always)

(2) 使用$(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.

当没有合适的特殊规则可以使用,并且在进入makefile文件时就要建立主机程序,可以使用变量$(always).

例如: #scripts/lxdialog/Makefile

hostprogs-y   := lxdialog

always     := $(hostprogs-y)

This will tell kbuild to build lxdialog even if not referenced in any rule.

这样就告诉内核编译系统即使没有任何规则使用lxdialog也要编译它.
--- 4.7 Using hostprogs-$(CONFIG_FOO)

--- 4.7 使用hostprogs-$(CONFIG_FOO)

A typical pattern in a Kbuild file looks like this:

Kbuild文件中典型模式如下:

例如: #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 handles hostprogs-m exactly like hostprogs-y. But only hostprogs-y is recommended to be used when no CONFIG symbols are involved.

Kbuild来说'y'用于内嵌对象'm'用于模块.因此如果config符号是'm',编译系统也将创建该程序.换句话说内核编译系统等同看待hostprogs-mhostprogs-y.但如果不涉及到CONFIG符号仅建议使用hostprogs-y.

=== 5 Kbuild clean infrastructure

=== 5 编译清除机制


"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-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).

"make clean"命令删除在编译内核生成的大部分文件,例如主机程序.列举在$(hostprogs-y)$(hostprogs-m)$(always)$(extra-y)$(targets)中目标文件都将被删除.代码目录数中的"*.[oas]""*.ko"文件和一些由编译系统产生的附加文件也将被删除.

附加文件可以使用$(clean-files)进行定义.

例如: #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 '/').

当执行"make clean"命令时, "devlist.h classlist.h"两个文件将被删除.内核编译系统默认这些文件与makefile具有相同的相对路径,否则需要设置以'/'开头的绝对路径.

To delete a directory hierarchy use:

删除整个目录使用以下方式:

例如: #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 '/').

To exclude certain files from make clean, use the $(no-clean-files) variable. This is only a special case used in the top level Kbuild file:

这样就将删除包括子目录在内的整个debian目录.如果没有指定以'/'开头的绝对路径,Kuild假定这里使用和Makefile相同的相对路径.

如果要使make clean的时候排除某些文件,则需使用$(no-clean-file)变量.这仅仅是在顶层Kbuild文件中的一种特殊情况:

例如:#Kbuild

no-clean-files := $(bounds-file) $(offsets-file)

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.

通常内核编译系统根据"obj-* := dir/"进入子目录,但有的时候,Kbuild架构还不足以描述和体系结构相关的makefile的情况时,就需要显式的指明所要访问的子目录:

例如: #arch/x86/boot/Makefile

subdir- := compressed/

The above assignment instructs kbuild to descend down in the directory compressed/ when "make clean" is executed.

上面赋值语句指示编译系统执行"make clean"命令时进入compressed/目录.

To support the clean infrastructure in the Makefiles that builds the final bootimage there is an optional target named archclean:

在编译最终的引导映像文件的makefile中有一个可选的目标对象名称是archclean.

例如: #arch/ x86/Makefile

archclean:

$(Q)$(MAKE) $(clean)=arch/ x86/boot

When "make clean" is executed, make will descend down in arch/x86/boot, and clean as usual. The Makefile located in arch/x86/boot/ may use the subdir- trick to descend further down.

当执行"make clean"时编译器进入arch/ x86/boot并象通常一样工作.arch/ x86/boot中的makefile文件可以使用subdir- 标识进入更下层的目录.

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.

注意1:arch/$(ARCH)/Makefile不能使用"subdir-",因为它被包含在顶层makefile文件中,在这个位置编译机制是不起作用的.

Note 2: All directories listed in core-y, libs-y, drivers-y and net-y will be visited during "make clean".

注意2:所有列举在core-ylibs-ydrivers-ynet-y中的目录将被"make clean"命令清除.

=== 6 Architecture Makefiles

=== 6 架构Makefile文件


The top level Makefile sets up the environment and does the preparation, before starting to descend down in the individual directories.

在开始进入各个目录编译之前,顶层makefile文件设置编译环境和做些准备工作.

The top level makefile contains the generic part, whereas arch/$(ARCH)/Makefile contains what is required to set up kbuild for said architecture.

To do so, arch/$(ARCH)/Makefile sets up a number of variables and defines a few targets.

顶层makefile文件包含通用的部分,然而arch/$(ARCH) /Makefile包含该体系架构所需的设置.要做到这一点,arch/$(ARCH)/Makefile会设置一些变量和少量的目标.

When kbuild executes, the following steps are followed (roughly):

当编译时将按照以下大概步骤执行:

1) Configuration of the kernel => produce .config

1) 配置内核 => 产生.config文件 

2) Store kernel version in include/linux/version.h

2) 保存内核版本到include/linux/version.h文件中 

3) Symlink include/asm to include/asm-$(ARCH)

3) 符号链接include/asm到include/asm-$(ARCH)

4) Updating all other prerequisites to the target prepare:

4) 更新所有目标对象的其它前提文件

- Additional prerequisites are specified in arch/$(ARCH)/Makefile

- 附加前提文件定义在arch/$(ARCH)/Makefile文件中 

5) Recursively descend down in all directories listed in init-* core* drivers-* net-* libs-* and build all targets.
5)
递归进入init-* core* drivers-* net-* libs-*中的所有子目录并编译所有的目标对象

- The values of the above variables are expanded in arch/$(ARCH)/Makefile.

- 上述变量都可以在arch/$(ARCH)/Makefile文件中扩展.

6) 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 head-y, assigned by arch/$(ARCH)/Makefile.

6) 链接所有的object文件生成vmlinux文件,在代码树根目录下.最先链接的几个object文件是在arch/$(ARCH)/Makefile文件的head-y变量中指定的.

7) Finally, the architecture-specific part does any required post processing and builds the final bootimage.

7) 最后,特定体系相关的部分做一些必要的处理并建立最终的引导映像bootimage.

- This includes building boot records

- 包括创建引导指令

- Preparing initrd images and the like

- 准备initrd镜像和类似文件

--- 6.1 Set variables to tweak the build to the architecture
--- 6.1
设置变量调整构建的体系结构

LDFLAGS                        Generic $(LD) options

LDFLAGS      $(LD)一般选项

Flags used for all invocations of the linker. Often specifying the emulation is sufficient.

该选项在每次调用联接器时都会用到.一般情况下,只用来指明模拟器.

例如: #arch/s390/Makefile

LDFLAGS   := -m elf_s390

Note: ldflags-y can be used to further customize the flags used. See chapter 3.7.

注意: LDFLAGS-y可以进一步订制所使用选项,参考第3.7.

LDFLAGS_MODULE   Options for $(LD) when linking modules

LDFLAGS_MODULE       $(LD)链接模块的选项

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_MODULE用于在使用$(LD)链接.ko文件为模块的时候设置选项.默认为"-r",指定输出文件是可重定位的.

LDFLAGS_vmlinux       Options for $(LD) when linking vmlinux

LDFLAGS_vmlinux   $(LD)链接vmlinux选项

LDFLAGS_vmlinux is used to specify additional flags to pass to the linker when linking the final vmlinux image.

LDFLAGS_vmlinux用于在链接最终vmlinux镜像时给链接器指定一些附加选项.

LDFLAGS_vmlinux uses the LDFLAGS_$@ support.

LDFLAGS_vmlinux支持使用LDFLAGS_$@.

例如: #arch/ x86/Makefile

LDFLAGS_vmlinux := -e stext

OBJCOPYFLAGS           objcopy flags

OBJCOPYFLAGS      objcopy选项

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.

当使用$(call if_changed,objcopy)转化a .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)

In this example, the binary $(obj)/image is a binary version of vmlinux. The usage of $(call if_changed,xxx) will be described later.

在该例中, $(obj)/imagevmlinux的二进制版本文件.$(call if_changed,xxx)的使用方法见后.

KBUILD_AFLAGS                       $(AS) assembler flags

KBUILD_AFLAGS      $(AS)汇编选项

Default value - see top level Makefile

默认值见顶层Makefile文件

Append or modify as required per architecture.

针对每个体系需要另外添加和修改它.

例如: #arch/sparc64/Makefile

KBUILD_AFLAGS += -m64 -mcpu=ultrasparc
KBUILD_CFLAGS                        $(CC) compiler flags

KBUILD_CFLAGS      $(CC)编译器选项

Default value - see top level Makefile

默认值见顶层Makefile文件

Append or modify as required per architecture.

针对每个体系需要另外添加和修改它.

Often, the KBUILD_CFLAGS variable depends on the configuration.

通常KBUILD_CFLAGS变量值取决于内核配置.

例如: #arch/ x86/Makefile

cflags-$(CONFIG_M386) += -march=i386

CFLAGS += $(cflags-y)

Many arch Makefiles dynamically run the target C compiler to probe supported options:

许多体系Makefiles文件动态运行目标C编译器来检测其支持的选项:

#arch/ x86/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 example utilises the trick that a config option expands to 'y' when selected.

第一个例子使用了一个配置选项,config配置该选项为'y'时将被选中.

KBUILD_AFLAGS_KERNEL      $(AS) options specific for built-in

KBUILD_AFLAGS_KERNEL      编译built-in对象时,$(AS)使用的选项

$(KBUILD_AFLAGS_KERNEL) contains extra C compiler flags used to compile resident kernel code.

$( KBUILD_AFLAGS_KERNEL)包含编译常驻内核代码使用的外部C编译器选项.

KBUILD_AFLAGS_MODULE   Options for $(AS) when building modules

KBUILD_AFLAGS_MODULE     编译模块时, $(AS)使用的选项

$(KBUILD_AFLAGS_MODULE) is used to add arch specific options that are used for $(AS).

$( KBUILD_AFLAGS_MODULE)用于为$(AS)添加一些特定的选项.

From commandline AFLAGS_MODULE shall be used (see kbuild.txt).

可以查看命令行AFLAGS_MODULE用法(kbuild.txt)

KBUILD_CFLAGS_KERNEL      $(CC) options specific for built-in

KBUILD_CFLAGS_KERNEL        编译built-in对象时,$(CC)使用的选项

$(KBUILD_CFLAGS_KERNEL) contains extra C compiler flags used to compile resident kernel code.

$( KBUILD_CFLAGS_KERNEL)包含编译常驻内核代码使用的外部C编译器选项.

KBUILD_CFLAGS_MODULE   Options for $(CC) when building modules

KBUILD_CFLAGS_MODULE     编译模块时, $(CC)使用的选项

$(KBUILD_CFLAGS_MODULE) is used to add arch specific options that are used for $(CC).

$( KBUILD_CFLAGS_MODULE)用于为$(CC)添加一些特定的选项.

From commandline CFLAGS_MODULE shall be used (see kbuild.txt).

可以查看命令行CFLAGS_MODULE用法(kbuild.txt)

KBUILD_LDFLAGS_MODULE   Options for $(LD) when linking modules

KBUILD_LDFLAGS_MODULE   链接模块时,$(LD)所使用的选项

$(KBUILD_LDFLAGS_MODULE) is used to add arch specific options used when linking modules. This is often a linker script.

$( KBUILD_LDFLAGS_MODULE)用于在链接模块时添加一些特定的选项.这也是一个链接脚本.

From commandline LDFLAGS_MODULE shall be used (see kbuild.txt).

可以查看命令行LDFLAGS_MODULE用法(kbuild.txt)

KBUILD_ARFLAGS   Options for $(AR) when creating archives

KBUILD_ARFLAGS    创建压缩文件时,$(AR)所使用的选项

$(KBUILD_ARFLAGS) set by the top level Makefile to "D" (deterministic mode) if this option is supported by $(AR).

$( KBUILD_ARFLAGS)由顶层Makefile设置为”D”(确定模式),如果$(AR)支持该选项的话.

--- 6.2 Add prerequisites to archheaders
--- 6.2
增加预设置项到archheaders
The archheaders: rule is used to generate header files that may be installed into user space by "make header_install" or "make headers_install_all".  In order to support "make headers_install_all", this target has to be able to run on an unconfigured tree, or a tree configured for another architecture.

archheaders:这是用于生成头文件的规则,这些头文件可以通过”make header_install”或者”make headers_install_all”安装到用户空间.为了支持”make headers_install_all”,该目标必须能够在未配置或者被配置为其他体系结构的树上运行.

It is run before "make archprepare" when run on the architecture itself.

这些命令(指生成头文件)会在”make archprepare”之前在本地架构上就运行.

--- 6.3 Add prerequisites to archprepare

--- 6.3增加预设置项到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.

archprepare:这个规则用于列举开始进入子目录前编译时需要的前提文件.通常用在包含汇编常量的头文件.

例如: #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 describe how kbuild supports generating offset header files.

在这个例子中,目标文件maketools将在进入子目录前被处理.详见XXX-TODO章描述了kbuild如何支持生成offset头文件.
--- 6.4 List directories to visit when descending

--- 6.4 递归向下访问的目录列表

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.

体系makefile文件配合顶层makefile文件共同定义了一些变量用于指定如何建立vmlinux文件.注意架构makefile是不会定义和模块相关的内容的;所有构建模块的机制都是体系无关的.

         head-y, init-y, core-y, libs-y, drivers-y, net-y

$(head-y) lists objects to be linked first in vmlinux.

$(head-y) 列出了最先链接到vmlinux的目标文件.

$(libs-y) lists directories where a lib.a archive can be located.

$(libs-y) 列出了所有lib.a所在的目录.

The rest list directories where a built-in.o object file can be located.

其余的变量列出了build-in.o文件所在的目录.

$(init-y) objects will be located after $(head-y).

$(init-y) 列举的对象位于$(head-y)对象之后.

Then the rest follows in this order:

$(core-y), $(libs-y), $(drivers-y) and $(net-y).

然后剩下的按照如下顺序:

$(core-y), $(libs-y), $(drivers-y) $(net-y).
The top level Makefile defines values for all generic directories, and arch/$(ARCH)/Makefile only adds architecture-specific directories.

顶层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.5 Architecture-specific boot images

--- 6.5 具体架构的引导映像

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.

体系makefile文件的目标就是,生成并压缩vmlinux文件,然后把它打包成引导启动代码,并复制到合适的位置.这包括各种安装命令.如何定义实际的目标对象是无法在各个体系结构间进行标准化的.

It is common to locate any additional processing in a boot/ directory below arch/$(ARCH)/.

一般的,附加处理过程常位于arch/$(ARCH)/下的boot/目录.

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/.

Kbuild并没有为构建boot/目录下的目标提供更好的方法.因此arch/$(ARCH)/Makefile需要调用make命令手动在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.

推荐使用的方法是在arch/$(ARCH)/Makefile包含快捷方式,然后在调用arch/$(ARCH) /boot/Makefile中使用完整路径.
例如
: #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.

建议使用"$(Q)$(MAKE) $(build)=<dir>"方式在子目录中调用make命令.

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.

没有专门用于命名特定体系结构目标文件的规则,但执行"make help"命令要列出所有目标系统文件,为支持该功能,因此必须定义$(archhelp)变量.

例如: #arch/x86/Makefile

         define archhelp

echo  '* bzImage      - Image (arch/$(ARCH)/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:.

当执行不带参数的make命令时,所遇到的第一个目标将被建立.在顶层makefile,第一个目标就是all:.

An architecture shall always, per default, build a bootable image. In "make help", the default goal is highlighted with a '*'.

默认情况下,每个体系结构都应该构造一个可引导映像."make help",默认的目标就是被高亮的”*”.

Add a new prerequisite to all: to select a default goal different from vmlinux.

增加新的前提文件给all,就可以构造一个不同于vmlinux的默认目标.

例如: #arch/x86/Makefile

         all: bzImage
When "make" is executed without arguments, bzImage will be built.

当执行不带参数的"make"命令时,bzImage文件将被构造.

--- 6.6 Building non-kbuild targets

--- 6.6 编译非内核目标

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:

extra-y指定了在当前目录下创建的没有在obj-*定义的附加的目标文件.extra-y中列举目标是处于两个目的:

1) Enable kbuild to check changes in command lines

1) 使kbuild可以检查命令行是否发生变化

- When $(call if_changed,xxx) is used

- 当使用$(call if_changed,xxx) 

2) kbuild knows what files to delete during "make clean"

2) kbuild知道执行"make clean"命令时删除哪些文件

例如:#arch/x86/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.

该例子中,extra-y中的对象文件将被编译,但不会被链接到built-in.o.

--- 6.7 Commands useful for building a boot image

--- 6.7 构建引导映像的命令

Kbuild provides a few macros that are useful when building a boot image.

Kbuild提供了一些宏,用于构建一个引导映像.

if_changed

if_changed is the infrastructure used for the following commands.

if_changed是后面命令使用的基础.

用法:

target: source(s) FORCE

$(call if_changed,ld/objcopy/gzip)

When the rule is evaluated, it is checked to see if any files need an update, or the command line has changed since the 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.

任何使用if_changed的目标对象都必须在$(targets)中列出来,否则命令行检查将失败,并且目标总是会被重建.
Assignments to $(targets) are without $(obj)/ prefix.

$(targets)的对象的赋值没有$(obj)/前缀.

if_changed may be used in conjunction with custom commands as defined in 6.8 "Custom kbuild commands".    

if_changed也可以和定制命令配合使用,6.8"自定义内核编译命令".

Note: It is a typical mistake to forget the FORCE prerequisite.

注意: 忘记了FORCE前导词是一个常见的错误.

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, ld/objcopy/gzip)

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

ld

Link target. Often, LDFLAGS_$@ is used to set specific options to ld.

链接目标.常使用LDFLAGS_$@来设置ld的选项.

objcopy

Copy binary. Uses OBJCOPYFLAGS usually specified in arch/$(ARCH)/Makefile. OBJCOPYFLAGS_$@ may be used to set additional options.

拷贝二进制文件.一般用于arch/$(ARCH)/Makefile,使用OBJCOPYFLAGS变量来指定.也可以用OBJCOPYFLAGS_$@来设置附加选项.

gzip

Compress target. Use maximum compression to compress target.

压缩目标文件.使用最大压缩算法压缩目标文件.

例如: #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.

该例子中有两个可能的目标对象,分别需要不同的链接选项.定义链接器的选项使用LDFLAGS_$@语法,每个潜在目标一个.

$(targets) are assigned all potential targets, by which kbuild knows the targets and will:

$(targets) 会匹配所有的潜在目标,因此kbuild就知道目标是哪些,并且还会:

1)        check for commandline changes

1) 检查命令行的改变

2) delete target during make clean

2) 执行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.

先决条件中的": %: %.o"部分是简写方法,使我们不必在列出setup.obootsect.o文件.

注意: 常犯错误是忘记"target :="语句,导致目标文件莫名其妙地被重新编译.

dtc

Create flattend 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().

创建适合于链接到vmlinux的平面设备树文件.设备树文件链接进vmlinux被放置在镜像的init段中.平台代码必须在调用unflatten_device_tree()之前将设备树文件拷贝到非未初始化内存.

To use this command, simply add *.dtb into obj-y or targets, or make some other target depend on %.dtb

要使用此命令,只需要简单的将*.dtb加入到obj-y或者targets目标中,或者构建一些其他的目标使之依赖于%.dtb

A central rule exists to create $(obj)/%.dtb from $(src)/%.dts; architecture Makefiles do no need to explicitly write out that rule.

$(src)/%.dts构建$(obj)/%.dtb存在一个重要的规则;架构相关Makefile不需要显式指定该规则.

例如:

         targets += $(dtb-y)

         clean-files += *.dtb

         DTC_FLAGS ?= -p 1024

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

dtc_cpp

This is just like dtc as describe above, except that the C pre-processor is invoked upon the .dtsp file before compiling the resultwith dtc.

除了在编译之前是经过.dtsp文件中调用的C预编译器之外,该命令规则和上文dtc所描述的一样.

In order for build dependencies to work, all files compiled using dtc_cpp must use the C pre-processor's #include functionality and not dtc's /include/ functionality.

为了让构建依赖能正常工作,所有使用dtc_cpp编译的文件都必须使用C预编译器的#include功能而不是dtc的那种/include/机制.

Using the C pre-processor allows use of #define to create named constants. In turn, the #defines will typically appear in a header file, which may be shared with regular C code. Since the dtc language represents a data structure rather than code in C syntax, similar restrictions are placed on a header file included by a device tree file as for a header file included by an assembly language file.

使用C预编译器支持使用#define来创建命名常量.反之,#define定义通常会出现在一个头文件中,可以和常规的C代码共享.由于dtc语言表示的是一个数据结构而不是C语法代码,类似的限制被放置在一个头文件中,该头文件被设备树包含,就像汇编语言文件包含头文件那样.

In particular, the C pre-processor is passed -x assembler-with-cpp, which sets macro __ASSEMBLY__. __DTS__ is also set. These allow header files to restrict their content to that compatible with device tree source.

特别是,C预编译器将被传递-x assembler-with-cpp,通过设置宏__ASSEMBLY__. __DTS__也设置了,这就支持了头文件通过限制其内容来和设备树相兼容.

A central rule exists to create $(obj)/%.dtb from $(src)/%.dtsp; architecture Makefiles do no need to explicitly write out that rule.

$(src)/%.dtsP构建$(obj)/%.dtb存在一个重要的规则;架构相关Makefile不需要显式指定该规则.

--- 6.8 Custom kbuild commands
--- 6.8
自定义内核编译命令

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_<command>        - what shall be echoed

cmd_<command>      - the command to execute

kbuild执行带KBUILD_VERBOSE=0参数的编译命令时,只会显示命令的简写.要启用自定义命令的该功能,就需要设置两个变量:

quiet_cmd_<command>          - 将被显示的内容 

cmd_<command>             - 被执行的命令

例如: #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/x86/boot/bzImage

will be displayed with "make KBUILD_VERBOSE=0".

执行"make KBUILD_VERBOSE=0"命令更新$(obj)/bzImage目标时将显示:

BUILD    arch/x86/boot/bzImage
--- 6.9 Preprocessing linker scripts

--- 6.9
预处理连接脚本

When the vmlinux image is built, the linker script arch/$(ARCH)/kernel/vmlinux.lds is used.

当构造vmlinux映像时,将使用arch/$(ARCH)/kernel/vmlinux.lds链接脚本.

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.
该脚本是同目录下的vmlinux.lds.S文件的预处理的变体. Kbuild认识.lds文件并包含*lds.S -> *lds的生成规则.

例如:#arch/x86/kernel/Makefile

always := vmlinux.lds

 

#Makefile

         export CPPFLAGS_vmlinux.lds += -P -C -U$(ARCH)

The assignment to $(always) is used to tell kbuild to build the target vmlinux.lds.

赋值给$(always)是用来告诉kbuild,去构造目标vmlinux.lds

The assignment to $(CPPFLAGS_vmlinux.lds) tells kbuild to use the specified options when building the target vmlinux.lds.

赋值给$( CPPFLAGS_vmlinux.lds)是用来告诉kbuild,使用指定的选项去构造构造目标vmlinux.lds

When building the *.lds target, kbuild uses the variables:

编译*.lds时将使用到下面这些变量:

KBUILD_CPPFLAGS     : Set in top-level Makefile

KBUILD_CPPFLAGS  : 定义在顶层Makefile

cppflags-y        : May be set in the kbuild makefile

cppflags-y         : 可以在kbuild makefile中设置

CPPFLAGS_$(@F)  : Target specific flags.

                                          Note that the full filename is used in this assignment.

CPPFLAGS_$(@F)     :目标编译选项

                  注意此处的赋值使用完整的文件名

The kbuild infrastructure for *lds file are used in several architecture-specific files.

针对*.lds文件的kbuild构架还被用在一些特定的体系结构的文件中.

--- 6.10 Generic header files

--- 6.10 通用头文件

The directory include/asm-generic contains the header files that may be shared between individual architectures.

Include/asm-generic目录下包含的头文件可以在各个架构之间共享.

The recommended approach how to use a generic header file is to list the file in the Kbuild file.

推荐的使用通用头文件的方法,是将其罗列在kbuild文件中.

See "7.4 generic-y" for further info on syntax etc.
关于语法等更多资料,参看”7.4 gerneric-y”
=== 7 Kbuild syntax for exported headers

=== 7 导出头文件的Kbuild语法


The kernel include 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__)

这些预先处理包括:

-去掉内核特定的注释

-去掉compiler.h头文件的包含

-去掉内核内的所有段(即使用ifdef __KERNEL__声明的部分)

Each relevant directory contains a file name "Kbuild" which specifies the headers to be exported.

每个相关的目录都包含一个名为”Kbuild”的文件,该文件指定了那些头文件要被导出.

See subsequent chapter for the syntax of the Kbuild file.

参见后续章节的Kbuild文件的语法.

--- 7.1 header-y

header-y specify header files to be exported.

head-y指定了要导出的头文件.

例如:#include/linux/Kbuild

         header-y += usb/

         header-y += aio_abi.h

The convention is to list one file per line and preferably in alphabetic order.

约定每一行列出一个文件,并最好是按字母顺序排列.

header-y also specify which subdirectories to visit. A subdirectory is identified by a trailing '/' which can be seen in the example above for the usb subdirectory. Subdirectories are visited before their parent directories.

header-y还可以指定要访问的子目录.子目录可以由末尾是”/”确定,可以看到,上文例子中使用了usb子目录.子目录会在其父目录之前就被访问.

--- 7.2 genhdr-y

genhdr-y specifies generated files to be exported.

genhdr-y指定生成的文件被导出.

Generated files are special as they need to be looked up in another directory when doing 'make O=...' builds.

生成文件比较特殊,因为当执行’make O=…’构建的它们的时候,需要查询另一个目录

例如:#include/linux/Kbuild

         genhdr-y += version.h

--- 7.3 destination-y

When an architecture have a set of exported headers that needs to be exported to a different directory destination-y is used.

当一个架构有一套头文件需要被导出到不同的目录去的时候,就需要用到destination-y.

destination-y specify the destination directory for all exported headers in the file where it is present.

destination-y指定所有的存在于文件中,被指定的要导出的头文件的目标目录

例如:#arch/xtensa/platforms/s6105/include/platform/Kbuild

         destination-y := include/linux

In the example above all exported headers in the Kbuild file will be located in the directory "include/linux" when exported.

在上例中,所有存在与Kbuild文件中的要导出的头文件,在导出时都将被定位到”include/linux”目录.

--- 7.4 generic-y

If an architecture uses a verbatim copy of a header from include/asm-generic then this is listed in the file arch/$(ARCH)/include/asm/Kbuild like this:

如果一个架构从include/asm-generic目录逐字拷贝头文件,那么在arch/$(ARCH)/include/asm/Kbuild文件中的列表应该像下面这样:

例如:#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/$(ARCH)/include/generated/asm

构建一个包的准备阶段,包括在arch/$(ARCH)/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

当一个头文件被导出时,导出到的那个架构,采用了和在usr/include/asm目录下导出的头文件集合的一部分类似的封装,来生成通用头文件.

The generated wrapper will in both cases look like the following:

生成的封装可能就是像下面这两种情况:

例如:termios.h

#include <asm-generic/termios.h>

=== 8 Kbuild Variables

=== 8 Kbuild变量


The top Makefile exports the following variables:

VERSION, PATCHLEVEL, SUBLEVEL, EXTRAVERSION

顶层Makefile文件导出下面这些变量:

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.

这几个变量定义了当前内核版本号.很少有架构相关的Makefiles文件直接使用这些变量;它们通常会使用$(KERNELRELEASE)来获取内核版本号.

$(VERSION), $(PATCHLEVEL), and $(SUBLEVEL) define the basic three-part version number, such as "2", "4", and "0".  These three

values are always numeric.

$(VERSION),$(PATCHLEVEL)$(SUBLEVEL)定义了三个基础版本号,例如"2", "4","0".这三个变量总是数字.

$(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.

$(EXTRAVERSION)为补丁定义了更细的版本号,通常是一些非数值字符串,例如"-pre4",但更多情况下是空白.

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.

$(KERNELRELEASE)是一个字符串,比如"2.4.0-pre4",适合于安装目录的命名,或者显示当前的版本号.有些架构Makefile就使用该变量来实现此目标.

ARCH

This variable defines the target architecture, such as "i386", "arm", or "sparc". Some kbuild Makefiles test $(ARCH) to       determine which files to compile.

这个变量定义了目标系统体系结构,例如"i386",”arm","sparc".一些kbuild Makefile检测$(ARCH)来确定哪些文件需要编译.

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 ...

默认情况下顶层Makefile文件把$(ARCH)设置为主机相同的体系结构.当交叉编译编译时,用户可以使用命令行传值来改变$(ARCH),比如:

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.

该变量为架构Makefile定义了安装内核镜像与System.map文件的目录.该变量主要用来指明特定架构的安装路径.

              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.

$(INSTALL_MOD_PATH)为了安装模块,给变量$(MODLIB)指定了前缀.这个变量不能在Makefile中定义,但是如果需要的话,可以由用户传值进来.

$(MODLIB) specifies the directory for module installation.

$(MODLIB)指定了模块安装的目录.

The top Makefile defines $(MODLIB) to $(INSTALL_MOD_PATH)/lib/modules/$(KERNELRELEASE). The user may override this value on the command line if desired.

顶层Makefile$(MODLIB)定义为$(INSTALL_MOD_PATH)/lib/modules/$(KERNELRELEASE).如果需要,用户可以使用命令行传值的方式将其覆盖.

INSTALL_MOD_STRIP

If this variable is specified, 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, INSTALL_MOD_STRIP value will be used as the option(s) to the strip command.

如果该变量被定义的话,将导致模块在安装之后就被去掉.如果INSTALL_MOD_STRIP’1’,那么默认的选项—strip-debug将被使用.否则, INSTALL_MOD_STRIP这个变量的值将作为strip命令的选项被使用.

=== 9 Makefile language

=== 9 Makefile语言


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.

内核的Makefile被设计成使用GNU Make.Makefile仅使用GNU Make已注明的功能,但也确实用到了很多GNU的扩展.

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程序支持基本的列处理功能.内核Makefiles文件使用了一种新颖的方式,描述了"if"语句的构建和处理过程.

GNU Make has two assignment operators, ":=" and "=".

GNU Make程序有两种赋值操作符,":=""=".

":=" 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.
当然有些时候使用"="是可以的.但是,通常使用":="才是正确选择.

=== 10 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>

=== 11 TODO


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>

完整文档下载地址:http://yunpan.cn/QiRy3manWUYIb  访问密码 b247

本文是冷烟花原创,转载请注明出处!

posted on 2014-05-14 16:57  冷烟花  阅读(7853)  评论(0编辑  收藏  举报