原英文文档的目录为:Documentation\kbuild\makefiles.txt

译者:陈梓归

Linux Kernel Makefiles

Linux内核的Makefiles

This document describes the Linux kernel Makefiles.
这个文档描述Linux内核的Makefiles

=== Table of Contents
=== 目录表

=== 1 Overview
=== 1 概述

=== 2 Who does what
=== 2 Makefiles不同角色的分工

=== 3 The kbuild files
=== 3 kbuild文件
  --- 3.1 Goal definitions
  --- 3.1 目标定义
  
  --- 3.2 Built-in object goals - obj-y
  --- 3.2 将目标编译进内核
  
  --- 3.3 Loadable module goals - obj-m
  --- 3.3 将目标编译成可加载模块
  
  --- 3.4 Objects which export symbols
  --- 3.4 导出目标符号
  
  --- 3.5 Library file goals - lib-y
  --- 3.5 库文件编译
  
  --- 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) 支持的函数
  
=== 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 Kbuild清除其下组织

=== 6 Architecture Makefiles
=== 6 具体架构的Makefiles
  --- 6.1 Set variables to tweak the build to the architecture
  --- 6.1 设置用来调整生成架构的变量
  
  --- 6.2 Add prerequisites to archprepare:
  --- 6.2 设置用来调整生成架构的变量
 
 --- 6.3 List directories to visit when descending
 --- 6.3 递归时列出需要访问的目录  
 
 --- 6.4 Architecture-specific boot images
 --- 6.4 与架构相关的启动映像
 
 --- 6.5 Building non-kbuild targets
 --- 6.5 建立非kbuild的目标
 
 --- 6.6 Commands useful for building a boot image
 --- 6.6 用来建立启动映像的命令
 
 --- 6.7 Custom kbuild commands
 --- 6.7 自定义kbuild命令
 
 --- 6.8 Preprocessing linker scripts
 --- 6.8 预处理链接脚本

=== 7 Kbuild Variables
=== 7 Kbuild变量

=== 8 Makefile language
=== 8 Makefile语言

=== 9 Credits
=== 9 贡献者

=== 10 TODO
    === 10 下一步的工作

=== 1 Overview
=== 1 概要

The Makefiles have five parts:
Makefiles包含下面5个部分:

Makefile the top Makefile.

#顶层Makefile文件.

.config the kernel configuration file.

#内核配置文件

arch/$(ARCH)/Makefilethe arch Makefile.

#内核配置文件

scripts/Makefile.*common rules etc. for all kbuild Makefiles.

#对于所有kbuild和Makefiles都有效的规则等

kbuild Makefilesthere are about 500 of these.

#大约有500个makefiles

The top Makefile reads the .config file, which comes from the kernel
configuration process.
顶层Makefiles读取内核配置程序生成的.config文件.

The top Makefile is responsible for building two major products: vmlinux
(the resident kernel image) and modules (any module files).
顶层Makefile用来生成两个主要的目标:vmlinux(内核映像)和模块(任何模块文件).

It builds these goals by recursively descending into the subdirectories of
the kernel source tree.
Makefile通过递归遍历内核树中的所有子目录来生成这些目标.

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包含一个名叫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.
每个子目录都有一个kbuild Makefile,这个Makefile承载着从上层Makefile传递下来的命令.
kbuild Makefile使用.config文件中的信息来生成文件列表,kbuild使用这个文件列表来决定生成需要加载入内核的目标或者模块.

scripts/Makefile.* contains all the definitions/rules etc. that
are used to build the kernel based on the kbuild makefiles.
scripts/Makefile.*包含了所有的定义、规则等等.
基于kbuild makefiles使用这些定义、规则可以构建内核.

=== 2 Who does what
=== 2 Makefiles对于不同角色的作用

People have four different relationships with the kernel Makefiles.
有四类不同的人会用到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).
*用户*是生成内核的人.
这类人通常使用“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.
*一般的开发者*是工作在内核外层的人,比如设备驱动,文件系统以及网络协议.
这些人需要去维护他们修改的子系统的kbuild Makefiles.
为了有效地去实现这些工作,他们通常取药一些关于内核makefile的整体知识,加上一些关于kuild公共接口的具体信息.

*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,同时也需要了解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.
*Kbuild开发者*这类人的工作对象是整个内核系统本身.他们需要知道内核Makefiles的方方面面.

This document is aimed towards normal developers and arch developers.
这个文档的适合读者是一般开发者和架构开发者.

=== 3 The kbuild files
=== 3 kbuild文件

Most Makefiles within the kernel are kbuild Makefiles that use the
kbuild infrastructure. This chapter introduces the syntax used in the
kbuild makefiles.
内核中的大多数Makefiles是使用kbuild基本语法规则的kbuild Makefiles.
这一章介绍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.
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.
目标定义是kbuildMakefile文件的主要部分(核心),它们定义了将要被构建的文件,任何具体的编译选项,
以及任何将要递归进入的子目录。

