全部博文(185)
分类:
2009-08-07 18:26:52
Linux内核Makefile文件(二)
=== 6 体系Makefile文件 在开始进入各个目录编译之前,顶层Makefile文件设置编译环境和做些准备工作。顶层Makefile文件包含通用部分,arch/$ (ARCH) /Makefile包含该体系架构所需的设置。因此arch/$(ARCH)/Makefile会设置一些变量和少量的目标。 当编译时将按照以下大概步骤执行: --- 6.1 变量设置 LDFLAGS $(LD)一般选项 选项使用于链接器的所有调用中。通常定义emulation就可以了。 Example: 注意: EXTRA_LDFLAGS和LDFLAGS_$@可以进一步订制使用选项,请参考第7章。 LDFLAGS_MODULE $(LD)链接模块的选项 LDFLAGS_MODULE通常设置$(LD)链接模块的.ko选项。默认为"-r"即可重定位输出文件。 LDFLAGS_vmlinux $(LD)链接vmlinux选项 LDFLAGS_vmlinux定义链接最终vmlinux时链接器的选项。LDFLAGS_vmlinux支持使用LDFLAGS_$@。 Example: OBJCOPYFLAGS objcopy选项 当使用$(call if_changed,objcopy)转化a .o文件时,OBJCOPYFLAGS中的选项将被使用。$(call if_changed,objcopy)经常被用作为vmlinux产生原始的二进制文件。 Example: #arch/s390/boot/Makefile 在上面例子中$(obj)/image是vmlinux的二进制版本文件。$(call if_changed,xxx)的使用方法见后。 AFLAGS $(AS)汇编选项 默认值见顶层Makefile文件。针对每个体系需要另外添加和修改它。 Example: CFLAGS $(CC)编译器选项 默认值见顶层Makefile文件。针对每个体系需要另外添加和修改它。 通常CFLAGS变量值取决于内核配置。 Example: 许多体系Makefiles文件动态启动市场目标机器上的C编译器检测支持的选项: #arch/i386/Makefile 第一个例子当config选项是'y'时将被选中。 CFLAGS_KERNEL $(CC)编译built-in对象的选项 $(CFLAGS_KERNEL)包含外部C编译器选项编译本地内核代码。 CFLAGS_MODULE $(CC)编译模块选项 $(CFLAGS_MODULE)包含外部C编译器选项编译可加载内核代码。 --- 6.2 增加预设置项 prepare: 这个规则用于列举开始进入子目录编译前需要的前提文件。通常是些包含汇编常量的头文件。 Example: 在这个例子中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的对象文件。 $(init-y) 列举的对象位于$(head-y)对象之后。 顶层Makefile定义了所有同用目录,arch/$(ARCH)/Makefile文件只需增加体系相关的目录。 Example: --- 6.4 引导映像 体系Makefile文件定义了编译vmlinux文件的目标对象,将它们压缩和封装成引导代码,并复制到合适的位置。这包括各种安装命令。如何定义实际的目标对象无法为所有的体系结构提供标准化的方法。 附加处理过程常位于arch/$(ARCH)/下的boot/目录。 内核编译系统无法在boot/目录下提供一种便捷的方法创建目标系统文件。因此arch/$(ARCH)/Makefile要调用make命令在 boot/目录下建立目标系统文件。建议使用的方法是在arch/$(ARCH)/Makefile中设置调用,并且使用完整路径引用arch/$ (ARCH)/boot/Makefile。 Example: 建议使用"$(Q)$(MAKE) $(build)= 没有定义体系目标系统文件的规则,但执行"make help"命令要列出所有目标系统文件,因此必须定义$(archhelp)变量。 Example: 当执行不带参数的make命令时,将首先编译第一个目标对象。在顶层Makefile中第一个目标对象是all:。 Example: 当执行不带参数的"make"命令时,bzImage文件将被编译。 --- 6.5 编译非内核目标 extra-y extra-y定义了在当前目录下创建没有在obj-*定义的附加的目标文件。 在extra-y中列举目标是处于两个目的: Example: 上面例子extra-y中的对象文件将被编译但不会练接到built-in.o中。 --- 6.6 编译引导映像命令 Kbuild提供了一些编译引导映像有用的宏。 if_changed if_changed是后面命令使用的基础。 用法: 当这条规则被使用时它将检查哪些文件需要更新,或命令行被改变。后面这种情况将迫使重新编译编译选项被改变的执行文件。使用if_changed的目标对象必须列举在$(targets)中,否则命令行检查将失败,目标一直会编译。 注意: 一个常见错误是忘记了FORCE前导词。 ld objcopy gzip Example: targets += setup setup.o bootsect bootsect.o 在上面例子中有两个可能的目标对象,分别需要不同的链接选项。使用LDFLAGS_$@语法为每个目标对象设置不同的链接选项。 ": %: %.o"是简写方法,减写setup.o和bootsect.o文件。 注意: 常犯错误是忘记"target :="语句,导致没有明显的原因目标文件被重新编译。 --- 6.7 定制编译命令 当执行带KBUILD_VERBOSE=0参数的编译命令时命令的简短信息会被显示。要让定制命令具有这种功能需要设置两个变量: Example: targets += bzImage 执行"make KBUILD_VERBOSE=0"命令编译$(obj)/bzImage目标时将显示: BUILD arch/i386/boot/bzImage --- 6.8 预处理连接脚本 当编译vmlinux映像时将使用arch/$(ARCH)/kernel/vmlinux.lds链接脚本。 $(always)赋值语句告诉编译系统编译目标是vmlinux.lds。$(CPPFLAGS_vmlinux.lds)赋值语句告诉编译系统编译vmlinux.lds目标的编译选项。
顶层Makefile文件导出下面这些变量: VERSION, PATCHLEVEL, SUBLEVEL, EXTRAVERSION 这几个变量定义了当前内核版本号。很少体系体系Makefiles文件直接使用他们,常用$(KERNELRELEASE)代替。 $(VERSION)、$(PATCHLEVEL)和$(SUBLEVEL)定义了三个基本部分版本号,例如"2", "4",和"0"。这三个变量一直使用数值表示。 $(EXTRAVERSION)定义了更细的补钉号,通常是短横跟一些非数值字符串,例如"-pre4"。 KERNELRELEASE ARCH INSTALL_PATH 这个变量定义了体系Makefiles文件安装内核映项和System.map文件的路径。 INSTALL_MOD_PATH, MODLIB $(INSTALL_MOD_PATH)定义了模块安装变量$(MODLIB)的前缀。这个变量通常不在Makefile文件中定义,如果需要可以由用户添加。
内核Makefiles设计目标用于运行GNU Make程序。Makefiles仅使用GNU Make提到的特性,但使用了较多的GNU扩展部分。 GNU Make程序支持基本的列表处理功能。内核Makefiles文件结合"if"语句使用了简单的列表建立和维护功能。 GNU Make程序有两种赋值操作符:":="和"="。 ":="执行时立即计算右值并赋值给左值。"="类似公式定义,当每次使用左值要被使用时计算右值并赋给它。 一些情况中使用"="合适,而一些情况中使用":="才是正确选择。
Original version made by Michael Elizabeth Chastain, <> === 10 TODO - Describe how kbuild support shipped files with _shipped. |