您的位置:首页 > 其它

uboot主Makefile分析

2016-05-19 09:24 387 查看
转自:http://blog.csdn.net/qq_24696949/article/details/51156807









导出后的这些变量可以被其他文件使用,我们称这种变量为环境变量,环境变量相当于C中的全局变量,环境变量一般用大写字母表示。

小插曲①:什么是静默编译?

平时编译时命令行会打印出来很多编译信息,有时候我们不希望看到这些编译信息,即后台编译即可,就叫静默编译;

静默编译的使用方法:

编译时 make -s,-s会作为MAKEFLAGS传给Makefile;其中MAKEFLALGS是个变量,

‘-s’和‘-k’标志通过变量MAKEFLAGS自动传递给子make。该变量由make自动建立,并包含make收到的标志字母。所以,如果用‘make –ks’变量MAKEFLAGS就得到值‘ks’。









上面截图中的50行中就是从变量MAKEFLAGS中寻找s,如果找到了就执行非静默编译。

小插曲②:uboot的两种编译方法(原地编译和单独输出文件夹编译)

(1)编译复杂项目,Makefile提供两种编译管理方法,默认情况下是当前文件夹中的 .c文件和编译生成的 .o文件会放在同一文件夹下,这种方式叫原地编译。原地编译的坏处:污染了原文件目录;

(2)为了解决原地编译的缺点,uboot支持单独输出文件夹方式的编译:即在编译时另外指定一个输出目录,将所有的生成的.o文件或生成的其他文件全部丢到那个输出目录中。

(3)默认是原地编译,要指定具体的输出目录编译有两种方式来指定输出目录;

第一种:make O=输出目录;

第二种:export BUILD_DIR(表示uboot的编译路径)=输出目录,然后在make,如果两种都指定了,则O=xx这种具有更高的优先级。具体细节如下截图:























注:OBJTREE是编译出来的 .o文件存放的目录的根目录,在默认编译下,OBJTREE等于当前目录,在O=xx编译下,OBJTERR就等于我们设置的那个输出目录。







上图中的101行的MKCONFIG是Makefile中定义的一个变量,它的值就是源码根目录下的mkconfig,这个mkconfig是一个脚本,就是uboot配置阶段的配置脚本。











上图中的133行中的config.mk文件不是源码自带的(没编译过的源码目录下没有这个文件),要在配置过程(make
x210_sd_config)中才会生成这个文件,因此这个文件和我们的配置过程有关,是由配置过程根据我们的配置自动生成的。

我们在X210_iNand下配置生成的config.mk内容为(生成的config.mk文件在include目录下):

ARCH = arm

CPU = S5PC11x

BOARD = x210

VENDOR = samsung

SOC = S5PC110

其中,上面提到的config.mk文件是在mkconfig配置脚本中创建的,如下是配置脚本mkconfig中的部分:



接着回到主Makefile;





上图中用export导出了这5个变量作为环境变量,其环境变量的值由Makefile中2589行处的配置项决定。





CROSS_COMPILE 环境变量的值受ARCH的值影响,ARCH值来自于上面2589行的配置过程(ARCH的意义是定义当前编译的目标的CPU架构);CROSS_COMPILE 是定义交叉编译工具链的前缀的。





上图中的TOPDIR表示源码目录(注意:源码目录下自带的config.mk和OBJTREE下的config.mk不是同一个文件),在Makefile前段97行处有定义,如下:





源码目录下的config.mk文件中的部分如下:





这个autoconf.mk是配置过程自动生成的(借助下面的x210_sd.h生成),这个文件的作用是用来指导整个uboot的编译过程,这个文件的内容是很多CONFIG开头的宏,这些宏会影响uboot编译过程的走向。这些宏的配置过程在源码目录下的include/configs/xxx.h头文件中,210为include/config/x210_sd.h,这个头文件中全部都是宏定义,这些宏定义就是对210开发板uboot移植的关键。





小插曲③:主Makefile2589行分析





(1)@代表目标吗?印象里$@ 才代表目标,做了个测试

all:

@echo $@ 输出是all

@echo @ 输出是@

@echo $(@) 输出是all

所以我认为符号@在$()中和$@是一样的

(2)目标 :依赖

命令

命令是否可以直接是一个文件名?

做了个测试证明可以:

在外面建立一个mkconfig 里面输入 echo i am here !

在makefile 里

all:

@(路径/mkconfig)

输入命令make all(执行主目标直接make即可,其他目标需要make+目标名)

就会输出 i am here !(没有依赖,执行目标就是为了执行目标下面的命令,这种目标成为伪目标)

(3)对于下面的截图而言,make x210_sd_config 就相当于./mkconfig arm s5pc11x x210 samsung s5pc110





(4)再看加上 $(@:_config=),下图:





根据上面的分析,$(@)代表目标,也就是代表x210_sd_config,:_config=表示将_config赋值为空,即传给mkconfig的第一个参数实际是x210_sd,第二个参数是arm,第三个参数s5pc11x..........
$#=6。

(5)分析(4)中调用的mkconfig





上图中$#为6,break直接跳出while循环。






实际分析结果:BOARD_NAME=x210_sd





上图中表示$#小于4或大于6都返回1(返回1的意思是错误,不执行这个mkconfig脚本了),也就是说给这个脚本传参的时候只能传
4 5 6 ;如果大于6或小于4都不行。















上图中mkconfig文件的33-118行都是在创建符号链接;这些符号链接文件的存在就是整个配置过程的核心。这些符号链接文件(文件夹)的主要作用是给头文件包含等过程提供指向性的链接,根本目的是让uboot具有可移植性。





上述截图在前面Makefile分析过程中已经提到了,是在include目录下创建config.mk文件,将下列内容写入此文件中,如下:











上图中的APPEND 不是yes,因而是新建了一个config.h文件(也是配置后在include目录下生成的),其内容如下:





由SD卡换成nandflash移植时,其中上图中的这个config.h中的内容不用在mkconfig脚本中更改,因为make menuconfig 配置的过程会自动将$1参数变成nandflash相关的;如下截图(截图来自于mkconfig脚本):





这个头文件在当前目录下的configs目录下的 $1.h中。

注意:make menuconfig(make x210_sd_config就会在config.h中包含x210_sd.h头文件)
配置的过程已经决定了会使用哪个.h头文件。

至此,主Makefile和mkconfig脚本已经大致结束了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: