1. Makefile到底做了什么
之前看了网上许多牛人写的关于Makefile的解析的文章,在这里,我也结合我个人的理解,去分析U-Boot的Makefile。
首先,我们大致了解一下,Makefile到底做了些什么工作?其实,顶层Makefile的主要任务就是组织整个U-Boot工程的编译,概括可以分为以下几个步骤:
- 首先通过执行make *_config传入$(@:_config=), ARCH, CPU, BOARD, VENDOR, SOC参数(一共六个参数但不一定同时存在),给mkconfig。
- mkconfig接收到传递过来的参数后,将include头文件夹相应的头文件夹链接好,生成config.h
- 然后执行make分别调用各个子目录的makefile文件,以生成所有的obj文件(包括start.o)和obj库文件*.a。
- 最后,通过链接器把所有目标文件链接起来,生成uboot镜像。不同格式的镜像都是调用相应工具,经由elf镜像间接或者直接的生成的。
2. Makefile分析
接下来我们具体分析这些代码。规定说明:Makefile文件的代码用黑色,文件原注释用橄榄色,作者注释用浅蓝色。
VERSION = 1
PATCHLEVEL = 1
SUBLEVEL = 6
EXTRAVERSION =
U_BOOT_VERSION = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
VERSION_FILE = $(obj)include/version_autogenerated.h
#以上是预先定义一些变量,则U_BOOT_VERSION=1.1.6,VERSION_FILE表示版本文件。
HOSTARCH := $(shell uname -m | \
sed -e s/i.86/i386/ \ //将i.86替换成i386,以下类似
-e s/sun4u/sparc64/ \
-e s/arm.*/arm/ \
-e s/sa110/arm/ \
-e s/powerpc/ppc/ \
-e s/macppc/ppc/)
# uname 将正在使用的操作系统名写到标准输出中,-m显示硬件运行系统的机器 ID 号。
#sed 是一种在线编辑器,它一次处理一行内容。
#比如本人的电脑使用Intel Core2系列的CPU,因此“uname –m”输出“i686”。 “i686”可以匹配命令“sed -e s/i.86/i386/”中的“i.86”,因此在作者的机器上
#执行Makefile,HOSTARCH将被设置成“i386” 。
HOSTOS := $(shell uname -s | tr '[:upper:]' '[:lower:]' | \
sed -e 's/\(cygwin\).*/cygwin/')
export HOSTARCH HOSTOS
#“uname –s”输出主机内核名字,作者使用Linux发行版Ubuntu9.10,因此“uname –s”结果是“Linux”。“tr '[:upper:]' '[:lower:]'”作用是将标准输入中的所有大写字母转换为响应的小写字母。因此执行结果是将HOSTOS 设置为“linux”。
# Deal with colliding definitions from tcsh etc.
VENDOR= #表示开发商
#########################################################################
#此段注释比较重要,因此翻译出来。
# U-boot 的编译过程可以支持向一个自己定义的路径生成最终的目标文件。这里提供两种方法:
# U-boot build supports producing a object files to the separate external directory. Two use cases are supported:
# 第一种用法:通过在终端执行命令make O=/dir(即你指定的生成的目标文件的存放目录)
# 1) Add O= to the make command line
# 'make O=/tmp/build all'
#第二种用法:通过设置环境变量来指定目标文件存放目录,如下举例所示:
# 2) Set environement variable BUILD_DIR to point to the desired location
# 'export BUILD_DIR=/tmp/build'
# 'make'
#
#第二种方法也可以写成MAKEALL脚本,然后执行MAKEALL,如下:
# The second approach can also be used with a MAKEALL script
# 'export BUILD_DIR=/tmp/build'
# './MAKEALL'
#
#命令行'O='设置会覆盖环境变量BUILD_DIR的设置
# Command line 'O=' setting overrides BUILD_DIR environent variable.
#
#如果都不采用上面两种方法,那么目标文件放到源码顶层目录,也就是U-BOOT顶层目录
# When none of the above methods is used the local build is performed and
# the object files are placed in the source directory.
#
<由于工作忙,待续>