Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2150804
  • 博文数量: 438
  • 博客积分: 3871
  • 博客等级: 中校
  • 技术积分: 6075
  • 用 户 组: 普通用户
  • 注册时间: 2011-09-10 00:11
个人简介

邮箱: wangcong02345@163.com

文章分类

全部博文(438)

文章存档

2017年(15)

2016年(119)

2015年(91)

2014年(62)

2013年(56)

2012年(79)

2011年(16)

分类: LINUX

2012-05-04 17:08:23

  1. linux-2.6.30.4/Makefile中,prepare0的依赖执行完之后,执行:
  2.    make -f scripts/Makefile.build obj=.
  3. #执行scripts/Makefile的__build目标,此处只执行always依赖,(KBUILD_BUILTIN=1,但是$(builtin-target) $(lib-target) $(extra-y)都为空,KBUILD_MODULES=0)
  4. always=./include/linux/bounds.h ./include/asm/asm-offsets.h 
  5. __build: ./include/linux/bounds.h ./include/asm/asm-offsets.h 
  6.     :
  7. ./include/linux/bounds.h 与./include/asm/asm-offsets.h 这两个依赖的处理过程基本相似。
  8. 下面只分析./include/linux/bounds.h的过程。

点击(此处)折叠或打开

  1. linux-2.6.30.4/Kbuild
  2.  11 bounds-file := include/linux/bounds.h

  3.  38 $(obj)/$(bounds-file): kernel/bounds.s Kbuild
  4.  39 $(Q)mkdir -p $(dir $@)
  5.  40 $(call cmd,bounds)

  6.  34 kernel/bounds.s: kernel/bounds.c FORCE
  7.  35 $(Q)mkdir -p $(dir $@)
  8.  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)

点击(此处)折叠或打开

  1. linux-2.6.30.4/scripts/Kbuild.include
  2. 197 # Execute the command and also postprocess generated .d dependencies file.
  3. 198 if_changed_dep = $(if $(strip $(any-prereq) $(arg-check) ), \
  4. 199 @set -e; \
  5. 200 $(echo-cmd) $(cmd_$(1)); \
  6. 201 scripts/basic/fixdep $(depfile) $@ '$(make-cmd)' > $(dot-target).tmp;\
  7. 202 rm -f $(depfile); \
  8. 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 突然想起小学时写作文老师说的总分方式:

点击(此处)折叠或打开

  1. linux-2.6.30.4/scripts/Kbuild.include
  2. L189 any-prereq = $(filter-out $(PHONY),$?) $(filter-out $(PHONY) $(wildcard $^),$^)
  3.      #检查目标代码是否有更新,如果有更新返回值不为空
  4. 177 arg-check = $(strip $(filter-out $(cmd_$(1)), $(cmd_$@)) \
  5. 178 $(filter-out $(cmd_$@), $(cmd_$(1))) )
  6.     #检查参数是否改变,若有改变,返回值不为空

2.2.1 $(echo-cmd) 打印编译命令

点击(此处)折叠或打开

  1. linux-2.6.30.4/scripts/Kbuild.include
  2.   24 # Escape single quote for use in echo statements
  3.   25 escsq = $(subst $(squote),'\$(squote)',$1)

  4. 155 # Short version is used, if $(quiet) equals `quiet_', otherwise full one.
  5. 156 echo-cmd = $(if $($(quiet)cmd_$(1)),\
  6. 157     echo '  $(call escsq,$($(quiet)cmd_$(1)))$(echo-why)';)
  7. linux-2.6.30.4/Makefile控制quiet的值,此处为空,1是指cc_s_c,如果cmd_cc_s_c执行成功,就打印$(cmd_cc_s_c)即具体的编译过程到命令行。
  8. 这地方有点想不明白,if后面 $(cmd_cc_s_c)要执行一次,$(echo-cmd)执行完后又有一个$(cmd_$(1)),难不成$(cmd_cc_s_c)要执行两次?
  9. 噢,想错了!下面是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)的过程

点击(此处)折叠或打开

  1. linux-2.6.30.4/scripts/Kbuild.include
  2. 154 # echo command.
  3. 155 # Short version is used, if $(quiet) equals `quiet_', otherwise full one.
  4. 156 echo-cmd = $(if $($(quiet)cmd_$(1)),\
  5. 157 echo ' $(call escsq,$($(quiet)cmd_$(1)))$(echo-why)';)
  6. 158
  7. 159 # printing commands
  8. 160 cmd = @$(echo-cmd) $(cmd_$(1))
cmd = @$(echo-cmd) $(cmd_$(1))
先是打印命令这个,然后执行$(cmd_bounds)

点击(此处)折叠或打开

  1.  linux-2.6.30.4/Kbuild 
  2.  17 define cmd_bounds
  3.  18 (set -e; \
  4.  19 echo "#ifndef __LINUX_BOUNDS_H__"; \
  5.  20 echo "#define __LINUX_BOUNDS_H__"; \
  6.  21 echo "/*"; \
  7.  22 echo " * DO NOT MODIFY."; \
  8.  23 echo " *"; \
  9.  24 echo " * This file was generated by Kbuild"; \
  10.  25 echo " *"; \
  11.  26 echo " */"; \
  12.  27 echo ""; \
  13.  28 sed -ne $(sed-y) $<; \
  14.  29 echo ""; \
  15.  30 echo "#endif" ) > $@
  16.  31 endef
$@ 是 include/linux/bounds.h
$< 是 kernel/bounds.
这个宏简单一点就是: echo "something" > include/linux/bounds.h,将一些文本写入到include/linux/bounds.h中

点击(此处)折叠或打开

  1. linux-2.6.30.4/Kbuild 
  2.  54 define sed-y
  3.  55 "/^->/{s:->#\(.*\):/* \1 */:; \
  4.  56 s:^->\([^ ]*\) [\$$#]*\([^ ]*\) \(.*\):#define \1 \2 /* \3 */:; \
  5.  57 s:->::; p;}"
  6.  58 endef
 sed将kernel/bounds.s中以->开头的行进行处理,将行
->NR_PAGEFLAGS #21 __NR_PAGEFLAGS   @           替换为
#define NR_PAGEFLAGS 21 /* __NR_PAGEFLAGS   @ */
阅读(3411) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~