Kbuild和Makefile(4)

2019-03-28 11:11

KBUILD系统原理分析

当执行 \时,\这两个文件将被删除。如果不使用绝对路径(路径以'/'开头)的话,Kbuild假设所要删除的文件与Makefile在同一个相对路径上。

要删除一目录:

#scripts/package/Makefile clean-dirs := $(objtree)/debian/

这就会删除目录 debian,包括其所有的子目录。如果不使用绝对路径(路径以'/'开头)的话,Kbuild假设所要删除的目录与Makefile在同一个相对路径上。

一般情况下,Kbuild会根据 \递归访问其子目录,但有的时候,Kbuild架构还不足以描述所有的情况时,还要显式的指明所要访问的子目录。例子:

#arch/i386/boot/Makefile subdir- := compressed/

上面的赋值命令告诉Kbuild,当执行\时,要递归访问目录 compressed/。 为了支持在最终编译完成启动镜像后的架构清理工作,还有一可选的目标 archclean: #arch/i386/Makefile archclean:

$(Q)$(MAKE) $(clean)=arch/i386/boot

当\执行时,make会递归访问并清理 arch/i386/boot。在 arch/i386/boot中的Makefile可以用来提示make进行下一步的递归操作。

注意1:arch/$(ARCH)/Makefile 不能使用\,因为该Makefile被包含在顶层的Makefile中,Kbuild是不会在此处进行操作的。

注意2:\会访问在 core-y,libs-y,drivers-y 和 net-y 列出的所有目录。

2.5架构Makefile

在递归访问目录之前,顶层Makefile要完成设置环境变量以及递归访问的准备工作。顶层Makefile包含的公共部分,而 arch/$(ARCH)/Makefile 包含着针对某一特定架构的配置信息。所以,要在arch/$(ARCH)/Makefile 中设置一部分变量,并定义一些目标。

Kbuild执行的几个步骤(大致):

1) 根据内核配置生成文件 .config

2) 将内核的版本号存储在 include/linux/version.h 3) 生成指向 include/asm-$(ARCH) 的符号链接

4) 更新所有编译所需的文件: 附加的文件由 arch/$(ARCH)/Makefile 指定。

5) 递归向下访问所有在下列变量中列出的目录: init-* core* drivers-* net-* libs-*,并编译生成目标文件。这些变量的值可以在 arch/$(ARCH)/Makefile 中扩充。

6) 联接所有的目标文件,在源代码树顶层目录中生成 vmlinux。最先联接是在 head-y中列出的文件,该变量由 arch/$(ARCH)/Makefile 赋值。 7) 最后完成具体架构的特殊要求,并生成最终的启动镜像。 -- 包含生成启动指令 16

KBUILD系统原理分析

-- 准备 initrd 镜像或类似文件

2.5.1 调整针对某一具体架构生成的镜像

LDFLAGS 一般是 $(LD) 选项 该选项在每次调用联接器时都会用到。 一般情况下,只用来指明模拟器。例子: #arch/s390/Makefile LDFLAGS := -m elf_s390

注意:EXTRA_LDFLAGS 和 LDFLAGS_$@ 可用来进一步自定义选项。

LDFLAGS_MODULE 联接模块时的联接器的选项

LDFLAGS_MODULE 所设置的选项将在联接器在联接模块文件 .ko 时使用。默认值为 \,指定输出文件是可重定位的。

LDFLAGS_vmlinux 联接vmlinux时的选项

LDFLAGS_vmlinux用来传递联接vmlinux时的联接器的选项。 LDFLAGS_vmlinux需 LDFLAGS_$@ 支持。例子: #arch/i386/Makefile

LDFLAGS_vmlinux := -e stext

OBJCOPYFLAGS objcopy 选项

当用 $(call if_changed,objcopy) 来转换(translate)一个.o文件时,该选项就会被使用。 $(call if_changed,objcopy) 经常被用来为vmlinux生成原始的二进制代码。例子: #arch/s390/Makefile OBJCOPYFLAGS := -O binary #arch/s390/boot/Makefile $(obj)/image: vmlinux FORCE $(call if_changed,objcopy)

在此例中,二进制文件 $(obj)/image 是 vmlinux 的一个二进制版本。 $(call if_chagned,xxx)的用法稍后描述。

AFLAGS $(AS) 汇编编译器选项 默认值在顶层Makefile

扩充或修改在各具体架构的Makefile,例子: #arch/sparc64/Makefile

AFLAGS += -m64 -mcpu=ultrasparc

CFLAGS $(CC) 编译器选项 默认值在顶层Makefile

17

KBUILD系统原理分析

扩充或修改在各具体架构的Makefile。 一般,CFLAGS要根据内核配置设置。例子: #arch/i386/Makefile

cflags-$(CONFIG_M386) += -march=i386 CFLAGS += $(cflags-y)

许多架构Makefile都通过调用所要使用的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) ...

第一个例子利用了一个配置选项,当其为'y'时,扩展。 CFLAGS_KERNEL : #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) ...

