uboot系列之-----顶层Makefile分析(二)
来源:互联网 发布:java特种兵 读后感 编辑:程序博客网 时间:2024/04/30 01:28
继续上篇,这篇主要分析跟编译和连接库文件相关的变量
ifeq ($(obj)include/config.mk,$(wildcard $(obj)include/config.mk))
……
else # !config.mk
all $(obj)u-boot.hex $(obj)u-boot.srec $(obj)u-boot.bin \
$(obj)u-boot.img $(obj)u-boot.dis $(obj)u-boot \
$(filter-out tools,$(SUBDIRS)) $(TIMESTAMP_FILE) $(VERSION_FILE) \
updater depend dep tags ctags etags cscope $(obj)System.map:
@echo "System not configured - see README" >&2
@ exit 1
tools:
$(MAKE) -C $@ all
endif # config.mk
ifeq语句判断include目录下是否存在config.mk文件(通过《uboot系列之-----uboot配置过程详细分析》一文可知,只有执行了make xxx_config之后,才存在该文件)。
我们暂时不分析config.mk存在时的情况,因为太长了,先分析config.mk不存在的情况,即else后的语句,该语句把所有的目标都指向了一个依赖,就是打印出错信息“System not configured – see README”,然后退出。
接下来看config.mk存在的情况:
all:
sinclude $(obj)include/autoconf.mk.dep
sinclude $(obj)include/autoconf.mk
先看目标all:从makefile开始到现在,发现这个all是第一个目标,也就是说当我们执行make命令时,它是默认目标,但是该目标既没有依赖也没有规则,那它起到什么作用呢?接着往下看,sinclude $(obj)include/autoconf.mk.dep,他的意思是包含autoconf.mk.dep文件,进入到该文件,发现第一句是:
include/autoconf.mk: include/common.h \,它也是一个目标,并且有很多的依赖
再回到all的作用上来,如果没有这个all,那么当我们执行make时,根据make法则,(它将第一个目标作为他的默认目标),也就是将autoconf.mk作为默认目标,显然这不是我们想要的结果,(我们执行make是想编译整个文件,也就是执行第365行的all: $(ALL)这个规则,而在这里加上一个看起来“毫无意义”的all,就能达到我们想要的目的,即执行第一个空的all目标后,会跳过autoconf.mk目标,执行下一个all目标)
再来看sinclude,sinclude也是包含文件的关键词,他与include的区别就是使用sinclude时,即使所需要包含的文件不存在,也不影响makefile的往下执行。
而autoconf.mk.dep和autoconf.mk这两个文件是怎么来的呢,在makefile中有如下一段语句,说明了这两个文件的来源:
$(obj)include/autoconf.mk.dep: $(obj)include/config.h include/common.h
@$(XECHO) Generating $@ ; \
set -e ; \
: Generate the dependancies ; \
$(CC) -x c -DDO_DEPS_ONLY -M $(HOSTCFLAGS) $(CPPFLAGS) \
-MQ $(obj)include/autoconf.mk include/common.h > $@
$(obj)include/autoconf.mk: $(obj)include/config.h
@$(XECHO) Generating $@ ; \
set -e ; \
: Extract the config macros ; \
$(CPP) $(CFLAGS) -DDO_DEPS_ONLY -dM include/common.h | \
sed -n -f tools/scripts/define2mk.sed > $@.tmp && \
mv $@.tmp $@
这段规则没有完全看明白,望大侠们帮我分析一下
include $(obj)include/config.mk
export ARCH CPU BOARD VENDOR SOC
包含配置过程中生成的config.mk文件,并把该文件中的变量导出来
ifeq ($(ARCH),arm)
CROSS_COMPILE =/usr/local/arm/arm-2009q3/bin/arm-none-linux-gnueabi-
Endif
如果ARCH=arm,即体系架构为ARM ,就给变量CROSS_COMPILE赋值,改变量的值代表了交叉编译器的路径
include $(TOPDIR)/config.mk
包含顶层目录下的config.mk文件
下面开始定义了目标文件变量(跟ARM无关的这里就省略没有列出来)
OBJS = $(CPUDIR)/start.o
这里的CPUDIR目录在顶层目录的config.mk文件里面定义 CPUDIR=arch/$(ARCH)/cpu/$(CPU),对于smdk4412来说 CPUDIR= arch/arm/cpu/armv7
……
OBJS := $(addprefix $(obj),$(OBJS))
在原有OBJS值前面加上一个路径$(obj)前缀,指明绝对路径,如果$(obj)为空,则OBJS相当于没变化
下面开始定义了库文件变量(跟硬件平台无关的这里就省略没有列出来)
…….
LIBS += $(shell if [ -f board/$(VENDOR)/common/Makefile ]; then echo \
"board/$(VENDOR)/common/lib$(VENDOR).o"; fi)
LIBS += $(CPUDIR)/lib$(CPU).o
ifdef SOC
LIBS += $(CPUDIR)/$(SOC)/lib$(SOC).o
Endif
对于smdk4412来说,board/Samsung/common/Makefile文件并不存在,所以第一个赋值无效,接下来的两个分别为
LIBS+= arch/arm/cpu/armv7/libarmv7.o
LIBS+= arch/arm/cpu/armv7/exynos/libexynos.o
…..
LIBS += arch/$(ARCH)/lib/lib$(ARCH).o
LIBS+= arch/arm/lib/libarm.o
ifeq ($(SOC),exynos)
LIBS += $(CPUDIR)/s5p-common/libs5p-common.o
Endif
LIBS+= arch/arm/cpu/armv7/s5p-common/libs5p-common.o
LIBBOARD = board/$(BOARDDIR)/lib$(BOARD).o
LIBBOARD := $(addprefix $(obj),$(LIBBOARD))
BOARDDIR定义在顶层目录的config.mk文件中 BOARDDIR = $(VENDOR)/$(BOARD) 对于smdk4412来说
BOARDDIR = Samsung/smdk4212
LIBBOARD = board/samsung/smdk4212/libsmdk4212.o
PLATFORM_LIBGCC = -L $(shell dirname `$(CC) $(CFLAGS) -print-libgcc-file-name`) –lgcc
PLATFORM_LIBS += $(PLATFORM_LIBGCC)
export PLATFORM_LIBS
dirname `$(CC) $(CFLAGS) -print-libgcc-file-name`取得交叉编译器的libgcc.a的绝对路径
$(CC) = $(CROSS_COMPILE)gcc
$(CFLAGS)定义在config.mk
-L表示编译时将其后所跟的目录作为第一个寻找库文件的目录
LDPPFLAGS += \
-include $(TOPDIR)/include/u-boot/u-boot.lds.h \
$(shell $(LD) --version | \
sed -ne 's/GNU ld version \([0-9][0-9]*\)\.\([0-9][0-9]*\).*/-DLD_MAJOR=\1 -DLD_MINOR=\2/p')
$(LD)定义在顶层目录的config.mk文件
LD= $(CROSS_COMPILE)ld,表示交叉编译器里面的连接工具
shell $(LD) –version表示取得连接工具的版本,我这里的版本号是”GNU ld (GNU Binutils for Ubuntu) 2.22”
ifeq ($(CONFIG_NAND_U_BOOT),y)
NAND_SPL = nand_spl
U_BOOT_NAND = $(obj)u-boot-nand.bin
endif
ifeq ($(CONFIG_ONENAND_U_BOOT),y)
ONENAND_IPL = onenand_ipl
U_BOOT_ONENAND = $(obj)u-boot-onenand.bin
ONENAND_BIN ?= $(obj)onenand_ipl/onenand-ipl-2k.bin
endif
__OBJS := $(subst $(obj),,$(OBJS))
__LIBS := $(subst $(obj),,$(LIBS)) $(subst $(obj),,$(LIBBOARD))
$subst(<from>,<to>,<text>)的功能是将<text>中的<from>字符串换成<to>字符串
__OBJS相当于截取OBJS的相对路径,__LIBS类似
- uboot系列之-----顶层Makefile分析(二)
- uboot系列之-----顶层Makefile分析(一)
- uboot系列之-----顶层Makefile分析(三)
- uboot系列之-----顶层Makefile分析(一)
- uboot系列之-----顶层Makefile分析(一)
- Uboot顶层Makefile分析
- uboot 2011-06 之顶层Makefile分析
- jz2440 uboot 移植(顶层Makefile分析)
- uboot的Makefile分析之顶层config.mk
- uboot 2011-06 之makefile 分析(二)
- uboot分析之Makefile(二)两种编译
- uboot-顶层Makefile注释
- Uboot 之Makefile 分析
- uboot之Makefile分析
- Uboot 之Makefile 分析
- uboot之Makefile分析
- uboot之Makefile分析
- Uboot 之Makefile 分析
- 快速书写html代码---Zen Coding
- js技巧
- u3d 按照路径不停的运动
- 寻找迷宫的一条出路 (o:通路,X障碍)
- 安装最新版本的MySQL5.1.47(64位)
- uboot系列之-----顶层Makefile分析(二)
- C++ 简单选择排序
- Android 控件常用属性
- 中文字体在CSS中写法
- repne指令和scasb指令解析
- Android开发之旅: Intents和Intent Filters(理论部分)
- nagios全攻略(四)----监控LINUX上的”本地信息”
- 自定义 Android 对话框 (AlertDialog) 的样式
- oracle变量绑定