### u-boot中的Makefile #### 一、引言 u-boot是一个开源的嵌入式设备启动加载程序,广泛应用于各种嵌入式系统中。本文主要分析了u-boot-2008.10版本在mini2440平台上的移植过程中涉及到的Makefile配置与构建流程。 #### 二、Makefile配置解析 u-boot的Makefile主要用于自动化编译和构建过程,它通过一系列预定义的变量和规则来控制整个项目的构建流程。下面我们将详细介绍几个关键部分: ##### 1. 定义环境变量 ```makefile 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/macppc/ppc/') ``` 这部分代码的作用是获取当前系统的架构,并根据不同的架构进行映射转换。例如,对于i386架构,它会被映射为`i386`;对于`sun4u`架构,则会被映射为`sparc64`。通过这种方式,Makefile可以适应不同类型的主机架构。 ```makefile HOSTOS:=$(shell uname -s | tr '[:upper:]' '[:lower:]' | sed -e 's/\(cygwin\).*/cygwin/') ``` 这里定义了`HOSTOS`变量,用来表示主机的操作系统。首先使用`uname -s`命令获取操作系统名称,然后通过`tr`命令将所有大写字母转换为小写字母,最后使用`sed`进行特定的替换操作。例如,如果检测到的是Cygwin环境,则会将其统一映射为`cygwin`。 ##### 2. 导出环境变量 ```makefile export HOSTARCH HOSTOS ``` 这行代码将`HOSTARCH`和`HOSTOS`两个变量导出到环境变量中,使得在后续的构建过程中可以被其他脚本或者Makefile引用。 ##### 3. 配置项目目录结构 ```makefile TOPDIR:=$(shell if [ "$$PWD" != "" ]; then echo $$PWD; else pwd; fi) export TOPDIR ``` 这里定义了`TOPDIR`变量,表示u-boot项目的根目录。`$$PWD`用于获取当前工作目录,如果为空则使用`pwd`命令获取。 ```makefile ifeq (,$(findstrings ,$((MAKEFLAGS)))) XECHO=echo else XECHO=: endif ``` 这段代码用于判断`MAKEFLAGS`中是否包含`-s`标志。如果没有,则定义`XECHO`为`echo`,否则将其定义为空。这样,在执行`echo`命令时,可以根据`MAKEFLAGS`中的设置来决定是否输出信息。 ```makefile ifdef O ifeq ("$(origin O)","commandline") BUILD_DIR:=$(O) endif endif ``` 这部分代码用于处理`O`变量,该变量可以通过命令行参数传递给Makefile,用来指定构建目录。如果`O`变量是通过命令行传递的,则将其赋值给`BUILD_DIR`。 ```makefile $(shell [-d ${BUILD_DIR}] || mkdir -p ${BUILD_DIR}) ``` 这里检查`BUILD_DIR`目录是否存在,如果不存在则创建之。`[-d ${BUILD_DIR}]`是一个shell命令,用于检查`BUILD_DIR`是否为一个存在的目录。 ##### 4. 目录变量定义 ```makefile ifeq ($(BUILD_DIR),) OBJTREE:=$(CURDIR) else OBJTREE:=$(BUILD_DIR) endif ``` 这里定义了`OBJTREE`变量,表示对象文件的存放目录。如果`BUILD_DIR`未定义,则默认为当前目录;否则使用`BUILD_DIR`的值。 ```makefile SRCTREE:=$(CURDIR) TOPDIR:=$(SRCTREE) LNDIR:=$(OBJTREE) ``` 定义了源码树(`SRCTREE`)、顶级目录(`TOPDIR`)和链接目录(`LNDIR`)。通常情况下,这三个目录都指向相同的路径。 ```makefile export TOPDIR SRCTREE OBJTREE ``` 导出这些目录变量,以便在后续的Makefile文件中使用。 ##### 5. 配置文件引入 ```makefile MKCONFIG:=$(SRCTREE)/mkconfig export MKCONFIG ``` 这里定义了`MKCONFIG`变量,指向`mkconfig`脚本的路径。该脚本用于生成或修改配置文件,如`include/config.mk`。 ```makefile ifeq ($(OBJTREE),$(SRCTREE)) obj:= src:= else obj:=$(OBJTREE)/ src:=$(SRCTREE)/ endif ``` 根据`OBJTREE`和`SRCTREE`是否相同来定义`obj`和`src`变量。如果相同,则这两个变量为空;否则,它们分别指向对象文件和源文件所在的目录。 ```makefile ifeq (include/config.mk,$(wildcard include/config.mk)) include $(obj)include/config.mk endif ``` 这里检查`include/config.mk`文件是否存在,如果存在,则将其包含进来。`include/config.mk`文件通常包含具体的配置信息,比如架构相关的配置。 #### 三、总结 通过以上分析,我们可以看出u-boot的Makefile配置非常灵活且强大。它不仅能够根据不同的主机环境自动调整配置,还能够自动生成或引入配置文件,大大简化了嵌入式系统的构建流程。对于开发者来说,理解这些配置对于定制和优化u-boot构建过程具有重要意义。


















