makefile管理编译工程 2

前面 https://blog.csdn.net/duapple/article/details/108180638 通过Makefile工程,已经能够让我们很轻松的构建大型工程了。但是工程的结构会被我们设计的Makefile结构所限制。

这里对前面的Makefile再进行修改,尽量减少Makefile的数量,让工程中的模块部分具备高耦合的特点,使我们的Makefile更加的通用,以便集成到其它工程中去。

目录结构如下:
在这里插入图片描述
mod目录为库的引入文件夹。其它目录和文件为原工程。
因此原成功只有一个简单的Makefile来进行管理,主程序拥有一些全局变量,包括CC命令等,用于交叉编译和全局控制等。在mod中引入需要编译的子模块,添加编译和删除命令即可。
Makefile如下:

#------------------------------
# 选择编译工具链
#------------------------------
CROSS=
#arm-himix100-linux-
export CC=${CROSS}gcc
export AR=${CROSS}ar

#------------------------------
# 全局编译参数变量
#------------------------------
export CFLAGS_ENV=-Wall -Os -ffunction-sections -fdata-sections
#-g 

#-------------------------------
# 全局编译路径变量
#-------------------------------
export ROOT_DIR=$(shell pwd)
export mk_dir=$(pwd)/build/tool
export BUILD_DIR=$(ROOT_DIR)/build/out
export APP_DIR=$(ROOT_DIR)/app
export MOD_DIR=$(ROOT_DIR)/mod

#------------------------------
# 生成程序名称
#------------------------------
target := main

#------------------------------
# 生成程序输出路径
#------------------------------
outdir := $(ROOT_DIR)

#----------------------------------------
# 源文件路径(采用相对路径)
#----------------------------------------
srcdir := . src source

#----------------------------------------
# 头文件路径
#----------------------------------------
INCLUDE := -I./include 
INCLUDE += $(addprefix -I./, $(srcdir))
INCLUDE += -I./mod/app

#----------------------------------------
# 编译参数
#----------------------------------------
CFLAGS := $(CFLAGS_ENV)

#------------------------------
# 链接参数
#------------------------------
LDLAGS := -Wl,-Map=$(BUILD_DIR)/object.map,--cref,--gc-section -lpthread -ldl -lm

#------------------------------
# 模块路径
#------------------------------
MOD := app

