万能makefile深入浅出 - 第三篇

    xiaoxiao2021-03-25  152

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

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

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

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

    5. 如有任何疑问,可联系本人QQ:279533105,添加时请注明来自

    以下是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

     

     

     

     

     

     

    转载请注明原文地址: https://ju.6miu.com/read-3245.html

    最新回复(0)