The most simple kbuild makefile contains one line:
最简单的kbuild makefile只包含一行:

Example:
例子:
obj-y += foo.o

This tells kbuild that there is one object in that directory, named
foo.o. foo.o will be built from foo.c or foo.S.
这一行告诉kbuild这个目录只有一个叫做foo.o的的目标.
foo.o将从foo.c或者foo.S生成.

If foo.o shall be built as a module, the variable obj-m is used.
Therefore the following pattern is often used:
如果foo.o将被生成为一个模块,那么就使用obj-m变量。因此下面的模版经常会被使用:

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.
$(CONFIG_FOO)等于y(编译进内核)或者m(编译为模块).
如果$(CONFIG_FOO)既不是y也不是m,那么这个文件就不会被编译也不会被链接.

--- 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.
KbuildMakefile在$(obj-y)列表中指定了编译进vmlinux的对象文件.
这个列表依靠内核配置文件生成.

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.
Kbuild编译所有的$(obj-y)文件。然后调用"$(LD)-r"将这些编译生成的文件合成到一个built-in.o文件中.
Built-in.o稍后会被父层Makfile链接到vmlinux中.

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.
$(obj-y)列表中文件的顺序是有意义的.
文件可以在$(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.
链接顺序也是有意义的。因为某些函数(比如(module_init() / __initcall))在系统启动的过程中将会按照它们出现的顺序调用.
所以记住改变链接顺序将会造成一些不确定情况。比如改变你的SCSI控制器的的被检测顺序,那么你的磁盘就会被重新编号.

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

Example:
例子:
#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.
如果一个内核模块由多个源文件编译而成,你需要像上面例子一样指定需要生成的模块。

Kbuild needs to know which the parts that you want to build your
module from, so you have to tell it by setting an
$(<module_name>-objs) variable.
Kbuild需要知道你要的模块是从哪些文件编译生成的,所以你必须通过设置$(<module_name>-objs)变量来让Kbuild知道.

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.
在这个例子中,模块的名字是isdn.o。Kbuild将会编译生成$(isdn-objs)变量中列出的目标文件.
然后运行"$(LD) -r"命令来链接列表中的文件从而生成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.
Kbuild通过后缀名-objs和-y来判断一个对象是否是一个复合对象.
这允许Makefiles使用CONFIG_标记的值来决定一个对象是否是复合对象的一部分.

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'.
在这个例子中,只有当$(CONFIG_EXT2_FS_XATTR)值等于’y’,xattr.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.
在makefiles中,模块不需要任何特殊的表示就可以导出符号.

--- 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-*为前缀列出的对象是指定目录中将要编译生成的模块或者编译进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开头列出的对象将会被包含到对应目录下的一个单独的库文件中.
在obj-y列表中的对象以及附加在lib-y列表中的对象将不会被包含到库文件中,因为它们可以以任何方式读取.
为了保持一致性,lib-m列表中的对象将被包含进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.
需要注意的是同一个kbuildmakefile 可能会列出编译进内核的文件以及包含进库中的文件.
因此同一个目录可能会包含一个built-in.o和一个lib.a文件.

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 built,
the directory shall be listed in libs-y.
See also "6.3 List directories to visit when descending".
这个例子将会基于checksum.o和delay.o生成一个库文件lib.a。只有将目录置于列      
表libs-y中,kbuild才会知道该目录下有一个lib.a要生成.
其它详情请看“6.3递归时列出需要访问的目录”.

Use of lib-y is normally restricted to lib/ and arch/*/lib.
一般只有lib/和arch/*/lib目录下可以使用lib-y.

--- 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.
一个Makefile文件只负责编译它所处目录的文件。子目录中的文件应该由子目录中的Makefile来进行维护.
编译系统会自动递归进入子目录,从而提供一种让编译系统知道子目录存在的机制.

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.
为了达到这个目的,将使用obj-y和obj-m.
ext2在一个单独的文件中,fs/目录中的Makefile只用如下的表达式来告诉kbuild来进入子目录.

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.
如果obj-中相应的CONFIG_EXT2_FS变量被设置成‘y’或者‘m’,那么kbuild将会进入到ext2目录中.
Kbuild只能利用这些信息来决定是否需要进入一个子目录.
子目录中的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’的时候,kbuild就能完全忽略该目录.

--- 3.7 Compilation flags
--- 3.7 编译标记

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_变量只能使用在定义该变量后的makefile文件中.
EXTRA_变量被makefile文件所有的执行命令语句所使用.

$(EXTRA_CFLAGS) specifies options for compiling C files with
$(CC).
$(EXTRA_CFLAGS)是使用$(CC)编译C文件的选项.

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.
定义这个变量是必须的,因为顶层makefile定义了$(CFLAGS)变量并使用该变量编译整个代码树.

$(EXTRA_AFLAGS) is a similar string for per-directory options
when compiling assembly language source.
$(EXTRA_AFLAGS)是每个目录编译汇编语言源文件的选项.

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).
$(EXTRA_LDFLAGS)和$(EXTRA_ARFLAGS)用于每个目录的$(LD)和$(AR)选项.

