https://github.com/kernel-digger/linux/blob/comments/Documentation/kbuild/makefiles.txt
=== 1 Overview
Makefile包含5个部分:
1. 顶层Makefile。
2. 配置文件.config。
3. 对应架构的arch/$(ARCH)/Makefile。
4. 对所有Makefile的通用规则scripts/Makefile.*。
5. 各个子目录下的Makefile。
顶层Makefile读取通过配置生成的.config文件。
顶层Makefile主要负责生成2个文件:vmlinux(常驻内存的内核镜像文件)和其他模块。
递归进入源码树的各个子目录进行编译。
顶层Makefile原文包含对应架构的arch/$(ARCH)/Makefile。
每个子目录都有一个Makefile来执行上层传递下来的命令。
Makefile使用.config中的信息构建编译内建或模块目标的文件列表。
scripts/Makefile.*包含所有内核构建使用的定义和规则。
=== 2 Who does what
=== 3 The kbuild files
尽量使用文件名称"Makefile","Kbuild"名称文件存在的时候则使用"Kbuild"文件。
--- 3.1 Goal definitions
--- 3.2 Built-in object goals - obj-y
使用obj-y为vmlinux指定目标文件。
使用"$(LD) -r"将目标文件合并为built-in.o。
这些built-in.o最终由顶层Makefile链接成vmlinux。
$(obj-y)文件列表的顺序很重要。
链接顺序很重要。
--- 3.3 Loadable module goals - obj-m
使用obj-m为可加载模块指定目标文件。
模块由多个源文件编译的时候,使用$(<module_name>-y)为模块指定其需要的目标文件。
--- 3.4 Objects which export symbols
--- 3.5 Library file goals - lib-y
使用lib-y,lib-m指定的目标文件会被包含在lib.a中。
lib-y通常限制在lib/和arch/*/lib目录下。
--- 3.6 Descending down in directories
一个Makefile文件只负责为其所在的目录编译目标文件。
构建系统会递归进入子目录调用make。
使用斜杠"/"结尾的目标来指定需要递归进入的目录。
--- 3.7 Compilation flags
ccflags-y, asflags-y and ldflags-y这3个标志只对其所在的Makefile有效。
EXTRA_CFLAGS, EXTRA_AFLAGS and EXTRA_LDFLAGS有同样的功能,仍然支持不过已经弃用。
subdir-ccflags-y, subdir-asflags-y这2个标志对其所在目录及子目录的Makefile有效。
CFLAGS_$@, AFLAGS_$@只对当前的Makefile有效。
--- 3.9 Dependency tracking
--- 3.10 Special Rules
特殊规则为依赖文件和目标文件提供相对目录。
$(src)路径用于引用的文件。
$(obj)路径用于生成的文件。
$(kecho)用于在执行"make -s"的时候可以输出信息。
--- 3.11 $(CC) support functions
不同版本的编译器支持不同的特性和选项。
对可用的选项进行一些基本的检查。
as-option
cc-ldoption
as-instr
cc-option
cc-option-yn
cc-option-align
cc-disable-warning
cc-version
cc-ifversion
cc-fullversion
cc-cross-prefix
--- 3.12 $(LD) support functions
ld-option
=== 4 Host Program support
构建一些主机程序用于内核镜像的生成。
使用变量hostprogs-y指定需要的主机程序。
使用明确的依赖。在规则中加入依赖或使用变量$(always)。
--- 4.1 Simple Host Program
--- 4.2 Composite Host Programs
使用$(<executable>-objs)列出生成该主机程序需要的目标文件。
--- 4.3 Defining shared libraries
共享文件使用-objs列出其依赖的目标文件。
--- 4.4 Using C++ for host programs
仅限于kconfig。
使用$(qconf-cxxobjs)指定其依赖目标。
--- 4.5 Controlling compiler options for host programs
使用$(HOSTCFLAGS)为$(HOSTCC)传递选项。
使用变量HOST_EXTRACFLAGS为该Makefile中生成的主机程序设置标志。
使用变量HOSTLOADLIBES为链接器指定额外选项。
--- 4.6 When host programs are actually built
(1) 在规则的先决条件中列出。
(2) 使用$(always)
--- 4.7 Using hostprogs-$(CONFIG_FOO)
=== 5 Kbuild clean infrastructure
clean-files 删除文件
clean-dirs 删除目录及子目录
no-clean-files 排除
subdir- 进入子目录删除
archclean
"make clean"会进入core-y, libs-y, drivers-y and net-y目录。
=== 6 Architecture Makefiles
在进入下层目录前,顶层的Makefile设置环境变量和一些准备工作。
顶层目录包含通用部分,arch/$(ARCH)/Makefile包含架构相关部分。
内核生成步骤:
1) 配置内核生成.config。
2) 保存内核版本到include/linux/version.h。
3)
4) 更新先决条件。
5) 递归进入子目录编译。
6) 链接生成vmlinux,链接在最前的目标文件由head-y列出。
7) 架构相关部分生成最终的引导镜像。
--- 6.1 Set variables to tweak the build to the architecture
LDFLAGS
LDFLAGS_MODULE
LDFLAGS_vmlinux
OBJCOPYFLAGS
KBUILD_AFLAGS
KBUILD_CFLAGS
KBUILD_AFLAGS_KERNEL
KBUILD_AFLAGS_MODULE
KBUILD_CFLAGS_KERNEL
KBUILD_CFLAGS_MODULE
KBUILD_LDFLAGS_MODULE
KBUILD_ARFLAGS
--- 6.2 Add prerequisites to archheaders:
--- 6.3 Add prerequisites to archprepare:
--- 6.4 List directories to visit when descending
架构相关的Makefile与顶层Makefile一起定义用于生成vmlinux的变量。
模块的生成与架构无关。
head-y, init-y, core-y, libs-y, drivers-y, net-y
$(head-y)列出在vmlinux最先链接的目标。
$(libs-y)列出会含有lib.a的目录。
余下的目录会生成built-in.o目标文件。
$(init-y)目标链接在$(head-y)后面。
余下的以此顺序链接$(core-y), $(libs-y), $(drivers-y) and $(net-y)。
顶层Makefile为通用目录定义值。
arch/$(ARCH)/Makefile添加架构相关目录。
--- 6.5 Architecture-specific boot images
架构相关Makefile的目标是压缩vmlinux,与引导代码一起打包,把最终文件复制到某个地方。
通用的做法是将额外的处理放在arch/$(ARCH)/boot目录。
--- 6.6 Building non-kbuild targets
extra-y指定除obj-*之外,其目录外的额外目标。
但不会被链接进built-in.o文件。
--- 6.7 Commands useful for building a boot image
if_changed
ld
objcopy
gzip
dtc
dtc_cpp
--- 6.8 Custom kbuild commands
--- 6.9 Preprocessing linker scripts
生成vmlinux镜像的时候,使用链接脚本arch/$(ARCH)/kernel/vmlinux.lds。
该脚本由同目录下的vmlinux.lds.S预处理生成。
--- 6.10 Generic header files
include/asm-generic包含架构共享的头文件。
=== 7 Kbuild syntax for exported headers
内核包含导出到用户空间的头文件。
--- 7.1 header-y
header-y列举要导出的头文件。
--- 7.2 genhdr-y
genhdr-y列举生成的文件中需要导出的文件。
--- 7.3 destination-y
指定导出的目的目录。
--- 7.4 generic-y
=== 8 Kbuild Variables
顶层Makefile导出以下变量:
VERSION, PATCHLEVEL, SUBLEVEL, EXTRAVERSION
KERNELRELEASE
ARCH
INSTALL_PATH
INSTALL_MOD_PATH, MODLIB
INSTALL_MOD_STRIP
=== 9 Makefile language
内核Makefile使用GNU Make。
GNU Make有两种赋值运算符,":="和"="。
":="右侧立即展开,并将真正的字符串保存在左侧。
"="像公式定义,在左侧使用的时候才展开。
有时候使用"="合适。
不过通常":="是正确的选择。
=== 10 Credits
=== 11 TODO