1.uboot源码文件的功能
使用make xxx_deconfig命令即可配置uboot
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- mx6ull_14x14_ddr512_emmc_
defconfig
2.MAKEFLAGS变量
make是支持递归调用的,其实是在Makefile中使用make命令来执行其他的Makefiel文件,一般都是子目录中的makefile文件。
假如在当前目录下存在一个“subdir”子目录,这个
子目录中又有其对应的 Makefile 文件,那么这个工程在编译的时候其主目录中的 Makefile 就可
以调用子目录中的 Makefile,以此来完成所有子目录的编译。主目录的 Makefile 可以使用如下
代码来编译这个子目录:
$(MAKE) -C subdir
$(MAKE)表示make命令,-C指定子目录。有时候向子make传递变量,使用export来导出要传递给子make的变量即可,如果不希望哪个变量传递给子make的话使用unexport声明不导出:
export VARIABLE //导出变量给子make
unexport VARIABLE
在uboot的主Makefile中有如下代码:
MAKEFLAGS += -rR --include-dir=$(CURDIR)
+=给变量MAKEFLAGS追加了一些值,-rR表示禁用内置的隐式规则和变量定义,–include-dir指明搜索路径,$(CURDIR)表示当前目录
在终端中输出短命令虽然看起来很清爽,但是不利于分析 uboot 的编译过程。可以通过设置变量“V=1“来实现完整的命令输出,这个在调试 uboot 的时候很有用
顶层 Makefile 中控制命令输出的代码如下:
73 ifeq ("$(origin V)", "command line") //判断$(origin V)和command line是否相等
74 KBUILD_VERBOSE = $(V)
75 endif
76 ifndef KBUILD_VERBOSE
77 KBUILD_VERBOSE = 0
78 endif
79
80 ifeq ($(KBUILD_VERBOSE),1)
81 quiet =
82 Q =
83 else
84 quiet=quiet_
85 Q = @
86 endif
origin函数他不操作变量的值,用来告诉你变量是哪来的,语法格式为:
$(origin<variable>)
variable 是变量名,origin 函数的返回值就是变量来源,因此 ( o r i g i n V ) 就 是 变 量 V 的 来 源 如 果 变 量 V 是 在 命 令 行 定 义 的 那 么 它 的 来 源 就 是 " c o m m a n d l i n e " , 这 样 " (origin V)就是变量 V 的来源 如果变量 V 是在命令行定义的那么它的来源就是"command line",这样" (originV)就是变量V的来源如果变量V是在命令行定义的那么它的来源就是"commandline",这样"(origin V)"和"command
line"就相等了。
当这两个相等的时候变量 KBUILD_VERBOSE 就等于 V 的值,比如在命令行中
输入“ V=1 “ 的 话 那 么 KBUILD_VERBOSE=1 。如果没有在命令行输入 V 的 话
KBUILD_VERBOSE=0。
第 80 行判断 KBUILD_VERBOSE 是否为 1,如果 KBUILD_VERBOSE 为 1 的话变量 quiet和 Q 都为空,如果 KBUILD_VERBOSE=0 的话变量 quiet 为“quiet_“,变量 Q 为“@”
3.静默输出
编译的时候使用make -s即可实现静默输出,顶层Makefile中的相应的代码如下:
88 # If the user is running make -s (silent mode), suppress echoing of
89 # commands
90
91 ifneq ($(filter 4.%,$(MAKE_VERSION)),) # make-4
92 ifneq ($(filter %s ,$(firstword x$(MAKEFLAGS))),)
93 quiet=silent_
94 endif
95 else # make-3.8x
96 ifneq ($(filter s% -s%,$(MAKEFLAGS)),)
97 quiet=silent_
98 endif
99 endif
100
101 export quiet Q KBUILD_VERBOSE
$(filter<pattern...>,<text>)
filter 函数表示以 pattern 模式过滤 text 字符串中的单词,仅保留符合模式 pattern 的单词,
可以有多个模式。函数返回值就是符合 pattern 的字符串。
第 91 行判断当前正在使用的编译器版本号是否为 4.x,判断 ( f i l t e r 4. (filter 4.%, (filter4.(MAKE_VERSION))
和“ ”(空)是否相等,如果不相等的话就成立,执行里面的语句。make -v查看make工具版本号
$(firstword<text>)
firstword函数用于去除text字符串中的第一个单词,函数的返回值就是获取到的单词。
4.设置编译结果输出目录
uboot 可以将编译出来的目标文件输出到单独的目录中,在 make 的时候使用“O”来指定
输出目录,比如“make O=out”就是设置目标文件输出到 out 目录中。
ifeq ("$(origin O)", "command line") //判断O是否来自命令行
ifneq ($(KBUILD_OUTPUT)) //判断KBUILD_OUTPUT是否为空
5.代码检查
uboot 支持代码检查,使用命令“make C=1”使能代码检查,检查那些需要重新编译的文
件。“make C=2”用于检查所有的源码文件
6.模块编译
在 uboot 中允许单独编译某个模块,使用命令“make M=dir”即可,旧语法“make
SUBDIRS=dir”也是支持的
7.获取主机架构和系统
HOSTARCH := $(shell uname -m | \
sed -e s/i.86/x86/ \
HOSTARCH 变量用于保存主机架构,调用shell命令uname -m表示获取架构名称
shell 中的“|”表示管道,意思是将左边的输出作为右边的输入,sed -e 是替换命令,“sed -e s/i.86/x86/”表示将管道输入的字符串
中的“i.86”替换为“x86”,其他的“sed -e s”命令同理。
8.设置目标架构、交叉编译器和配置文件
编 译 uboot 的 时 候 需 要 设 置 目 标 板 架 构 和 交 叉 编 译 器 ,“ make ARCH=arm
CROSS_COMPILE=arm-linux-gnueabihf-”就是用于设置 ARCH 和 CROSS_COMPILE,在顶层
Makefile 中代码如下:
244 # set default to nothing for native builds
245 ifeq ($(HOSTARCH),$(ARCH))
246 CROSS_COMPILE ?=
247 endif
248
249 KCONFIG_CONFIG ?= .config
250 export KCONFIG_CONFIG
第 249 行定义变量 KCONFIG_CONFIG,uboot 是可以配置
的,这里设置配置文件为.config,.config 默认是没有的,需要使用命令“make xxx_defconfig” 对 uboot 进行配置,配置完成以后就会在 uboot 根目录下生成.config。默认情况下.config 和
xxx_defconfig 内容是一样的,因为.config 就是从 xxx_defconfig 复制过来的。如果后续自行调整
了 uboot 的一些配置参数,那么这些新的配置参数就添加到了.config 中,而不是 xxx_defconfig。
相当于 xxx_defconfig 只是一些初始配置,而.config 里面的才是实时有效的配置。
9.调用scripts/Kbuild.include
主 Makefile 会调用文件 scripts/Kbuild.include 这个文件,顶层 Makefile 中代码如下:
327 # We need some generic definitions (do not try to remake the file).
328 scripts/Kbuild.include: ;
329 include scripts/Kbuild.include