u-boot1.3.4 ftp://ftp.denx.de/pub/u-boot/
1、uboot version确定(Makefile的24-29行)
Makefile代码部分:
VERSION = 1
PATCHLEVEL = 3
SUBLEVEL = 4
EXTRAVERSION =
U_BOOT_VERSION = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
VERSION_FILE = $(obj)include/version_autogenerated.h
1、uboot的版本号分3个级别
VERSION:主板本号
PATCHLEVEL:次版本号
SUBLEVEL:再次版本号
EXTRAVERSION:另外附加的版本信息, 一般默认为空,我们可以自己设置
这4个用.分隔开共同构成了最终的版本号U_BOOT_VERSION ,这个变量记录了Makefile中配置的版本号。
2、include/version_autogenerated.h文件是编译过程中自动生成的一个文件,所以源目录中没有,但是编译过后的uboot中就有了。它里面的内容是一个宏定义,宏定义的值内容就是我们在Makefile中配置的uboot的版本号。
#define U_BOOT_VERSION "U-Boot 1.3.4"
VERSION_FILE = $(obj)include/version_autogenerated.h
这个文件是根据355行
$(VERSION_FILE):
@( printf '#define U_BOOT_VERSION "U-Boot %s%s"\n' "$(U_BOOT_VERSION)" \
'$(shell $(CONFIG_SHELL) $(TOPDIR)/tools/setlocalversion $(TOPDIR))' \
) > $@.tmp
@cmp -s $@ $@.tmp && rm -f $@.tmp || mv -f $@.tmp $@
编译过后, version_autogenerated.h 文件的路径是:根目录下面include/version_autogenerated.h。这个文件中引用了变量U_BOOT_VERSION的值; version_autogenerated.h这个文件是在编译时自动生成的,通过vi可以看到里面的 内容是一个宏:#define U_BOOT_VERSION "U-Boot 1.3.4"
代码详解:https://blog.csdn.net/qq_30106701/article/details/96891205
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
代码详解:https://blog.csdn.net/qq_30106701/article/details/96836095
1、HOSTARCH这个名字:HOST是主机,就是当前在做开发用的这台电脑就叫主机;ARCH是architecture(架构)的缩写,表示CPU的架构。所以HOSTARCH就表示主机的CPU的架构。
2、直接在shell中执行uname -m得到i686,得到的值其实你当前执行这个命令的电脑的CPU的版本号。
3、shell中的 | 叫做管道,管道的作用就是把管道前面一个运算式的输出作为后面一个的输入再去做处理,最终的输出才是我们整个式子的输出。
4、这两个环境变量是主机的操作系统和主机的CPU架构
':=' 就是当冒号前面的变量不存在或值为空时,就把等号后的值赋值给变量
export HOSTARCH HOSTOS 的意思是输出两个makefile变量HOSTARCH HOSTOS
3、VENDOR= #开发商
4、静默编译(48-56)
#########################################################################
# Allow for silent builds
ifeq (,$(findstring s,$(MAKEFLAGS)))
XECHO = echo
else
XECHO = :
endif
#########################################################################
1、平时默认编译时命令行会打印出来很多编译信息。但是有时候我们不希望看到这些编译信息,就后台编译即可。这就叫静默编译。
2、使用方法就是编译时make -s,-s会作为MAKEFLAGS传给Makefile,这段代码作用下XECHO变量就会被变成空(默认等于echo),于是实现了静默编译。
代码详解:https://blog.csdn.net/qq_30106701/article/details/96852373
5、2种编译方法(原地编译和单独输出文件夹编译)
1、编译复杂项目,Makefile提供2种编译管理方法。默认情况下是当前文件夹中的.c文件,编译出来的.o文件会放在同一文件夹下。这种方式叫原地编译。原地编译的好处就是处理起来简单。
2、原地编译有一些坏处:第一,污染了源文件目录。第二的缺陷就是一套源代码只能按照一种配置和编译方法进行处理,无法同时维护2个或2个以上的配置编译方式。
3、为了解决以上2种缺陷,uboot支持单独输出文件夹方式的编译(Linux kernel也支持,而且uboot的这种技术就是从linux kernel学习来的)。基本思路就是在编译时另外指定一个输出目录,将来所有的编译生成的.o文件或生成的其他文件全部丢到那个输出目录下去。源代码目录不做任何污染,这样输出目录就承载了本次配置编译的所有结果。
4、具体用法:默认的就是原地编译。如果需要指定具体的输出目录编译则有2种方式来指定输出目录。(具体参考Makefile 56-76行注释内容)
第一种:make O=输出目录
第二种:export BUILD_DIR=输出目录 然后再make
如果两个都指定了(既有BUILD_DIR环境变量存在,又有O=xx),则O=xx具有更高优先级,听他的。
5、两种编译的实现代码在Makefile的56-124行,如下
代码详解:https://blog.csdn.net/qq_30106701/article/details/96855776
6、config.mk
参考:https://blog.csdn.net/qq_30106701/article/details/96879224
config.mk内容为:
ARCH = arm
CPU = arm920t
BOARD = smdk2410
VENDOR = NULL
SOC = s3c24x0
ifeq ($(obj)include/config.mk,$(wildcard $(obj)include/config.mk))
# load ARCH, BOARD, and CPU configuration
include $(obj)include/config.mk
export ARCH CPU BOARD VENDOR SOC
#****************
#****************
if执行的语句
#****************
#****************
#########################################################################
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 \
$(SUBDIRS) $(VERSION_FILE) gdbtools updater env depend \
dep tags ctags etags cscope $(obj)System.map:
@echo "System not configured - see README" >&2
@ exit 1
endif # config.mk
在Makefile规则中,通配符会被自动展开。但在变量的定义和函数引用时,通配符将失效。这种情况下如果需要通配符有效,就需要使用函数“wildcard”,它的用法是:$(wildcard PATTERN...) 。
在Makefile中,它被展开为已经存在的、使用空格分开的、匹配此模式的所有文件列表。如果不存在任何符合此模式的文件,函数会忽略模式字符并返回空。
如果没有config.mk将执行else ,然后退出。
参考以下文章:
https://www.cnblogs.com/yvivid/p/3555040.html
https://blog.csdn.net/u010003835/article/details/80752797