Linux Kernel Makefiles(转)- -
Linux Kernel Makefiles
本文由王立于 2003 年 5 月 3 日翻译。原文为 linux-2.4.20 中 Documentation/kbuild/makefiles.txt,由 Michael Elizabeth Chastain 于 2000 年 9 月 14 日作。
1、概述
Makefile 由五个部分组成:
- Makefile:顶层 Makefile。
- .config:内核配置文件。
- arch/*/Makefile:体系结构 Makefiles。
- 子目录 Makefile:大约三百个。
- Rules.make:为所有子目录 Makefile 提供通用规则。
顶层 Makefile 读入在内核配置过程中生成的 .config 文件。
顶层 Makefile 负责两个主要产品的创建:vminux (常驻内核映象) 和模块 (任何模块文件)。它通过递归下降到内核源代码树以创建这些目标。需要进入的子目录由内核配置确定。
顶层 Makefile 引入一个名为 arch/$(ARCH)/Makefile 的体系结构 Makefile。体系结构 Makefile 为顶层 Makefile 提供体系结构特定的信息。
每一子目录都有一个 Makefile 以完成从上层传递来的命令。子目录 Makefile 使用来自 .config 文件的信息以构造各种文件列表,而后引入 Rules.make 中的通用规则。
Rules.make 定义了所有子目录 Makefile 的通用规则。它的一个变量列表组成了它的公共界面。而后它根据这些列表声明规则。
2、谁需要什么
人们跟内核的 Makefile 有四种不同的关系。
用户是创建内核的人。这些人输入诸如“make menuconfig”或 “make bzImage”之类的命令。他们通常并不阅读或编辑内核 Makefile (或任何其它源代码)。
普通开发者是开发诸如设备驱动程序、文件系统或网络协议的人。这些人需要为他们开发的子系统维护用于该子系统的子目录 Makefile。为了有效地完成这一维护任务,他们需要一些关于内核 Makefile 的全局性的知识,以及一些关于 Rules.make 公共界面的细节。
体系结构开发者是开发整个体系结构 (例如 spare 或 ia64) 的人。体系结构开发者需要理解体系结构 Makefile 以及子目录 Makefile。
Kbuild 开发者是开发内核创建系统本身的人。这些人需要知道内核 Makefile 的所有方面。
本文档是面向普通开发者和体系结构开发者的。
3、Makefile 语言
内核 Makefile 被设计为使用 GNU Make。这些 Makefiles 只使用 GNU Make 文档说明了的功能,但它们使用了很多 GNU 扩展。
GNU Make 支持基本列表处理函数。内核 Makefile 使用带有少量 if 语句的新颖的列表创建和操作风格。
GNU Make 有两种赋值操作符:“:=”和“。“: ”立即对右侧进行求值并且将结果字符串存储于左侧变量中。“=”更像公式定义;它以未求值形式保存右侧的内容并在使用左侧变量的时候对此内容进行求值。
在有些情况下“=”比较适用。但通常“:=”是正确的选择。
本文档的所有示例都来自于实际的内核源代码。这些示例都被重新排版过 (改变了空白符和行的划分),但其它都完全一致。
4、从顶层传递下去的变量
顶层 Makefile 导出以下变量:
VERSION、 PATCHLEVEL、SUBLEVEL、EXTRAVERSION | ||
这些变量定义了当前内核版本。少数体系结构 Makefile 直接使用这些值;它们应该使用 $(KERNELRELEASE)。 $(VERSION)、$(PATCHLEVEL) 和 $(SUBLEVEL) 定义了三个基本版本编号,例如“2”、“4”和“0”。这三个值总是数值。 $(EXTRAVERSION) 定义了更低级别的预备补丁或附加补丁。它通常是类似于 “-pre4的”非数值字符串,并且往往为空。 |
||
KERNELRELEASE | ||
$(KERNELRELEASE) 是类似于“2.4.0-pre4”的单个字符串,适于构造安装目录名或在版本字符串中显示。某些体系结构 Makefile 将它用于这样的目的。 | ||
ARCH | ||
该变量定义了目标体系结构,例如“i386”、“arm”或 “sparc”。许多子目录 Makefile 测试 $(ARCH) 以决定编译那些文件。 在默认情况下,顶层 Makefile 将 $(ARCH) 设定为主机系统的体系机构。为了进行交叉创建,用户可以在命令行覆盖 $(ARCH) 的值。
|
||
TOPDIR、HPATH | ||
$(TOPDIR) 是内核源代码树顶层目录的路径。子目录 Makefile 需要此变量以便引入 $(TOPDIR)/Rules.make。 $(HPATH) 等价于 $(TOPDIR)/include。少数体系结构 Makefile 需要它以使用引入文件做一些特殊的事。 |
||
SUBDIRS | ||
$(SUBDIRS) 是顶层 Makefile 应该进入以便完成 vmlinux 或模块创建的目录列表。$(SUBDIRS) 含有那些目录取决于内核配置。顶层 Makefile 定义此变量,体系结构Makefile 扩展此变量。 | ||
HEAD、CORE_FILES、NETWORKS、DRIVERS、LIBS、LINKFLAGS | ||
$(HEAD)、$(CORE_FILES)、$(NETWORKS)、$(DRIVERS) 和 $(LIBS) 给出要连接到 vmlinux 中的目标文件和库的列表。 $(HEAD) 中的文件首先连接到 vmlinux 中。 $(LINKFLAGS) 指定创建 vmlinux 的标志。 顶层 Makefile 和体系结构 Makefile 联合定义这些变量。顶层 Makefile 定义 $(CORE_FILES)、$(NETWORKS)、$(DRIVERS) 和 $(LIBS)。体系结构 Makefile 定义 $(HEAD) 和 $(LINKFLAGS) 并扩展 $(CORE_FILES) 和 $(LIBS)。 注意:这些变量并不都是必需的。$(NETWORKS)、$(DRIVERS)甚至 $(LIBS) 都应该合并到 $(CORE_FILES) 中去。 |
||
CPP、CC、AS、LD、AR、NM、STRIP、OBJCOPY、OBJDUMP、CPPFLAGS、CFLAGS、CFLAGS_KERNEL、MODFLAGS、AFLAGS、LDFLAGS、PERL、GENKSYMS | ||
这些变量指定了 Rules.make 用于从源代码文件创建目标文件的命令和标志。 $(CFLAGS_KERNEL) 含有用于编译常驻内核代码的附加 C 编译器标志。 $(MODFLAGS) 含有用于编译可载入内核模块的附加 C 编译器标志。将来该标志可能要改为更通用的 $(CFLAGS_MODULE)。 $(AFLAGS) 含有汇编标志。 $(GENKSYMS) 含有用于生成在启用了 CONFIG_MODVERSIONS 时内核符号签名的命令。 genksyms 命令由 modutils 包提供。 |
||
CROSS_COMPILE | ||
该变量是诸如 $(CC)、$(AS) 和 $(LD) 之类的其它变量的前缀路径。体系结构Makefile 有时显式使用并设置该变量。子目录 Makefile 不需要关心它。 如果需要,用户可以在命令行中覆盖 $(CROSS_COMPILE) 的值。 |
||
HOSTCC、HOSTCFLAGS | ||