第一个例子利用了一个配置选项,当其为'y'时,扩展。

CFLAGS_KERNEL 编译进内核时,$(CC) 所用的选项

$(CFLAGS_KERNEL) 包含了用于编译常驻内核代码的附加编译器选项。

CFLAGS_MODULE 编译成模块时,$(CC)所用的选项

$(CFLAGS_MODULE) 包含了用于编译可装载模块的附加编译器选项。

2.5.2 将所需文件加到 archprepare 中:

archprepare规则在递归访问子目录之前,列出编译目标文件所需文件。 一般情况下,这是一个包含汇编常量的头文件。(assembler constants) 例子:

#arch/arm/Makefile archprepare: maketools

此例中,目标文件 maketools 将在递归访问子目录之前编译。在TODO一章可以看到,Kbuild

18

KBUILD系统原理分析

是如何支持生成分支头文件的。(offset header files)

2.5.3 递归下向时要访问的目录列表

如何生成 vmlinux,是由架构makefile和顶层Makefile一起来定义的。注意,架构Makefile是不会定义与模块相关的内容的,所有构建模块的定义是与架构无关的。

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)和$(net-y)。

顶层makefile定义了通用的部分,arch/$(ARCH)/Makefile 添加了架构的特殊要求。 例子:

#arch/sparc64/Makefile core-y += arch/sparc64/kernel/

libs-y += arch/sparc64/prom/ arch/sparc64/lib/

drivers-$(CONFIG_OPROFILE) += arch/sparc64/oprofile/

2.5.4 具体架构的启动镜像

一具体架构Makefile的具体目的就是,将生成并压缩 vmlinux 文件,写入启动代码,并将其拷贝到正确的位置。这就包含了多种不同的安装命令。该具体目的也无法在各个平台间进行标准化。

一般,附加的处理命令入在 arch/$(ARCH)/下的boot目录。

Kbuild并没有为构造boot所指定的目标提供任何更好的方法。所以,arch/$(ARCH)/Makefile 将会调用 make 以手工构造 boot的目标文件。

比较好的方法是,在 arch/$(ARCH)/Makefile 中包含快捷方式,并在arch/$(ARCH)/boot/Makefile 中使用全部路径。例子:

#arch/i386/Makefile boot := arch/i386/boot bzImage: vmlinux

$(Q)$(MAKE) $(build)=$(boot) $(boot)/$@

当在子目录中调用 make 时,推荐使用 \。 并没有对架构特殊目标的命名规则,但用命令 \可以列出所有的相关目标。 为了支持 \,$(archhelp) 必须被定义。例子: #arch/i386/Makefile define archhelp

echo '* bzImage - Image (arch/$(ARCH)/boot/bzImage)' endef

19

KBUILD系统原理分析

当make 没带参数执行时,所遇到的第一个目标将被执行。在顶层,第一个目标就是 all: 每个架构Makefile都要默认构造一可启动的镜像文件。 在 \中,默认目标就是被加亮的'*'。

添加一新的前提文件到 all:,就可以构造出一不同的vmlinux。例子: #arch/i386/Makefile all: bzImage

当 make 没有参数时,bzImage将被构造。

2.5.5 构造非Kbuild目标

extra-y

extra-y 列出了在当前目录下,所要创建的附加文件,不包含任何已包含在obj-* 中的文件。 用 extra-y 列目标,主要是两个目的: 1) 可以使Kbuild检查命令行是否发生变化

使用 $(call if_changed,xxx) 的时候

2) 让Kbuild知道哪些文件要在 \时删除 例子:

#arch/i386/kernel/Makefile extra-y := head.o init_task.o

在此例子中,extra-y用来列出所有只编译,但不联接到 built-in.o的目标文件。

2.5.6 构建启动镜像的命令

Kbuild 提供了几个用在构建启动镜像时的宏。

if_changed

if_changed 为下列命令的基础。使用方法: target: source(s) FORCE

$(call if_changed,ld/objcopy/gzip)

当执行该规则时,就检查是否有文件需要更新,或者在上次调用以后,命令行发生了改变。如果有选项发生了改变,后者会导致重新构造。只有在 $(targets)列出的的目标文件,才能使用 if_changed,否则命令行的检查会失败,并且目标总会被重建。给 $(targets)的赋值没有前缀 $(obj)/ 。 if_changed 可用来联接自定义的Kbuild命令,关于Kbuild自定义命令请看 6.7节。

注意:忘记 FORCE 是一种典型的错误。还有一种普遍的错误是,空格有的时候是有意义的;比如。下面的命令就会错误(注意在逗号后面的那个多余的空格):

target: source(s) FORCE

#WRONG!# $(call if_changed, ld/objcopy/gzip)

ld 联接目标

经常是使用LDFLAGS_$@来设置ld的特殊选项。

20


Kbuild和Makefile(4).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:数字图像处理技术的研究现状及其发展方向

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: