Linux 2.6内核Makefile分析
le会在这个目录下统一生成一个目标文件ext2.o(由obj-$(CONFIG_EXT2_FS)决定)。其中obj-y表示为生成vmlinux文件所需要的目标文件集合,具体的文件依赖于内核配置。
Makefile会编译所有的$(obj-y)中定义的文件,然后调用链接器将这些文件链接到built-in.o文件中。最终built-in.o文件通过顶层Makefile链接到vmlinux中。值得注意的是$(obj-y)的文件顺序很重要。列表文件可以重复,文件第一次出现时将会链接到built-in.o中,后来出现的同名文件将会被忽略。文件顺序直接决定了他们被调用的顺序,这一点读者需要特别注意。
读者可能会在某些Makefile中发现lib-y定义,所有包含在lib-y定义中的目标文件都将会被编译到该目录下一个统一的库文件中。值得注意的是lib-y定义一般被限制在 lib 和arch/$(ARCH)/lib 目录中。
体系makefile文件和顶层makefile文件共同定义了如何建立vmlinux文件的规则。
$(head-y) 列举首先链接到vmlinux的对象文件。
$(libs-y) 列举了能够找到lib.a文件的目录。
其余的变量列举了能够找到内嵌对象文件的目录。
$(init-y) 列举的对象位于$(head-y)对象之后。
然后是如下位置顺序:
$(core-y), $(libs-y), $(drivers-y) 和 $(net-y)。
顶层makefile定义了所有通用目录,arch/$(ARCH)/Makefile文件只需增加体系相关的目录。
例如: #arch/i386/Makefile
libs-y += arch/i386/lib/
core-y += arch/i386/kernel/ \
arch/i386/mm/ \
arch/i386/$(mcore-y)/ \
arch/i386/crypto/
drivers-$(CONFIG_MATH_EMULATION) += arch/i386/math-emu/
drivers-$(CONFIG_PCI) += arch/i386/pci/
…………………………………………
2) 目录递归
Makefile文件只负责当前目录下的目标文件,子目录中的文件由子目录中的makefile负责编译,编译系统使用obj-y 和 obj-m来自动递归编译各个子目录中的文件。
对于fs/Makefile:
obj-$(CONFIG_EXT2_FS) += ext2/
如果在内核配置文件.config中,CONFIG_EXT2_FS被设置为y或者m,则内核makefile会自动进入ext2目录来进行编译。内核Makefile只使用这些信息来决定是否需要编译这个目录,子目录中的makefile规定哪些文件编译为模块,哪些文件编译进内核。
3) 依赖关系
Linux Makefile通过在编译过程中生成的 .文件名.o.cmd(比如对于main.c文件,它对应的依赖文件名为.main.o.cmd)来定义相关的依赖关系。
一般文件的依赖关系由如下部分组成:
Ø 所有的前期依赖文件(包括所有相关的*.c 和 *.h)
Ø 所有与CONFIG_选项相关的文件
Ø 编译目标文件所使用到的命令行
位于init目录下的main.c文件的依赖文件.main.o.cmd内容如下,读者可以结合起来理解上述文件依赖关系的三个组成部分:
cmd_init/main.o := gcc -m32 -Wp,-MD,init/.main.o.d -nostdinc -isystem /usr/lib/gcc-lib/i386-redhat-linux/3.2.2/include -D__KERNEL__ -Iinclude -Iinclude2 -I/home/linux/linux-2.6.17.11/include -include include/linux/autoconf.h -I/home/linux/linux-2.6.17.11/init -Iinit -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -Os -fomit-frame-pointer -pipe -msoft-float -mpreferred-stack-boundary=2 -march=i686 -mcpu=pentium4 -mregparm=3 -ffreestanding -I/home/linux/linux-2.6.17.11/include/asm-i386/mach-default -Iinclude/asm-i386/mach-default -D"KBUILD_STR(s)=\#s" -D"KBUILD_BASENAME=KBUILD_STR(main)" -D"KBUILD_MODNAME=KBUILD_STR(main)" -c -o init/.tmp_main.o /home/linux/linux-2.6.17.11/init/main.c
deps_init/main.o := \
/home/linux/linux-2.6.17.11/init/main.c \
$(wildcard include/config/x86/local/apic.h) \
$(wildcard include/config/acpi.h) \
# 由于篇幅的关系,此处略去一些定义
……………………………………..
include2/asm/mpspec_def.h \
/home/linux/linux-2.6.17.11/include/asm-i386/mach-default/mach_mpspec.h \
include2/asm/io_apic.h \
include2/asm/apic.h \
init/main.o: $(deps_init/main.o)
$(deps_init/main.o):
4) 特殊规则
特殊规则使用在内核编译需要规则定义而没有相应定义的时候。典型的例子如编译时头文件的产生规则。其他例子有体系makefile编译引导映像的特殊规则。特殊规
- (转贴)Makefile解读(04-23)
- Linux内核配置系统详解(05-07)
- Linux下C编程基础之:make工程管理器(08-13)
- GNU ARM汇编--(十七)u-boot的makefile和mkconfig解读(11-26)
- TQ2440国嵌学院gboot-Makefile工程文件(11-26)
- REDIce-Linux--灵活的实时Linux内核(11-12)