UBOOT的编译过程二

#make all

插讲:

Makefile:在符合GNU Makefiel惯例的Makefile中,包含了一些基本的预先定义的操作:

make:根据Makefile编译源代码,连接,生成目标文件,可执行文件。

make clean:清除上次的make命令所产生的object文件(后缀为“.o”的文件)及可执行文件。

make install:将编译成功的可执行文件安装到系统目录中,一般为/usr/local/bin目录。

make dist:产生发布软件包文件(即distribution package)。这个命令将会将可执行文件及相关文件打包成一个tar.gz压缩的文件用来作为发布软件的软件包。它会在当前目录下生成一个名字类似“PACKAGE-VERSION.tar.gz”的文件。PACKAGE和VERSION,是我们在configure.in中定义的AM_INIT_AUTOMAKE(PACKAGE, VERSION)。

make distcheck:生成发布软件包并对其进行测试检查,以确定发布包的正确性。这个操作将自动把压缩包文件解开,然后执行configure命令,并且执行make,来确认编译不出现错误,最后提示你软件包已经准备好,可以发布了。

make distclean:类似make clean,但同时也将configure生成的文件全部删除掉,包括Makefile

# Include autoconf.mk before config.mk so that the config options are available
# to all top level build files.  We need the dummy all: target to prevent the
# dependency target in autoconf.mk.dep from being the default.
all:
sinclude $(obj)include/autoconf.mk.dep
sinclude $(obj)include/autoconf.mk

# load ARCH, BOARD, and CPU configuration
include $(obj)include/config.mk
export	ARCH CPU BOARD VENDOR SOC

# set default to nothing for native builds
ifeq ($(HOSTARCH),$(ARCH))
CROSS_COMPILE ?=
endif

# load other configuration
include $(TOPDIR)/config.mk

也是一样从all开始分析makefile代码。这一点很重要。其实在这个语句前不有一句话

ifeq ($(obj)include/config.mk,$(wildcard $(obj)include/config.mk))

其实主要是表示是否存在这个文件。

扩展插讲:

      make 在读入所有 makefile 文件之后,首先将所读取的每个 文件 作为一个目标,寻找更新它们的规则。如果存在一个更新某一个 文件明确规则或者隐含规则,就去更新对应的文件。完成对所有的文件的更新之后,如果之前所读取任何一个文件被更新,那么 make 就清除本次执行的状态重新读取一遍所有的文件(此过程中,同样在读取完成以后也会去试图更新所有的已经读取的文件,但是一般这些文件不会再次被重建,因为它们在时间戳上 已经是最新的)。读取完成以后再开始解析已经读取的 文件并开始执行必要 的动作。自然不存在这两个文件就得在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 $@

插讲:

例子:g-bios/app/net/Makefile
----------------------------------------------------------------------------------------------------------------------------------------
OBJS = ifconfig.o tftp_util.o ping.o
SRCS = $(OBJS:.o=.c)

PHONY += all
all : $(BUILT_IN_OBJ)

$(BUILT_IN_OBJ) : $(OBJS)
        $(LD) $(LDFLAGS) -r $^ -o $@

$(OBJS) : $(SRCS)
        $(CC) $(CFLAGS) -c $^

PHONY += clean
clean :
        @rm -vf *.o

.PHONY : $(PHONY)
----------------------------------------------------------------------------------------------------------------------------------------
说明:$(BUILT_IN_OBJ) 和 $(PHONY)来自上层目录g-bios/app/Makefile,可以不用理解。
$@ 代表目标 上例为$(BUILT_IN_OBJ)
$^ 代表所有的依赖对象 上例第一个$^为$(OBJS),即 ifconfig.o tftp_util.o ping.o,上例第二个$^为$(SRCS),即$(OBJS:.o=.c) (Makefile解释后为: ifconfig.c tftp_util.c ping.c)
$< 代表第一个依赖对象 前面例子修改如下:
$(BUILT_IN_OBJ) : $(OBJS)
        $(LD) $(LDFLAGS) -r $< -o $@
则$<表示为ifconfig.o

对于autoconf.mk.dep和autoconf.mk产生请参考UBOOT的编译过程二之番外

以上make执行的时候会将autoconf.mk和autoconf.mk.dep,还有include下面的config.mk包含进来。还有顶层目录下的config.mk包含进来。通过makefile里面的规则对文件中的内容进行处理,如果有依赖就产生相应的生成目标文件的规则,进行产生目标文件。

ifeq ($(HOSTARCH),$(ARCH))
CROSS_COMPILE ?=
endif

这句话的意思是比较当前机器的架构与我们的目标系统的架构是不是一样。一样的话就将交叉编译工具链设置为空。

插讲:=,:=,?=,+=区别。

= 是最基本的赋值
:= 是覆盖之前的值
?= 是如果没有被赋值过就赋予等号后面的值
+= 是添加等号后面的值

总结:

主要这个部分是包含config.mk,生成autoconf.mk,autoconf.mk.dep文件,并包含进来。也就是说如果想进行make或者make all

一定要先进行make xxx_config产生config.mk以及config.h文件。


版权声明:本文为huangminilong原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。