Example:
例子:
#arch/m68k/fpsp040/Makefile
EXTRA_LDFLAGS := -x

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)的每个文件的选项。$@部分代表该文件。

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
这三行定义了aha152x.o、gdth.o和seagate.o文件的编译选项.

$(AFLAGS_$@) is a similar feature for source files in assembly
languages.
$(AFLAGS_$@)使用在汇编语言代码文件中,具有同上相同的含义.

Example:
例子:
# arch/arm/kernel/Makefile
AFLAGS_head-armv.o := -DTEXTADDR=$(TEXTADDR) -traditional
AFLAGS_head-armo.o := -DTEXTADDR=$(TEXTADDR) -traditional

--- 3.9 Dependency tracking
--- 3.9 依赖性跟踪

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
Kbuild使用下面信息来跟踪依赖项:
    1) 所有的先决文件(both*.c and *.h)
    2) 在所有先决文件中使用的CONFIG_选项
    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.
当kbuild机制没有提供必要的支持时,特殊规则就起作用了.一个典型的例子是在生成过程中生成的头文件.
另一个例子是与具体架构相关的Makefiles需要特殊规则来准备启动映像.

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.
特殊规则的书写和正常的Make规则一样.
Kbuild不在Makefile所在的目录中执行,所以所有的特殊规则需要提供相对路径给先决文件和目标文件.

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.
$(src)
    $(src)是一个用来指向makfile所在目录的相对路径。必须使用$(src) 变量来引用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)是一个用来指向目标文件保存位置的相对目录.必须使用$(obj)变量来引用生成的文件.

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.
这是一个遵循正常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).
目标文件依赖于两个先决文件.
对目标文件的引用使用$(obj)作为前缀,而对先决文件的引用则使用$(src)(因为它们不是生成文件).

--- 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编译器,但是其它的编译器也是可以的.

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)文件 – 支持给定的选项.
当不支持第一个选项的时候,第二个可选选项可能会被指定.

Example:
例子:
#arch/sh/Makefile
cflags-y += $(call as-option,-Wa$(comma)-isa=$(isa-y),)

In the above example, cflags-y will be assigned the option
-Wa$(comma)-isa=$(isa-y) if it is supported by $(CC).
The second argument is optional, and if supplied will be used
if first argument is not supported.
在上面的例子中,当支持$(CC)的时候,cflags-y将等于选项-Wa$(comma)-isa=$(isa-y)的值.
第二个参数是可选的,当不支持第一个选项,并且第二个选项有给出的时候,它就会被使用.

ld-option
ld-option 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.
ld-option用来在链接目标文件时检查是否支持给定的选项.
当不支持第一个选项的时候,一个可选的第二选项可能会被支持.

Example:
例子:
#arch/i386/kernel/Makefile
vsyscall-flags += $(call ld-option, -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),那么vsyscall-flags就会被赋予-Wl$(comma)--hash-style=sysv选项的值.
第二个参数是可选的,当不支持第一个选项,并且第二个选项有给出的时候,它就会被使用.

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用来检查汇编器是否报告了一个特定的指令,然后输入选项1或者选项2.
C测试指令支持C转义.

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)是否支持一个给定的选项,而不是支持使用一个可选的第二选项.
 
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),那么cflags-y将会被赋予-march=pentium-mmx选项的值,否则就赋予-march=i586选项的值.
对于cc-option,第二个参数是可选的.
如果第二参数被省略了并且第一个选项不被支持,那么cflags-y将会被置为空.

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

Example:
例子:
#arch/ppc/Makefile
biarch := $(call cc-option-yn, -m32)
aflags-$(biarch) += -a32
cflags-$(biarch) += -m32

In the above example, $(biarch) is set to y if $(CC) supports the -m32
option. When $(biarch) equals 'y', the expanded variables $(aflags-y)
and $(cflags-y) will be assigned the values -a32 and -m32,
respectively.
在上面的例子中,如果$(CC)支持-m32选项,那么$(biarch)的值将会被置为y.
当$(biarch)的值等于‘y’,那么扩展的变量$(aflags-y)和$(cflags-y)将会分别等于-a32和-m32.

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)将选择合适的前缀:
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.
在上面的例子中,选项-falign-functions=4用于gcc >=3.00的情况.
于gcc < 3.00的情况,使用 -malign-functions=4 选项.

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就会非常有用.比如尽管cc-version选项会被gcc给接受,但是-mregparm=3在某些gcc版本中还是不会成立.

