首页 > 其他分享 >万能makefile深入浅出 - 第三篇

万能makefile深入浅出 - 第三篇

时间:2022-12-14 11:33:58浏览次数:42  
标签:BIN 第三篇 LIB make 深入浅出 makefile PROJECT EXE NAMES


1. 本示例演示的是需链接动态库静态库,且需先编译库的makefile的编写方式(自己写的简单动态库编译和使用,自己写的简单静态库的编译和使用)

2. 目的是帮助那些新接触makefile的新手如何快速写出可用的makefile,下载本例后完全可以稍作修改就可以满足自己的需要

3. 本篇博客逐条语句分析了万能makefile的实现,尽可能多的添加了注释,也在一些地方进行了修改,以用于不同情况下makefile的编写

4. 所有示例都在centos上亲测编译,运行通过的,附上完整示例下载链接,下载解压后,根目录中有介绍文档,请务必按照里面的步骤操作,保证可以运行成功

5. 如有任何疑问

以下是makefile的内容(空间有限,这里仅贴出主makefile的代码),如发现错误,欢迎拍砖

 

#用于定义本项目中各个工程(库工程,可执行程序工程)的Makefile所在路径以及它们之间的依赖关系

# 项目根目录,下面" PROJECT_ROOT := .. "的意思是项目的根目录在本目录的上一级目录
PROJECT_ROOT := ..

# 习惯:LIB开头的为库文件工程所在的目录,BIN开头的为可执行程序工程所在的目录
LIB_DYNAMIC_LIB := $(PROJECT_ROOT)/dynamic_lib # 备注:本项目中的动态库示例工程所在目录,名字随意
LIB_STATIC_LIB := $(PROJECT_ROOT)/static_lib # 备注:本项目中的静态库示例工程所在目录,名字随意
BIN_EXAMPLE_EXE := $(PROJECT_ROOT)/use_lib_example # 备注:本项目中使用动态库,静态库的示例程序工程所在目录,名字随意

# 执行 make clean时伪目标中用到的名字集合(即库工程,可执行程序工程所在路径的名字)
# 注意后面都加了"_CLEAN" ,目的是为了不与其他伪目标名字重复,对应每个库所在的路径,每个可执行程序所在的路径
# 具体值仍为路径,当执行该伪目标时,需要先跳转到该目录,再执行 make clean 命令
LIB_DYNAMIC_LIB_CLEAN := $(LIB_DYNAMIC_LIB)
LIB_STATIC_LIB_CLEAN := $(LIB_STATIC_LIB)
BIN_EXAMPLE_EXE_CLEAN := $(BIN_EXAMPLE_EXE)

# 执行 make veryclean时伪目标中用到的名字集合(即库文件,可执行程序所在的路径的名字)
# 注意后面都加了"_VERYCLEAN" ,目的是为了不与其他伪目标名字重复,对应每个库所在的路径,每个可执行程序所在的路径
# 具体值仍为路径,当执行该伪目标时,需要先跳转到该目录,再执行 make veryclean 命令
LIB_DYNAMIC_LIB_VERYCLEAN := $(LIB_DYNAMIC_LIB)
LIB_STATIC_LIB_VERYCLEAN := $(LIB_STATIC_LIB)
BIN_EXAMPLE_EXE_VERYCLEAN := $(BIN_EXAMPLE_EXE)

# 所有的各个工程(库工程,可执行程序工程)所在路径的名字
# 注意:PROJECT_NAMES是下面伪目标的名字,最终是要执行的
PROJECT_NAMES := LIB_DYNAMIC_LIB \
LIB_STATIC_LIB \
BIN_EXAMPLE_EXE

# clean时的所有工程所在路径的名字集合
# 函数 addsuffix _加后缀函数,示例:$(addsuffix .c,foo bar)返回值是foo.c bar.c
# 由上面的 PROJECT_NAMES 定义,
# 注意: PROJECT_NAMES_CLEAN是下面伪目标的名字,最终是要执行的
PROJECT_NAMES_CLEAN := $(addsuffix _CLEAN, $(PROJECT_NAMES))

# veryclean时的所有工程所在路径的名字集合
PROJECT_NAMES_VERYCLEAN := $(addsuffix _VERYCLEAN, $(PROJECT_NAMES))

# 所有的伪目标,.PHONY用来声明所有的伪目标
# 当执行make all 时,由于伪目标all依赖于$(PROJECT_NAMES),所以会先执行伪目标$(PROJECT_NAMES),即执行其命令 $(MAKE) -C $($@),也就是进入到每个目录去执行make
.PHONY: all $(PROJECT_NAMES) clean $(PROJECT_NAMES_CLEAN) veryclean $(PROJECT_NAMES_VERYCLEAN)

all : $(PROJECT_NAMES)
clean : $(PROJECT_NAMES_CLEAN)
veryclean : $(PROJECT_NAMES_VERYCLEAN)

# 切换到指定的目录,再执行make操作,-C表示进入后面的目录,$($@)表目前规则中所有目标的集合
# 以 LIB_DYNAMIC_LIB 为例,已知上面定义LIB_DYNAMIC_LIB := $(PROJECT_ROOT)/dynamic_lib
# 执行时下面的命令显示为:
# make -C ../dynamic_lib
# make[1]: Entering directory `/home/make_test/make3/dynamic_lib'
# make[1]: Leaving directory `/home/make_test/make3/dynamic_lib'

$(PROJECT_NAMES) :
$(MAKE) -C $($@)

# 切换到指定的目录,再执行make clean操作
$(PROJECT_NAMES_CLEAN) :
$(MAKE) -C $($@) clean

# 切换到指定的目录,再执行make veryclean操作
$(PROJECT_NAMES_VERYCLEAN) :
$(MAKE) -C $($@) veryclean

# 所有的工程名字(目标名字)的依赖关系,也是使用伪目标的依赖来实现的
# 以下面一行的 BIN_EXAMPLE_EXE 为例,表示 BIN_EXAMPLE_EXE 依赖于LIB_DYNAMIC_LIB和LIB_STATIC_LIB
# 要生成目标BIN_EXAMPLE_EXE ,必须先生成后面的目标 LIB_DYNAMIC_LIB 和 LIB_STATIC_LIB
# 这样的话,当生成 BIN_EXAMPLE_EXE的时候,如果其依赖项还未生成,则会先去执行生成依赖项的命令
BIN_EXAMPLE_EXE : LIB_DYNAMIC_LIB LIB_STATIC_LIB

 

 

 

 

 

 

标签:BIN,第三篇,LIB,make,深入浅出,makefile,PROJECT,EXE,NAMES
From: https://blog.51cto.com/u_15912066/5936285

相关文章