|
Makefile 对应内核版本: 2.6.35.13
在编译内核时,会经常调用 scripts/Makefile.build 文件,如果其后不指定具体目标时,默认就处理它里面的 __build 这个目标:
[code=Makefile]__build: $(if $(KBUILD_BUILTIN),$(builtin-target) $(lib-target) $(extra-y)) \
$(if $(KBUILD_MODULES),$(obj-m) $(modorder-target)) \
$(subdir-ym) $(always)
@:[/mw_shl_code]
该目标没有什么实际命令,只有一个空命令 @; ,它表示如果 __build 的依赖都能够无错更新,那么就能执行到该命令,表示没有出什么错误。
在 __build 的依赖中,看到 $(lib-target) 变量,该变量和一大堆的库目标相关。这里先需要注意 $(KBUILD_BUILTIN) 变量,只有处理与基本内核相关的编译时 ,该变量的值会为 1,这样才会去处理 $(lib-target) 的内容。如果是 x86 平台,那么当处理顶层 Makefile 的 vmlinux-dirs 时我们会看到两个和库相关的目录:也就是说,当执行 vmlinux-dirs 底下的 make -f scripts/Makefile.build obj=$@ 命令时会分别包含 lib/ 和 arch/xi6/lib 这两个目录下的 Makefile 文件。
在 scripts/Makefile.build 里有 lib-target 相关的定义:
[code=Makefile]ifneq ($(strip $(lib-y) $(lib-m) $(lib-n) $(lib-)),)
lib-target := $(obj)/lib.a
endif
... ...
#
# Rule to compile a set of .o files into one .a file
#
ifdef lib-target
quiet_cmd_link_l_target = AR $@
cmd_link_l_target = rm -f $@; $(AR) rcs $@ $(lib-y)
$(lib-target): $(lib-y) FORCE
$(call if_changed,link_l_target)
targets += $(lib-target)
endif[/mw_shl_code]
由上可见,lib-target 最终会生成 lib.a 文件,如:[beyes@beyes linux-2.6.35.13]$ ls arch/x86/lib/lib.a
arch/x86/lib/lib.a
[beyes@beyes linux-2.6.35.13]$ ls lib/lib.a
lib/lib.a
在 lib/ 或 arch/x86/lib/ 下的 Makefile 中对 lib-y 等变量都有赋值。实际上,在 x86 上,$(lib-m) 这个变量为空;而 $(lib-) 指代的是和 CPU 指令集或架构相关的库,默认编译的情况下,在 x86 上对应 $(lib-) 变量的会有下面两个这样的目标文件:rwsem-spinlock.o
mmx_32.o 在 arch/x86/lib/Makefile 中看到:lib-$(CONFIG_X86_USE_3DNOW) += mmx_32.o 如果你用的是 intel 系列处理器,那么就不会又 3DNOW! 指令集 --- 该指令集为 AMD 系列 CPU 所有,所以这里 $(CONFIG_X86_USE_3DNOW) 变量为空,也就是会产生 $(lib-) 这样的变量。
在 lib/Makefile 里看到:lib-$(CONFIG_RWSEM_GENERIC_SPINLOCK) += rwsem-spinlock.o 这里 $(CONFIG_RWSEM_GENERIC_SPINLOCK) 变量同样为空。
在 scripts/Makefile.build 中包含了 Makefile.lib 文件:include scripts/Makefile.lib 在该文件中也有对 lib-y 变量的处理:
[code=Makefile]
# Libraries are always collected in one lib file.
# Filter out objects already built-in
lib-y := $(filter-out $(obj-y), $(sort $(lib-y) $(lib-m)))
... ...
lib-y := $(addprefix $(obj)/,$(lib-y))[/mw_shl_code]
上面注释中也已说明,所有的库总是链接成一个库文件,我们会过滤掉在 built-in 中已经定义了的文件 --- $(filter-out $(obj-y), $(sort $(lib-y) $(lib-m))) 这条语句就是将 $(lib-y) 和 $(obj-y) 中重复定义了的文件滤除掉。最后,将这些库文件添加了路径前缀。
在生成 lib.a 文件时使用了 if_changed 规则,使用该规则,最后会执行 rm -f $@; $(AR) rcs $@ $(lib-y) 命令。rm 命令将之前旧的 lib.a 删除;最后用 ar 命令对这些库目标文件进行归档,使它们链接成 lib.a 文件。 |
|