Example:
例子:
#arch/i386/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)的版本,并且当版本表达式的值为真的时候,它的值等于最后一个参数的值.

Example:
例子:
#fs/reiserfs/Makefile
EXTRA_CFLAGS := $(call cc-ifversion, -lt, 0402, -O1)

In this example, EXTRA_CFLAGS 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的值将会等于-01的值.
    cc-ifversion语序所有的shell操作符:
    -eq,-ne, -lt, -le, -gt, 和-ge
    在这个例子中,第三个参数可以是一个文本,但是它也可以是一个扩展变量或者宏。
 
=== 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.
Kbuild支持在编译阶段使用主机上的可执行文件.
为了使用主机可执行文件需要两个步骤.

The first step is to tell kbuild that a host program exists. This is
done utilising the variable hostprogs-y.
第一步是告诉kbuild存在一个主机程序.
这可以通过使用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.
第二步是给可执行文件增加一个明确地依赖项.这可以通过两种方法实现.通过在规则中增
加依赖项或者使用$(always)变量.
这两种可能性都在下面描述.

--- 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.
在某些情况下,需要在build运行的主机上编译和运行一个程序.
下面的几行将告诉kbuild有一个程序bin2hex将要在build运行的主机上编译运行.
 
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.
Kbuild假设上面例子中的bin2hex是从一个名叫bin2hex.c的c源文件编译生成的,它与Makefile处于同一个目录下面.

--- 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.
主机程序可以基于复合对象生成。
用来给主机程序定义复合对象的语法与定义内核对象的语法类似。
$(<executable>-objs)变量列出了最后链接可执行文件的所有对象。

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 <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后缀名的对象被认为是共享库,共享库会被编译成为与位置无关的对象.
Kbuild提供了对共享库的支持,但是对共享库的使用应该严格限制.
在下面的例子中,共享库libkconfig.so用来连接可执行文件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.
在makefile文件中,共享库需要相应的-obs行,在上面的例子中,共享库libkconfig由expr.o和type.o两个对象组成。
Expr.o和type.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,一般不建议使用.

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).
在上面的例子中可执行文件由名叫qconf.cc的C++文件组成– 使用$(qconf-cxxobjs)变量来识别.

If qconf is composed by a mixture of .c and .cc files, then an
additional line can be used to identify this.
如果qconf由.c和.cc和混合文件组成,那么需要一些额外的行来标记该行为.

Example:
例子:
#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)变量中指定的选项。
可以使用HOST_EXTRACFLAGS变量来设置对所有当前Makefile中创建的主机都有效的标记。

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".
当连接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) 将先决条件明确地在特殊规则中列出

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).
只有当$(obj)/gen-devlist更新后,目标$(obj)/devlist.h才会被编译。
注意特殊规则中对主机程序的引用必须使用前缀$(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.
当没有合适的特殊规则,并且在kbuild进入makefile的时候就要生成主机程序,那么就应该使用$(always)变量。

Example:
例子:
#scripts/lxdialog/Makefile
hostprogs-y   := lxdialog
always        := $(hostprogs-y)

This will tell kbuild to build lxdialog even if not referenced in
any rule.
这将告诉kbuild编译lxdialog,即使它没有在任何规则中引用。

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

A typical pattern in a Kbuild file looks like this:
Kbuild文件中的一种典型形式是这样的:

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 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’是将文件作为模块。
所以如果一个文件的配置标志等于‘m’,kbuild还是会将它编译成二进制代码。
换句话说,Kbuild处理hostprogs-m完全和处理hostprogs-y的方法一样。
不过在没有CONFIG标志的时候,只建议使用hostprogs-y。

=== 5 Kbuild clean infrastructure
=== 5 Kbuild的清除机制

"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.
“make clean”命令删除大多数内核编译目录的目标树中生成的文件。
要删除的文件包括所编译过程中生成的文件,比如主机程序。
Kbuild知道(hostprogs-y), $(hostprogs-m), 
$(always),$(extra-y) 和$(targets)这些列表中存在的目标,这些目标都会在执行"make clean"命令后删除。
匹配"*.[oas]", "*.ko"模式的文件加上一些由kbuild生成的附加文件,在"makeclean"执行时都
会从内核源码树中删除。

Additional files can be specified in kbuild makefiles by use of $(clean-files).
在kbuild makefiles中可以使用(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 '/').
当执行"make clean"后,"devlist.h  classlist.h"这两个文件也将会被删除。如果没有给出文件
的绝对地址(以‘/’开头),那么kbuild就会假设该文件与makefile在同一目录下。

To delete a directory hierarchy 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 '/').
上面的例子中将会删除目录debian,以及它包含的所有子目录。如果没有给出目录
的绝对地址(以‘/’开头),那么kbuild就会假设该目录与makefile在同一目录下。

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.
如果makefile中存在类似"obj-* := dir/"的语句,那么kbuild就必须进入到指定的子目录中去,
但是在于体系架构相关的makefiles中kbuild的机制不够全面,这种情况需要明确指出来。