#------------------------------
# 链接时需要的库
#------------------------------
LIB += $(foreach d, $(addsuffix /lib, $(addprefix $(MOD_DIR)/, $(MOD))), $(wildcard $(d)/*.a))

#------------------------------
# 编译前准备
#------------------------------
src := $(foreach d, $(srcdir), $(wildcard $(d)/*.c))
obj := $(src:.c=.o)
dep := $(src:.c=.d)
build := $(BUILD_DIR)/$(subst $(ROOT_DIR)/,,$(CURDIR)/)
objs := $(addprefix $(build)/, $(obj))
deps := $(addprefix $(build)/, $(dep))
target_out := $(outdir)/$(target)

all: module $(target_out)

#-----------------------------------------------
# 子模块编译
#-----------------------------------------------
module:
	@make -C $(MOD_DIR)/$(MOD)

#-----------------------------------------------
# 生成静态库及依赖关系
#-----------------------------------------------
$(target_out):$(objs)
	echo $(addsuffix /lib, $(addprefix $(MOD_DIR)/, $(MOD)))
	@mkdir -p $(addprefix $(build)/, $(srcdir))
	@mkdir -p $(outdir)
	$(CC) -o $(target_out) $(objs) $(INCLUDE) -Xlinker "-(" $(LIB) -Xlinker "-)" $(LDLAGS)
	@echo "-------------------------------------------"
	@echo "create $(target) successs."
	@echo "-------------------------------------------"

-include $(deps)

#-----------------------------------------------
# 生成.o文件的所有依赖关系
#-----------------------------------------------
$(build)/%.o: %.c
	@mkdir -p $(dir $@)
	$(CC) -c $(CFLAGS) $(INCLUDE) $< -o $@

#-----------------------------------------------
# 生成.d文件的所有依赖关系
#-----------------------------------------------
$(build)/%.d: %.c
	@set -e; mkdir -p $(@D); rm -f $@; \
	$(CC) -MM $(CFLAGS) $(INCLUDE) $< > $@.$$$$; \
	sed 's,\($(*F)\)\.o[ :]*,$(build)/$(<D)/\1.o $@ : ,g' < $@.$$$$ > $@; \
	rm -f $@.$$$$;\

#echo "generate dependencies $(@F) ."

.PHONY: clean clean_all

clean_all:
	-@rm -rf $(BUILD_DIR)

clean:
	@echo "cleanning ..."
	-@make -C $(MOD_DIR)/$(MOD) clean
	-@rm -f $(target_out) $(objs)
	@echo "clean completed."

子模块编译Makefile,子模块一般用于生成库。因此照着主程序的Makefile进行编写,根据需求进行简单修改。内容如下:

#------------------------------
# 生成程序名称
#------------------------------
target := app.a

#------------------------------
# 生成程序输出路径
#------------------------------
outdir := lib

#----------------------------------------
# 源文件路径(采用相对路径)
#----------------------------------------
srcdir := . src source

#----------------------------------------
# 头文件路径
#----------------------------------------
INCLUDE := -I./include 
INCLUDE += $(addprefix -I./, $(srcdir))

#----------------------------------------
# 编译参数
#----------------------------------------
CFLAGS := $(CFLAGS_ENV)

#------------------------------
# 编译前准备
#------------------------------
src := $(foreach d, $(srcdir), $(wildcard $(d)/*.c))
obj := $(src:.c=.o)
dep := $(src:.c=.d)
build := $(BUILD_DIR)/$(subst $(ROOT_DIR)/,,$(CURDIR)/)
objs := $(addprefix $(build)/, $(obj))
deps := $(addprefix $(build)/, $(dep))
target_out := $(outdir)/$(target)

all: $(target_out)

#-----------------------------------------------
# 生成静态库及依赖关系
#-----------------------------------------------
$(target_out):$(objs)
	@mkdir -p $(addprefix $(build)/, $(srcdir))
	@mkdir -p $(outdir)
	$(AR) -rc $@ $^
	@echo "-------------------------------------------"
	@echo "create $(target) successs."
	@echo "-------------------------------------------"

-include $(deps)

#-----------------------------------------------
# 生成.o文件的所有依赖关系
#-----------------------------------------------
$(build)/%.o: %.c
	@mkdir -p $(dir $@)
	$(CC) -c $(CFLAGS) $(INCLUDE) $< -o $@

#-----------------------------------------------
# 生成.d文件的所有依赖关系
#-----------------------------------------------
$(build)/%.d: %.c
	@set -e; mkdir -p $(@D); rm -f $@; \
	$(CC) -MM $(CFLAGS) $(INCLUDE) $< > $@.$$$$; \
	sed 's,\($(*F)\)\.o[ :]*,$(build)/$(<D)/\1.o $@ : ,g' < $@.$$$$ > $@; \
	rm -f $@.$$$$;\

#echo "generate dependencies $(@F) ."

.PHONY: clean clean_all

clean_all:
	-@rm -rf $(BUILD_DIR)

clean:
	@echo "cleanning ..."
	-@rm -f $(target_out) $(objs)
	@echo "clean completed."

和主程序的Makefile相比,少了全局变量和链接相关参数。
这样,子模块的Makefile对主程序没有产生依赖,因此,把这个库移动到其它地方,无需修改Makefile也是能编译的。

编译如下:
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在删除掉所有的文件夹后,我们也仅仅只需要把 all: module $(target_out)修改为all: $(target_out),编译照常运行,通用性非常的好。
添加子模块和主程序文件,只需要在对应的参数上加上文件夹即可。编译参数这些也是按需添加。
把这些东西做成模板,最后写个程序来生成这些模板,再也不用手写Makefile了。-.-

在这里插入图片描述

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值