实现目标文件与源码分开的makefile测试实验

时间:2023-03-10 06:48:04
实现目标文件与源码分开的makefile测试实验

uboot提供了两种编译策略,即可以将生成的目标文件与源码混在一起,也可以将生成的目标文件与源码分开。通过对uboot Makefile的分析,笔者编写了一个简单的实现这种功能的Makfile。

顶层makefile

ifneq ($(BUILD_DIR),)
saved-output := $(BUILD_DIR)
# Attempt to create a output directory.
$(shell [ -d ${BUILD_DIR} ] || mkdir -p ${BUILD_DIR}) //创建目录BUILD_DIR
# Verify if it was successful.
BUILD_DIR := $(shell cd $(BUILD_DIR) && /bin/pwd)
$(if $(BUILD_DIR),,$(error output directory "$(saved-output)" does not exist))
endif # ifneq ($(BUILD_DIR),)
OBJTREE := $(if $(BUILD_DIR),$(BUILD_DIR),$(CURDIR)) //目标文件生成的根目录,可以认为是一个常量,区别于obj
SRCTREE := $(CURDIR) //CURDIR是当前目录的路径,目录改变,它随之改变
TOPDIR := $(SRCTREE)
export SRCTREE OBJTREE TOPDIR include $(TOPDIR)/config.mk //config.mk中定义了obj变量,下边的内容使用了这个变量 OBJS = add/add.o sub/sub.o test/test.o //需要生成的目标文件
OBJS := $(addprefix $(obj),$(OBJS)) //需要生成目标文件的完整路径
.PHONY : $(OBJS) //确保源文件修改了,目标文件能够自动重建 $(obj)program: $(OBJS) //在总目标前边也加上了前缀obj,以实现目标文件与目标文件在不同的目录
gcc $^ -o $@ $(OBJS):
make -C $(dir $(subst $(obj),,$@)) //依次执行各个子目录中的makefile .PHONY: clean
clean:
make -C add clean
make -C sub clean
make -C test clean
rm -f $(obj)program //删除时也要注意目录问题

顶层config.mk (确定当前的源文件的目录,以及要生成目标文件的完整路径,并创建这个路径)

ifneq ($(OBJTREE),$(SRCTREE))
ifeq ($(CURDIR),$(SRCTREE))
dir :=
else
dir := $(subst $(SRCTREE)/,,$(CURDIR))
endif obj := $(if $(dir),$(OBJTREE)/$(dir)/,$(OBJTREE)/) //确定要生成目标文件的完整路径,
//注意这是个变量,在不同的子目录中,执行makefile,obj的值相应的发生变化
src := $(if $(dir),$(SRCTREE)/$(dir)/,$(SRCTREE)/) //确定当前源文件的目录 $(shell mkdir -p $(obj)) //创建目标文件的完整路径,注意gcc命令并不能自动生成缺少的路径,所以需要事先创建
else //上边的是目标文件与源文件不同的情况,下边的是相同的情况
obj := //目标文件与源文件目录相同时,obj没有必要赋值
src :=
endif

子目录makefile,以add/makefile为例

include $(TOPDIR)/config.mk //子目录中的makefile也调用了obj变量,所以也要包含config.mk文件

$(obj)add.o: add.c ../include/heads.h
gcc -c -o $@ $< .PHONY: clean
clean:
rm -f $(obj)*.o

编译方法:

1、目标文件与源码混在一起

直接在顶层目录中执行:#make

2、目标文件与源码分开

方法一:

先声明个环境变量:#exprort BUILD_DIR=/tmp/build    //这里以/tmp/build为例

然后在顶层目录中执行:#make

方法二:

直接在顶层目录中执行:#make BUILD_DIR=/tmp/build

下载源码链接:sometest.zip