Example:
例子:
#arch/i386/boot/Makefile
subdir- := compressed/

The above assignment instructs kbuild to descend down in the
directory compressed/ when "make clean" is executed.
上面的等式告诉kbuild在执行"make clean"命令时,同时也需要进入子目录compressed/中执
行该命令。

To support the clean infrastructure in the Makefiles that builds the
final bootimage there is an optional target named archclean:
存在一个叫做archclean的可选目标,用来支持生成最终启动映像的Makefiles的清除机制:

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.
当执行"make clean"命令时,make会进入arch/i386/boot目录,并且像一般情况一样进行清
除。arch/i386/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中,
而kbuild机制在那个时候还是不能工作的。

Note 2: All directories listed in core-y, libs-y, drivers-y and net-y will
be visited during "make clean".
注意2:在执行"make clean"时,所有core-y, libs-y, drivers-y 和 net-y列表中的目录都将会被
访问。

=== 6 Architecture Makefiles
=== 6 具体架构的Makefiles

The top level Makefile sets up the environment and does the preparation,
before starting to descend down in the individual directories.
The top level makefile contains the generic part, whereas
arch/$(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在开始进入单个的目录之前会设置环境并且做一些准备工作。顶层makefile
中包含一些通用部分,而arch/$(ARCH)/Makefile包含为了表示架构而建立kbuild需要的东西。
arch/$(ARCH)/Makefile建立了一些变量以及定义了一些目标来做准备。

When kbuild executes, the following steps are followed (roughly):
1) Configuration of the kernel => produce .config
2) Store kernel version in include/linux/version.h
3) 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 values of the above variables are expanded in 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.
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
当kbuild执行时,将会执行下面这些步骤(不一定完全是):
1)  配置内核 => 产生 .config文件
2)  将内核版本号保存到include/linux/version.h文件中
3)  符号链接include/asm到include/asm-$(ARCH)
4)  更新目标的所有先决条件:-附加的先决条件在arch/$(ARCH)/Makefile中指定
5)  递归地进入init-*core* drivers-* net-* libs-*列表中的列出的所有目录,并且编译生成所有目标。
- 上述变量的值是在arch /$(ARCH)/ Makefile中扩充
 
6)  所有生成的目标将会被链接最后生成vmlinux文件,它位于目标树的根部。
7)  最终,特定于体系结构的那部分程序会做所有善后工作,并且生成最终的bootimage。
- 建立boot记录
- 准备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.
用于所有调用连接器的标志。
通常指定仿真器就足够了。

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-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 uses the LDFLAGS_$@ support.
当链接最终的vmlinux映像的时候,LDFLAGS_vmlinux指定传递给链接的附加标志。
LDFLAGS_vmlinux使用LDFLAGS_$@支持。

Example:
例子:
#arch/i386/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.
当使用$(callif_changed,objcopy)来转换一个.o文件时,OBJCOPYFLAGS中指定的标志将会被使用。
$(callif_changed,objcopy)经常用来生成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.
这个例子中,二进制文件 $(obj)/image是vmlinux得一个二进制版本。$(call if_changed,xxx)变量的使用将会在后面描述。

AFLAGS $(AS) assembler flags
AFLAGS      $(AS)  汇编器标志

Default value - see top level Makefile
Append or modify as required per architecture.
默认值 - 请看顶层Makfile文件
根据系统架构的要求进行追加或者修改。

Example:
例子:
#arch/sparc64/Makefile
AFLAGS += -m64 -mcpu=ultrasparc

CFLAGS $(CC) compiler flags
CFLAGS      $(CC)  编译器标志

Default value - see top level Makefile
Append or modify as required per architecture.
默认值 - 请看顶层Makfile文件
根据系统架构的要求进行追加或者修改。

Often, the CFLAGS variable depends on the configuration.
大多数情况下,CFLAGS变量值依赖于配置程序

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:
许多体系相关的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)
...

The first example utilises the trick that a config option expands
to 'y' when selected.
第一个例子中使用了一个技巧,当一个配置选项被选择时,它的值会被扩展到‘y’。

CFLAGS_KERNEL $(CC) options specific for built-in
CFLAGS_KERNEL   $(CC)  为编译进内核指定的选项