当我们编译U-BOOT的时候,大家键入make smdk2410_config,make 的时候都作了那些动作呢,这里我先大概介绍一下Makefile的内容,然后在大概理解一下命令执行的流程。如果有错的地方,希望大家指正,谢谢。
1.u-boot顶层目录的Makefile分析:
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/macppc/ppc/)
首先执行uname -m得到I686,通过管道传送给sed命令,然后sed命令将执行sed -e s/i.86/i386/,将I686替换成i386,最后的结果是HOSTARCH=i386.
HOSTOS := $(shell uname -s | tr '[:upper:]' '[:lower:]' | \
sed -e 's/\(cygwin\).*/cygwin/')
首先执行uname -s 查看开发平台的系统,结果为Linux,然后通过管道传送给tr命令,tr命令利用字符类[:lower:]和[:upper:]将LInux字符串转化为linux,然后再利用sed命令.最后的结果是HOSTOS=linux
export HOSTARCH HOSTOS
export 是Makefile的语法关键词,将这些变量传递给下一层的Makefile.总控Makefile的变量可以传递到下级的Makefile中(如果你显示的声明),但是不会覆盖下层的Makefile中所定义的变量,除非指定了“-e”参数。
如果你要传递变量到下级Makefile中,那么你可以使用这样的声明:
export <variable ...>;
如果你不想让某些变量传递到下级Makefile中,那么你可以这样声明:
unexport <variable ...>;
TOPDIR := $(shell if [ "$$PWD" != "" ]; then echo $$PWD; else pwd; fi)
export TOPDIR
得到U-BOOT的绝对路径为TOPDIR.
ifeq (,$(findstring s,$(MAKEFLAGS)))
XECHO = echo
else
XECHO = :
endif
通过findstring函数来找MAKEFLAGS是否有匹配s的关键词,如果没有则ifeq就为真。那么变量XECHO就等于echo 反之亦然。
ifdef O
ifeq ("$(origin O)", "command line")
BUILD_DIR := $(O)
endif
endif
这里主要说明origin的语法:
origin函数不像其它的函数,他并不操作变量的值,他只是告诉你你的这个变量是哪里来的?其语法是:
$(origin <variable>;)
注意,<variable>;是变量的名字,不应该是引用。所以你最好不要在<variable>;中使用“$”字符。Origin函数会以其返回值来告诉你这个变量的“出生情况”,下面,是origin函数的返回值:
“undefined”
如果<variable>;从来没有定义过,origin函数返回这个值“undefined”。
“default”
剩余11页未读,继续阅读


- 粉丝: 13
我的内容管理 展开
我的资源 快来上传第一个资源
我的收益
登录查看自己的收益我的积分 登录查看自己的积分
我的C币 登录后查看C币余额
我的收藏
我的下载
下载帮助


最新资源
- XP-网络故障解决措施全集.doc
- 电气自动化在水利水电工程中的应用分析1.docx
- 时间触发通信:原理与应用
- 基于JSP的教学管理系统大学本科方案设计书.doc
- 基于PLC的物料分拣控制系统的设计.doc
- 实验项目管理-需求书.doc
- 最新高端简约英文版互联网科技金融商务工作计划总结PPT模PPT模板.pptx
- 移动通信技术与计算机网络.docx
- 面翻洪海广告设备有限公司项目管理书.doc
- 电网调度自动化系统的应用.pdf
- 互联网+时代高校线上线下混合式教学模式探究.docx
- 2017级大数据技术与应用专业人才培养方案.doc
- 论网络虚拟财产的民法界定.docx
- 基于 Python 实现自动驾驶的规划与控制代码
- 酒店无线网络覆盖解决方案.docx
- 电子科技16秋《供配电系统监控与自动化》在线作业2-辅导资料.doc


