-
linux-2.6.30.4/Makefile中,prepare0的依赖执行完之后,执行:
-
make -f scripts/Makefile.build obj=.
-
#执行scripts/Makefile的__build目标,此处只执行always依赖,(KBUILD_BUILTIN=1,但是$(builtin-target) $(lib-target) $(extra-y)都为空,KBUILD_MODULES=0)
-
always=./include/linux/bounds.h ./include/asm/asm-offsets.h
-
__build: ./include/linux/bounds.h ./include/asm/asm-offsets.h
-
:
-
./include/linux/bounds.h 与./include/asm/asm-offsets.h 这两个依赖的处理过程基本相似。
-
下面只分析./include/linux/bounds.h的过程。
-
linux-2.6.30.4/Kbuild
-
11 bounds-file := include/linux/bounds.h
-
-
38 $(obj)/$(bounds-file): kernel/bounds.s Kbuild
-
39 $(Q)mkdir -p $(dir $@)
-
40 $(call cmd,bounds)
-
-
34 kernel/bounds.s: kernel/bounds.c FORCE
-
35 $(Q)mkdir -p $(dir $@)
-
36 $(call if_changed_dep,cc_s_c)
目标include/linux/bounds.h在linux-2.6.30.4/Kbuild中,它的执行流程如下:
1. L34 mkdir -p kernel
2. L36 $(call if_changed_dep, cc_s_c),如果kernel/bounds.c有更新,则重新编译kernel/bounds.c,并将编译命令显示在终端,最后将编译命令写到文件.bounds.s.cmd.o中
3. kernel/bounds.s依赖完成之后,执行include/linux/bounds.h目标
4. L39 mkdir -p include/linux
5. $(call cmd, bounds) ,生成include/linux/bounds.h头文件
下面分析一下第2步: $(call if_changed_dep,cc_s_c)
-
linux-2.6.30.4/scripts/Kbuild.include
-
197 # Execute the command and also postprocess generated .d dependencies file.
-
198 if_changed_dep = $(if $(strip $(any-prereq) $(arg-check) ), \
-
199 @set -e; \
-
200 $(echo-cmd) $(cmd_$(1)); \
-
201 scripts/basic/fixdep $(depfile) $@ '$(make-cmd)' > $(dot-target).tmp;\
-
202 rm -f $(depfile); \
-
203 mv -f $(dot-target).tmp $(dot-target).cmd)
2.1 $(if $(strip $(any-prereq) $(arg-check) ) #如果目标有更新,则执行条件后面的东东
2.2 $(echo-cmd) 打印编译命令
2.3 $(cmd_cc_s_c) 在linux-2.6.30.4/scripts/Makefile.build中定义cmd_cc_s_c = $(CC) $(c_flags) -fverbose-asm -S -o $@ $<,这里面有-S,是将c文件转为.s文件,也就是常说的汇编阶段。
2.4 将kernel/bounds.c的汇编和编译所需的头文件统统写进文件kernel/.bounds.s.d.tmp中
2.5 删除kernel/.bounds.s.d
2.6 将kernel/.bounds.s.d.tmp 重命名为kernel/.bounds.s.d.cmd
2.1.1 突然想起小学时写作文老师说的总分方式:
-
linux-2.6.30.4/scripts/Kbuild.include
-
L189 any-prereq = $(filter-out $(PHONY),$?) $(filter-out $(PHONY) $(wildcard $^),$^)
-
#检查目标代码是否有更新,如果有更新返回值不为空
-
177 arg-check = $(strip $(filter-out $(cmd_$(1)), $(cmd_$@)) \
-
178 $(filter-out $(cmd_$@), $(cmd_$(1))) )
-
#检查参数是否改变,若有改变,返回值不为空
-
2.2.1 $(echo-cmd) 打印编译命令
-
linux-2.6.30.4/scripts/Kbuild.include
-
24 # Escape single quote for use in echo statements
-
25 escsq = $(subst $(squote),'\$(squote)',$1)
-
-
155 # Short version is used, if $(quiet) equals `quiet_', otherwise full one.
-
156 echo-cmd = $(if $($(quiet)cmd_$(1)),\
-
157 echo ' $(call escsq,$($(quiet)cmd_$(1)))$(echo-why)';)
-
linux-2.6.30.4/Makefile控制quiet的值,此处为空,1是指cc_s_c,如果cmd_cc_s_c执行成功,就打印$(cmd_cc_s_c)即具体的编译过程到命令行。
-
这地方有点想不明白,if后面 $(cmd_cc_s_c)要执行一次,$(echo-cmd)执行完后又有一个$(cmd_$(1)),难不成$(cmd_cc_s_c)要执行两次?
-
噢,想错了!下面是GNU `make'对if的说明 “$(if condition,then-part[,else-part]) The first argument, condition, first has all preceding and trailing whitespace stripped, then is expanded. If it expands to any non-empty string, then the condition is considered to be true. If it expands to an empty string, the condition is considered to be false.” 对于第一个参数:condition,首先去掉前面和尾部的空格,然后把条件语句展开。如果展开后是一个不为空的string,那么这个条件就被认为是true,反之是一个空string, 认为是false.
2.3.1
$(cmd_cc_s_c) 即$(CC) $(c_flags) -fverbose-asm -S -o $@ $<,具体的编译过程
2.4.1 scripts/basic/fixdep这个东东在make menuconfig/silentconfig中己经生成,具体是什么作用没有看,感觉是把.c文件需要的include重定向到另一个文件中。
5.1 $(call cmd, bounds)的过程
-
linux-2.6.30.4/scripts/Kbuild.include
-
154 # echo command.
-
155 # Short version is used, if $(quiet) equals `quiet_', otherwise full one.
-
156 echo-cmd = $(if $($(quiet)cmd_$(1)),\
-
157 echo ' $(call escsq,$($(quiet)cmd_$(1)))$(echo-why)';)
-
158
-
159 # printing commands
-
160 cmd = @$(echo-cmd) $(cmd_$(1))
cmd = @$(echo-cmd) $(cmd_$(1))
先是打印命令这个,然后执行$(cmd_bounds)
-
linux-2.6.30.4/Kbuild
-
17 define cmd_bounds
-
18 (set -e; \
-
19 echo "#ifndef __LINUX_BOUNDS_H__"; \
-
20 echo "#define __LINUX_BOUNDS_H__"; \
-
21 echo "/*"; \
-
22 echo " * DO NOT MODIFY."; \
-
23 echo " *"; \
-
24 echo " * This file was generated by Kbuild"; \
-
25 echo " *"; \
-
26 echo " */"; \
-
27 echo ""; \
-
28 sed -ne $(sed-y) $<; \
-
29 echo ""; \
-
30 echo "#endif" ) > $@
-
31 endef
$@ 是 include/linux/bounds.h
$< 是 kernel/bounds.s
这个宏简单一点就是: echo "something" > include/linux/bounds.h,将一些文本写入到include/linux/bounds.h中
-
linux-2.6.30.4/Kbuild
-
54 define sed-y
-
55 "/^->/{s:->#\(.*\):/* \1 */:; \
-
56 s:^->\([^ ]*\) [\$$#]*\([^ ]*\) \(.*\):#define \1 \2 /* \3 */:; \
-
57 s:->::; p;}"
-
58 endef
sed将kernel/bounds.s中以->开头的行进行处理,将行
->NR_PAGEFLAGS #21 __NR_PAGEFLAGS @ 替换为
#define NR_PAGEFLAGS 21 /* __NR_PAGEFLAGS @ */
阅读(3411) | 评论(0) | 转发(0) |