$(CFLAGS_KERNEL) contains extra C compiler flags used to compile
resident kernel code.
$(CFLAGS_KERNEL)包含额外的C编译器标志用来编译常驻内存的代码。

CFLAGS_MODULE $(CC) options specific for modules
CFLAGS_MODULE   $(CC)  为模块指定的选项

$(CFLAGS_MODULE) contains extra C compiler flags used to compile code
for loadable kernel modules.
$(CFLAGS_MODULE)包含额外的C编译器标志用来编译可加载内核模块的代码。

--- 6.2 Add prerequisites to archprepare:
--- 6.2 增加先决条件到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:这是一条用来列出先决条件的规则,这些先决条件是build进入子目录前 必须建立的。
这将从在包含汇编内容的头文件中使用。

Example:
例子:
#arch/arm/Makefile
archprepare: maketools

In this example, the file target maketools will be processed
before descending down in the subdirectories.
See also chapter XXX-TODO that describe how kbuild supports
generating offset header files.
在这个例子中,在进入到子目录前目标文件maketools将会被处理。
想要知道kbuild怎么支持生成偏移头文件,请看XXX-TODO这一章。

--- 6.3 List directories to visit when descending
--- 6.3 递归时列出需要访问的目录

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文件的变
量。注意没有给模块指定体系相关的区域;模块生成机制全是体系无关的。

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

$(head-y) lists objects to be linked first in vmlinux.
$(libs-y) lists directories where a lib.a archive can be located.
The rest list directories where a built-in.o object file can be
located.
$(head-y)列出了首先要链接到vmlinux中的对象
$(libs-y)列出了lib.a归档文件可以被放置的目录。
剩下的列出了一个built-in.o对象文件可以被放置的目录。

$(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).
$(init-y)对象将被放置在 $(head-y)后.
然后剩下的就按下面的顺序放置:
$(core-y),$(libs-y), $(drivers-y) and $(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只添加了体系相关的目录。

Example:
例子:
#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
--- 6.4 与架构相关的启动映像

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/中指定的目标。
因此应该手动调用make arch/$(ARCH)/Makefile来生成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文件中时再使用完整的路径。

Example:
例子:
#arch/i386/Makefile
boot := arch/i386/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)。

Example:
例子:
#arch/i386/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:.
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.
当不带任何参数执行make命令的时候,将会生成第一个遇到的目标。
当前顶层Makefile文件的第一个目标是all:.
    默认情况下,每一个架构应该生成一个可引导映像。
在"make help"中,默认目标使用一个'*'来突出显示。
向all:中添加一个新的先决条件:选择一个与vmlinux不同的默认目标。

Example:
例子:
#arch/i386/Makefile
all: bzImage

When "make" is executed without arguments, bzImage will be built.
当不带任何参数执行“make”命令时,bzImage将会被建立生成。

--- 6.5 Building non-kbuild targets
--- 6.5 建立非kbuild的目标

extra-y

extra-y specify additional targets created in the current
directory, in addition to any targets specified by obj-*.
extra-y指定在当前目录创建的额外目标,除了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"
在下面两种情况下,将所有目标放在extra-y列表下是必要的:
1)使能kbuild来检查命令行中的改变 – 当 $(callif_changed,xxx) 被使用
2)kbuild知道在执行"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.
在这个例子中,extra-y用来列出将要被建立的目标文件,但是这些文件不应该被链接作为built-in.o的一部分。

--- 6.6 Commands useful for building a boot image
--- 6.6 用来建立启动映像的命令

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是下面命令行的基础。

Usage:
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.
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".
当一个规则被求值的时候,会检查规则相对于上次被调用是否有文件被更新或者命令行被改变。
如果任何可执行文件的选项被改变,那么就会强制执行rebuild。
如果任何目标使用了if_changed,那么它必须放进$(targets)列表中,不然命令行的检查会失败,并且目标会一直被建立。
    $(targets)的等式中没有使用 $(obj)/前缀。
    if_changed可以结合和6.7节"Customkbuild commands"中定义的用户命令。
 
Note: It is a typical mistake to forget the FORCE prerequisite.
Another common pitfall is that whitespace is sometimes
significant; for instance, the below will fail (note the extra space
after the comma):
target: source(s) FORCE
#WRONG!# $(call if_changed, ld/objcopy/gzip)
注意:一个典型的错误就是忘记了 FORCE 先决条件。
    另外一个常见的陷阱就是空格有时很显著;比如,下面的例子将会失败(注意逗号后面         的多余空格):
    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.
