- 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.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.4.1 scripts/basic/fixdep这个东东在make menuconfig/silentconfig中己经生成,具体是什么作用没有看,感觉是把.c文件需要的include重定向到另一个文件中。
cmd= @$(echo-cmd) $(cmd_$(1))
$@ 是 include/linux/bounds.h
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_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
$< 是
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
->NR_PAGEFLAGS #21 __NR_PAGEFLAGS @ 替换为
#define NR_PAGEFLAGS 21 /* __NR_PAGEFLAGS @ */