日期:2014-05-16  浏览次数:20655 次

Linux内核Makefile文件(二)

?

=== 6 体系Makefile文件

在开始进入各个目录编译之前,顶层Makefile文件设置编译环境和做些准备工作。顶层Makefile文件包含通用部分,arch/$(ARCH) /Makefile包含该体系架构所需的设置。因此arch/$(ARCH)/Makefile会设置一些变量和少量的目标。

当编译时将按照以下大概步骤执行:
1) 配置内核 => 产生 .config文件
2) 保存内核版本到include/linux/version.h文件中
3) 符号链接include/asm to include/asm-$(ARCH)
4) 更新所有目标对象的其它前提文件
- 附加前提文件定义在arch/$(ARCH)/Makefile文件中
5) 递归进入init-* core* drivers-* net-* libs-*中的所有子目录和编译所有的目标对象
- 上面变量值都引用到arch/$(ARCH)/Makefile文件。
6) 链接所有的object文件生成vmlinux文件,vmlinux文件放在代码树根目录下。
最开始链接的几个object文件列举在arch/$(ARCH)/Makefile文件的head-y变量中。
7) 最后体系Makefile文件定义编译后期处理规则和建立最终的引导映像bootimage。
- 包括创建引导记录
- 准备initrd映像和相关处理

--- 6.1 变量设置

LDFLAGS????? $(LD)一般选项

???? 选项使用于链接器的所有调用中。通常定义emulation就可以了。

???? Example:
???????????? #arch/s390/Makefile
???????????? LDFLAGS?? := -m elf_s390

???? 注意: EXTRA_LDFLAGS和LDFLAGS_$@可以进一步订制使用选项,请参考第7章。

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

???? LDFLAGS_MODULE通常设置$(LD)链接模块的.ko选项。默认为"-r"即可重定位输出文件。

LDFLAGS_vmlinux?? $(LD)链接vmlinux选项

???? LDFLAGS_vmlinux定义链接最终vmlinux时链接器的选项。LDFLAGS_vmlinux支持使用LDFLAGS_$@。

???? Example:
???????????? #arch/i386/Makefile
???????????? LDFLAGS_vmlinux := -e stext

OBJCOPYFLAGS????? objcopy选项

???? 当使用$(call if_changed,objcopy)转化a .o文件时,OBJCOPYFLAGS中的选项将被使用。$(call if_changed,objcopy)经常被用作为vmlinux产生原始的二进制文件。

???? Example:
???????????? #arch/s390/Makefile
???????????? OBJCOPYFLAGS := -O binary

???????????? #arch/s390/boot/Makefile
???????????? $(obj)/image: vmlinux FORCE
????????????????????? $(call if_changed,objcopy)

???? 在上面例子中$(obj)/image是vmlinux的二进制版本文件。$(call if_changed,xxx)的使用方法见后。

AFLAGS?? $(AS)汇编选项

???? 默认值见顶层Makefile文件。针对每个体系需要另外添加和修改它。

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

CFLAGS????? $(CC)编译器选项

???? 默认值见顶层Makefile文件。针对每个体系需要另外添加和修改它。

???? 通常CFLAGS变量值取决于内核配置。

???? Example:
???????????? #arch/i386/Makefile
???????????? cflags-$(CONFIG_M386) += -march=i386
???????????? CFLAGS += $(cflags-y)

???? 许多体系Makefiles文件动态启动市场目标机器上的C编译器检测支持的选项:

?????????? #arch/i386/Makefile
?????????? ...
?????????? cflags-$(CONFIG_MPENTIUMII)?? += $(call cc-option,\
???????????????? -march=pentium2,-march=i686) ...
?????????? # Disable unit-at-a-time mode ...
?????????? CFLAGS += $(call cc-option,-fno-unit-at-a-time)
?????????? ...

???? 第一个例子当config选项是'y'时将被选中。

CFLAGS_KERNEL????? $(CC)编译built-in对象的选项

???? $(CFLAGS_KERNEL)包含外部C编译器选项编译本地内核代码。

CFLAGS_MODULE????? $(CC)编译模块选项

???? $(CFLAGS_MODULE)包含外部C编译器选项编译可加载内核代码。

--- 6.2 增加预设置项

???? prepare: 这个规则用于列举开始进入子目录编译前需要的前提文件。通常是些包含汇编常量的头文件。
???? prepare: 这个规则用于列举开始进入子目录编译前需要的前提文件。通常是些包含汇编常量的头文件。

???? Example:
???????????? #arch/s390/Makefile
???????????? prepare: include/asm-$(ARCH)/offsets.h

???? 在这个例子中include/asm-$(ARCH)/offsets.h将在进入子目录前编译。详见XXX-TODO文件描述了kbuild如何产生offset头文件。

--- 6.3 目录表

???? 体系Makefile文件和顶层Makefile文件共同定义了如何建立vmlinux文件的变量。注意没有体系相关的模块对象定义部分:所有的模块对象都是体系无关的。

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

???? $(head-y) 列举首先链接到vmlinux的对象文件。
???? $(libs-y) 列举了能够找到lib.a文件的目录。
???? 其余的变量列举了能够找到内嵌对象文件的目录。

???? $(init-y) 列举的对象位于$(head-y)对象之后。
???? 然后是如下位置秩序:
???? $(core-y), $(libs-y), $(drivers-y) 和 $(net-y)。

???? 顶层Makefile定义了所有同用目录,arch/$(ARCH)/Makefile文件只需增加体系相关的目录。

???? Example:
???????????? #arch/sparc64/Makefile
???????????? core-y += arch/sparc64/kernel/