复制二进制。OBJCOPYFLAGS的使用经常在arch/$(ARCH)/Makefile文件中指定。
    OBJCOPYFLAGS_$@可以用来设置附加的选项。

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 assigned all potential targets, by which kbuild knows
the targets and will:
1) check for commandline changes
2) delete target during make clean
在这个例子中,有两个可能的目标,在它们在链接的时候需要不同的选项。通过使用LDFLAGS_$@语法格式来指定链接选项 - 每一个可能的目标都需要指定。
    $(targets)代表的值是所有可能的目标,kbuild通过$(targets)来知道这些目标,然后执行下面的操作:
   1)检查命令行的改变
   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.o和bootsect.o文件。
注意:一个常见的错误就是忘记"target :="赋值表达式,导致目标文件在没有明显原因的情况下被重新编译。

--- 6.7 Custom kbuild commands
--- 6.7 自定义kbuild命令

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,那么只正常显示一个命令的简写方式。
为了使能自定义命令这一行为,kbuild需要设置两个变量:
    quiet_cmd_<command> - 被显示的部分
          cmd_<command> - 执行的命令名

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".
当更新 $(obj)/bzImage的时候,这一行
        
    BUILD    arch/i386/boot/bzImage
 
    将会显示为 "makeKBUILD_VERBOSE=0"。

--- 6.8 Preprocessing linker scripts
--- 6.8 预处理链接脚本

When the vmlinux image is built, 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 files and includes a rule *lds.S -> *lds.
当生成vmlinux映像的时候,会使用连接器脚本arch/$(ARCH)/kernel/vmlinux。
这个脚本是vmlinux.lds.S文件的一个预处理变种,vmlinux.lds.S文件与这个脚本在同一个目录下。
Kbuild知道.lds文件,并且包含一条*lds.S-> *lds规则。

Example:
例子:
#arch/i386/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.
The assignment to $(CPPFLAGS_vmlinux.lds) tells kbuild to use the
specified options when building the target vmlinux.lds.
赋给$(always)变量的等式是用来告诉kbuild建立vmlinux.lds目标。
赋给$(CPPFLAGS_vmlinux.lds)变量的等式是用来告诉kbuild在建立vmlinux.lds目标的时候使用指定的选项。
 
When building the *.lds target, kbuild uses the variables:
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.
当建立*.lds目标的时候,kbuild使用下面的这些变量:
    CPPFLAGS        : 在顶层Makefile文件中设置
    EXTRA_CPPFLAGS  : 可能在kbuild makefile文件中设置
    CPPFLAGS_$(@F)  : 针对特定的标志.
                      注意在这个赋值表达式中使用文件全名。

The kbuild infrastructure for *lds file are used in several
architecture-specific files.
针对*lds文件的kbuild机制在一些体系相关的文件中使用。

=== 7 Kbuild Variables
=== 7 Kbuild 变量

