Chinaunix首页 | 论坛 | 博客
  • 博客访问: 737555
  • 博文数量: 124
  • 博客积分: 3156
  • 博客等级: 中校
  • 技术积分: 1584
  • 用 户 组: 普通用户
  • 注册时间: 2008-08-02 10:29
文章分类

全部博文(124)

文章存档

2012年(3)

2011年(2)

2010年(61)

2009年(34)

2008年(24)

我的朋友

分类: LINUX

2010-09-02 10:49:56

http://blog.chinaunix.net/u2/72383/showart_1083225.html
分析了一下u-boot1.3.2的Makefile,基本的结构如下:
    主目录下有一个Makefile,一个config.mk,一个mkconfig脚本。
   (一) 首先用户需要make smdk2410_config,这样Makefile会掉用mkconfig脚本生成include/config.mk这里面包含了 ARCH,BOARD,CPU,SOC等变量,这些变量可以供其它的makefile使用,作为一个基本配置.
    如果还没有掉用make smdk2410_config,那么include/config.mk是不存在的,这样当make all的时候,会出错,因为Makefile里会依据该文件是否存在给all目标提供不同的规则和命令,当存在include/config.mk时,是 一些正常的规则,当不存在的时候,是出错提示。
    mkconfig脚本的作用不仅仅是生成include/config.mk文件,他还依据用户是否指定目标文件夹来创建目录,将生成的文件放到非源码的目录。此外还生成一个include/config.h文件,这个文件很简单,只有一句话:
    #include <$1.h> 当然这里的$1时要被替换成不同的board名字的.这个取决于我们在主Makefile中xxxx_config目标中的xxxx是什么. 这里可以以smdk2410.h为例子.
    (二)在源码目录(而非include)还有一个自带的config.mk,
一般每个子目录中 的Makefile都要包含这个config.mk,因为这个config.mk里面定义了一些变量,这些变量对这些子目录的Makefile是有意义 的,如$obj, $src等都定义了子目录的目标文件和源码路径,这些是依据CURDIR变量来推算的,因为子目录一般都是由父目录掉用make -C过来的,当进入子目录开始make后,CURDIR自动就成为了当前的working dir,因此就可以推算出当前子目录的路径。当然这个config.mk还有别的内容.包括:
    将不同CPU,BOARD目录下的原有的config.mk包含进来。
    还有一个很重要的内容:
    CPPFLAGS += -DTEXT_BASE=$(TEXT_BASE) 
    这个定义就制定了在编译的时候告诉编译器生成的代码的基地址是TEXT_BASE,参看u-boot的relocation部分的资料。当然在连接的时候也需要指定这个值。即在连接参数里指定TEXT_BASE:
    LDFLAGS += -Ttext $(TEXT_BASE)
    此外,还指定了连接脚本 -T $(LDSCRIPT)
    最后这个文件中包含一些规则,将.S转换成.s的规则。由.S生成.o,由.c生成.o
    (三)include/autoconf.mk的作用.
    它依赖于include/config.h文件,因此要首先make xxxx_config,以生成include/config.h。此外由于include/autoconf.mk的生成是通过将include /common.h中的带CONFIG_的宏筛选出来得到的,此外还生成了一个依赖文件,且这个依赖文件也是依据common.h生成的,这个依赖的目标 就是include/autoconf.mk,其第一个prerequsite就是include/common.h。而,common.h中 include了config.h,这样可知include/autoconf.mk实际上依赖于config.h以及common.h中的依赖。
下面是Makefie中的一段节选:

# Auto-generate the autoconf.mk file (which is included by all makefiles)
# 因为autoconf.mk中包含了用户自己定义在common.h中的一些宏
# This target actually generates 2 files; autoconf.mk and autoconf.mk.dep.
# the dep file is only include in this top level makefile to determine when
# to regenerate the autoconf.mk file. 之所以说可以告诉我们when to regenerate
# the autoconf.mk file,是因为在autoconf.mk文件中包含autoconf.mk: common.h
# 这样的依赖,一旦common.h改变了,autoconf.mk就的改变

# -M的意思是说生成dependency文件.
# -MQ是用来指定生成的dependency文件中的target是什么,如不指定,模认为xxxx.o
# 即 gcc -M inlcude/common.h >$@.dep 生成的结果为:
# include/common.o : ... 即自动以.o为target,这不是我们想要的,我们想要
# autoconfig.mk作为target,因此要-MQ来手动指定,而且,include/common.h会自动
# 作为一个prequisite.
# 结果,common.h的依赖的所有的文件,包括common.h都被写入include/autoconf.mk.dep
# 文件。这样include/autoconf.mk依赖于common.h以及common.h中的一些依赖,而接下来
# 的一些要被编译的target有全都依赖于include/autoconf.mk,因此,一旦common.h有所
# 修改,全部都的重新编译.
# $(CPP) -dM file 会将file中使用的宏全部输出到标准输出.并且将预处理器的预定义
# 宏也输出了. 因此这里有了一个查看于处理器自定义的宏的方法:
# touch foo.h; cpp -dM foo.h,因为foo.h是个空文件,因此输出的都是预定义宏.
# sed -n是quiet模式,sed使用tools/define2mk.sed脚本来处理输出的宏.将宏处理成
# 了一种适合make处理的autoconf的格式.而且只提取出了common.h中的#define CONFIG_XXX模式的宏,即用户在common.h中自己定义的宏.
$(obj)include/autoconf.mk: $(obj)include/config.h $(VERSION_FILE)
    @$(XECHO) Generating include/autoconf.mk ; \
    set -e ; \
    : Generate the dependancies ; \
    $(CC) -M $(HOST_CFLAGS) $(CPPFLAGS) -MQ $@ include/common.h > $@.dep ; \
    : Extract the config macros ; \
    $(CPP) $(CFLAGS) -dM include/common.h | sed -n -f tools/scripts/define2mk.sed > $@
# 将由common.h生成的依赖规则包含进来,sinclude,就算没有该文件,也不会出错.
sinclude $(obj)include/autoconf.mk.dep

    其它的规则总将include/autoconf.mk作为一个prerequsite,这样一旦common.h或者config.h等有更新,整个工程都得重新生成.

(四)rules.mk的使用
    在规则中,看到很多_depend,这个东西,其实是定义在rules.mk里面的,在各个makefile里面,包含了这个rules.mk,因此可以 通过make -C subdir _depend命令来生成位于各个subdir下的dependency文件,然后生成的文件有被包含进来。

    这个u-boot的makefile里面还包含了许多有趣的命令,可以学习一下。
阅读(1488) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~