主Makefile一上来先是一个版本号相关的内容:U_BOOT_VERSION这个变量的内容由4部分构成,它们分别是VERSION,PATHLEVEL,SUBLEVEL,EXTRAVERSION。uboot用赋值来构成最终的版本号,1.3.4,由于EXTRAVERSION为空,所以缺省就是1.3.4。
在uboot中接下来的一行中自动生成了一个文件version_autogenerated.h。它位于include/version_autogenerated.h,该文件在源码目录中没有,但是在编译过后的uboot中就有了。他的内容是一个宏定义,宏定义的值就是我们在Makefile中配置的版本号。如图:
分析完U_BOOT_VERSION之后,我们再来接着看下面的Makefile,它又定义了2个变量:HOSTARCH和HOSTOS。它们的值分别是通过这样定义的:
HOSTARCH := $(shell uname -m | \
sed -e s/i.86/i386/ \
-e s/sun4u/sparc64/ \
-e s/arm.*/arm/ \
-e s/sa110/arm/ \
-e s/powerpc/ppc/ \
-e s/ppc64/ppc/ \
-e s/macppc/ppc/)
HOSTOS := $(shell uname -s | tr '[:upper:]' '[:lower:]' | \
sed -e 's/\(cygwin\).*/cygwin/')
export HOSTARCH HOSTOS
(1)其中shell xxx表示执行shell的xxx命令,uname -m表示获得当前的CPU的架构信息,这个是获得当前执行这个命令的电脑的CPU的版本号。单独在ubuntu下执行uname -m得到的是i686。
(2)shell中的 | 表示管道,意思是说把前面表达式的输出作为后面一个表达式的输入。
(3)
sed -e s/i.86/i386/这句话的意思是查找字符串i.86,查到后替换为i386,结合上一句的管道就是把i686输出作为输入,然后替换为i386,所以经过这样一段执行后得到的HOSTARCH就是i386。
(4)HOSTOS的得来是通过uname -s,单独在shell中执行得到当前的操作系统,linux.
得到这2个这两个环境变量是主机的操作系统和主机的CPU架构,得出后保存备用,后面自然会用到。
#########################################################################
# Allow for silent builds
ifeq (,$(findstring s,$(MAKEFLAGS)))
XECHO = echo
else
XECHO = :
endif
#########################################################################
静默编译:
在Makefile的第49-54行。平时默认编译时命令行会打印出来很多编译信息,但有时候我们不想看到这些信息,就后台编译即可,这就叫静默编译。
我们可以在编译时加上参数来实现静默编译,如:make -s ,-s会作为
MAKEFLAGS传给Makefile,这时XECHO就等于空,上面这段代码的意思是在MAKEFLAGS里面查找s,并拿结果和空做比较,如果相等则XECHO等于echo,如果找到了就和空不相等则XECHO就等于空,于是乎实现了静默编译。
ifdef O
ifeq ("$(origin O)", "command line")
BUILD_DIR := $(O)
endif
endif
ifneq ($(BUILD_DIR),)
saved-output := $(BUILD_DIR)
# Attempt to create a output directory.
$(shell [ -d ${BUILD_DIR} ] || mkdir -p ${BUILD_DIR})
# Verify if it was successful.
BUILD_DIR := $(shell cd $(BUILD_DIR) && /bin/pwd)
$(if $(BUILD_DIR),,$(error output directory "$(saved-output)" does not exist))
endif # ifneq ($(BUILD_DIR),)
OBJTREE := $(if $(BUILD_DIR),$(BUILD_DIR),$(CURDIR))
SRCTREE := $(CURDIR)
TOPDIR := $(SRCTREE)
LNDIR := $(OBJTREE)
export TOPDIR SRCTREE OBJTREE
MKCONFIG := $(SRCTREE)/mkconfig
export MKCONFIG
ifneq ($(OBJTREE),$(SRCTREE))
REMOTE_BUILD := 1
export REMOTE_BUILD
endif
# $(obj) and (src) are defined in config.mk but here in main Makefile
# we also need them before config.mk is included which is the case for
# some targets like unconfig, clean, clobber, distclean, etc.
ifneq ($(OBJTREE),$(SRCTREE))
obj := $(OBJTREE)/
src := $(SRCTREE)/
else
obj :=
src :=
endif
export obj src
# Make sure CDPATH settings don't interfere
unexport CDPATH
在分析上面代码之前我们先来了解下Uboot的编译方法,目前uboot支持2种编译方式,一种是原地编译,一种是单独输出到指定文件夹的编译。默认是原地编译。
原地编译就是当前文件夹下的.c文件编译出来的.o文件放在一个文件夹下,处理起来比较简单;
单独输出文件夹编译就是编译时另外指定一个输出目录,将来所有编译生成的.o文件全部丢到指定的文件夹下。
具体做法就是在编译时通过指定选项来完成,比如:
第一种:make O=输出目录
第二种:export BUILD_DIR=输出目录,然后再make。
如果以上2中都指定了,则make O=输出目录具有更高的优先级。
阅读(1868) | 评论(0) | 转发(0) |