The top Makefile exports the following variables:
顶层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), and $(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",它适合作为安装目录名或者在版本号中出现。
一些架构的Makefiles就基于这些目的使用了它。

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 makefiles通过检查$(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:
默认情况下,顶层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.
这个变量定义了一个架构Makefiles安装固定内核映像和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中定义,但是用户愿意的话可以将它传入Makefile中。

$(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.
顶层Makefile为$(INSTALL_MOD_PATH)/lib/modules/$(KERNELRELEASE)定义了$(MODLIB)变量。
用户如果愿意的话可以通过命令行来改写这个值。

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 will used as the option(s) to the strip command.
如果这个变量被指定了,那么将导致模块在安装之后被去除。
如果INSTALL_MOD_STRIP的值为‘1’,那么会使用默认的选项--strip-debug。
否则,INSTALL_MOD_STRIP将会被作为strip命令的选项。

=== 8 Makefile language
=== 8 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.
内核 Makefiles被设计成使用GNU Make运行。Makefiles只使用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支持基本的list-processing功能。内核Makefiles使用一些样式新颖的列表来建立和操作一些"if"语句。

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.
GNU Make有两个赋值操作符,":="和"=" 。":="立即计算出等式右边的值,并且储存一个实际的字符串到等式左边。
"="就像一个规则定义;它将等式右边直接储存到等式左边而不计算出实际的值,当每次使用等式左边的值时再去计算出实际的值。

There are some cases where "=" is appropriate.  Usually, though, ":="
is the right choice.
有一些情况使用"="是合适的。但是大多数情况下使用":="是合适的选择。

=== 9 Credits
=== 9贡献者

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>
原始的版本由Michael Elizabeth Chastain 提供,<发送邮件至 : mec@shout.net>
Kai Germaschewski进行了更新 kai@tp1.ruhr-uni-bochum.de
Sam Ravnborg 进行了更新 sam@ravnborg.org
文本质量保证由Jan Engelhardt 担任jengelh@gmx.de

=== 10 TODO
=== 10 下一步的工作

- Describe how kbuild supports shipped files with _shipped.
- Generating offset header files.
- Add more variables to section 7?
- 描述kbuild怎么使用_shipped来支持shipped文件
- 生成offset头文件

- 增加更多的变量到 section 7?

博客上面不方便排版,美观一点的点我下载。

【补充】Linux-2.6.22.6 makefiles.txt翻译相关推荐

  1. Linux之Ubuntu 22.04实现微信双开

    Linux之Ubuntu 22.04实现微信双开 基于deepin-wine仓库安装第一个微信 添加仓库 安装对应软件包 com.qq.weixin.deepin 微信的安装 存在的问题 补充 Lin ...

  2. Linux内核官方文档atomic_ops.txt【摘自Linux 内核文档】

    摘自Linux内核文档 Documentation/atomic_ops.txt,不是本人原创 Semantics and Behavior of Atomic and Bitmask Operati ...

  3. 用两个文件a.txt;b.txt.使用linux命令,复制,a.txt文档倒数第十行的记录to b.txt文档

    用两个文件a.txt;b.txt.使用linux命令,复制,a.txt文档倒数第十行的记录to b.txt文档 tail -n 10 a.txt | head -n 1 >> b.txt

  4. linux生成文件清单,Linux 获取文件名称生成列表 txt - create_filelist

    Linux 获取文件名称生成列表 txt - create_filelist 1. find /home/strong/MOTChallenge/MOT16/MOT16/train/MOT16-04/ ...

  5. linux生成一个list文件,Linux 获取文件名称生成列表 txt - create_filelist

    Linux 获取文件名称生成列表 txt - create_filelist 1. find /home/strong/MOTChallenge/MOT16/MOT16/train/MOT16-04/ ...

  6. Timsort 介绍(listsort.txt 翻译)

    Timsort 介绍(listsort.txt 翻译) 译文 简介(Intro) 与 Python 样本混合排序的比较(Comparison with Python's Samplesort Hybr ...

  7. Linux源码下Makefile详解(参照Documentation\kbuild\makefiles.txt和资料)-转

    1.Makefile的作用 (1)决定编译哪些文件 (2)怎样编译这些文件 (3)怎样连接这些文件,最重要的是它们的顺序如何 2.Linux内核Makefile分类 ***************** ...

  8. 【linux基础】22、iptables layer7 实现七层应用过滤

    一.iptables layer7简介 iptables layer7模块根据应用层协议对访问请求进行过滤 iptables工作于二,三,四层,本身不具备7层过滤功能,第三方开发者为iptables新 ...

  9. linux编程 —— vscode 开发编译 CMakeList.txt 学习笔记

    文档声明: 以下资料均属于本人在学习过程中产出的学习笔记,如果错误或者遗漏之处,请多多指正.并且该文档在后期会随着学习的深入不断补充完善.感谢各位的参考查看. 笔记资料仅供学习交流使用,转载请标明出处 ...

最新文章

  1. 数据结构-线性表(栈与队列的特殊性)
  2. MySQL 的 bug 必须修复吗?
  3. VS2008创建dll,并使用dll
  4. KMP算法详细讲解(看完不会请打我)
  5. 红旗linux培训文档,Linux基本应用培训-红旗Linux.ppt
  6. Mr.J--正则表达式
  7. UE4: 学习虚幻引擎4的16条准则
  8. 高精度测量让交会对接更“温柔”
  9. iOS上传图片和视频(base64和file)
  10. Java基础---继承
  11. OSChina 周三乱弹 —— 究竟是谁走漏风声
  12. 用什么软件写html语言,写html代码用什么软件
  13. 集成电路技术与产业发展
  14. 怎么才能写好技术文档——这是我的全部经验
  15. SAP PS 第19节 里程碑开票
  16. 563. 二叉树的坡度【我亦无他唯手熟尔】
  17. 亚马逊AWS机器学习答案-练习题
  18. 2021年焊工(初级)免费试题及焊工(初级)实操考试视频
  19. python 装饰器
  20. 第7篇:MS12-020蓝屏漏洞在实战中的巧用

热门文章

  1. amd的cpu跑python_Windows下用cpu模式跑通目标检测py-faster-rcnn 的demo.py
  2. 编程的97件事——1、谨慎行事
  3. Oracle的ltrim函数
  4. bulldog1——爆破、命令执行、pty提权
  5. SVGA 礼物动画设计相关
  6. Hadoop的完全分布式搭建
  7. 构建云视频平台的七种武器分别包括长生剑、孔雀翎、碧玉刀、多情环、离别钩、霸王枪、拳头,这七种武器分别对应的是什么技术呢?该文将揭晓答案。
  8. 目标检测、视觉弱监督学习、大脑多模态成像技术等CV综述来了!图像图形学发展年度报告综述专刊!...
  9. 【AI打板?】【量化交易?】究竟是什么? 一句话看懂量化
  10. 从深度学习计算过程来分析深度学习工作站\服务器的硬件配置