文章目录

1. 一点说明

2. 顶层目录的Makefile模板

3. 顶层目录的共通设定

4. 子目录中的Makefile模板

5. 应用实例

6. 后记


1. 一点说明

如果要使用Makefile编译一个工程,则需要使用多个Makefile文件共同作用才比较合理。工程中的每个目录都有一个Makefile文件,负责编译当前目录的源文件,然后将编译好的对象文件打包,供上一级的Makefile使用。经过学习各种资料,在这里记录一种多个Makefile文件共同编译工程的模板,以供学习和查看。

2. 顶层目录的Makefile模板

顶层目录的Makefile模板的内容如下,附上代码的说明,便于更好的理解和记忆,文件名为Makefile,放在顶层目录中。

#最终目标名称定义
TGT := main
#顶层目录的获取,export关键字,表面TOP_DIR在子目录中可以使用,相当于全局变量,
#否则,定义的变量仅在本文件中有用
export TOP_DIR := $(shell pwd)
#导入子MaKefile文件,Header.mk是放在顶层目录中,用来导入.h文件
-include $(TOP_DIR)/Header.mk
#CXXFLAGS是Makefile的环境变量,用来定义编译选项
CXXFLAGS := -Wall -O2
#SUB_DIR是自定义变量,记录工程中当前目录的子目录
SUB_DIR := src
# SUB_TGT是当前目录各个文件编译后,打包所得的文件的命名,当然,它也是自定义变量,
# 并且是全局变量,因为以下每一个目录的打包名称都可以叫‘build_in.o’这个统一的名称
#,这么做是为了方便起见,你也可以为每一个目录起一个不同的名字。
export SUB_TGT := bulid_in.o
# SRC和OBJ都是自定义名称,SRC是取得当前目录中的.cpp文件的名称,wildcard是Makefile
# 内置的函数,为了获取当前目录中满足一定条件的文件的名称,patsubst也是内置函数,它是替
# 函数,利用已知后缀名的一些列的文件名,转换得到另一后缀名的一系列系同名文件。本Makefile
# 中就是.cpp的文件,换成.o的文件
SRC := $(wildcard *.cpp)
OBJ := $(patsubst %.cpp,%.o,$(SRC))# all是伪目标
all:$(TGT)@echo "make successfull [0]"#总目标的依赖关系,总目标依赖当前文件的.o文件和子目录打包后的目标build_in.o
#其中$(SUB_DIR:=/$(SUB_TGT))表示各子目录下的build_in.o
$(TGT):$(OBJ) $(SUB_DIR)$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(OBJ) $(SUB_DIR:=/$(SUB_TGT))  -o $@
#调用各个子目录中的子Makefile,$@代表依赖关系中的目标
$(SUB_DIR):$(MAKE) -C $@#当前目录下各个文件的编译目标和源文件的依赖关系,$<代表依赖关系中被依赖的各个文件的统称。
%.o:%.cpp$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $< -o $@# 依赖关系生成.d文件中记录着。o依赖.cpp和.h文件的关系,书写此依赖关系,是为了防止修改.h
# 文件,对应的.o文件没有重新编译,进而导致整个总目标没有正确的编译
%.d:%.cpp$(CXX) $(CPPFLAGS) $(CXXFLAGS) -MM $< -o $@#导入上一步生成的.d中记录的关系
sinclude $(SRC:.cpp=.d)#伪目标,是为了重新编译的方便,清楚编译所产生的所有文件
clean:$(RM) $(TGT) $(OBJ) $(SRC:.cpp=.d)$(MAKE) -C $(SUB_DIR) $@            #调用子目录中的clean@echo "clean successful[0]"#伪目标的声明
.PHONY:all clean $(SUB_DIR)

3. 顶层目录的共通设定

顶层目录的共通设定的目的是设定编译选项变量CPPFLAGS, 用此变量累计各个模块的.h文件,文件名Header.mk,放在顶层目录中,代码示例如下

CPPFLAGS := -I.
CPPFLAGS += -I$(TOP_DIR)
CPPFLAGS += -I$(TOP_DIR)/src
...

4. 子目录中的Makefile模板

值得说明的是,各个子目录中的Makefile的内容可以是相同的,如果子目录下还有子目录,即二级或三级子目录,可以参考顶层的目录继续调用其下一级的子目录中的Makefile,以下给出的是子目录中没有二级或三级子目录的Makefile的写法。文件名同样是Makefile,放在了各个子目录中。

#导顶层目录中共通设定Header.mk
-include $(TOP_DIR)/Header.mk#----get common files---
SRC := $(wildcard *.cpp)
OBJ := $(SRC:.cpp=.o)
DEP := $(SRC:.cpp=.d)# 打包各文件的编译对象,得到build_in.o
$(SUB_TGT):$(OBJ)$(LD) -r $^ -o $@#获取各文件对应的.d文件
$(DEP):$(SRC)$(CXX) $(CXXFLAGS) $(CPPFLAGS) -MM $< -o  $@#导入d文件记录的依赖关系,即.o对.cpp和.h的依赖
sinclude $(DEP)clean:$(RM) *.o *.d $(SUB_TGT).PHONY:clean

5. 应用实例

应用示例见

一个组合模式的例子+makefile模板_青草地溪水旁的博客-CSDN博客

6. 后记

上述记录的模板,可以应用在项目中,非常方便,在套用的过程中,如果出错,需要慢慢调试,在调试的过程中学习Makefile,会学得更踏实,凡知识和技能都是在应用过程时摸爬滚打中,才能真正的掌握。

工程级Makefile编译模板相关推荐

  1. 交互系统的构建之(一)重写Makefile编译TLD系统

    交互系统的构建之(一)重写Makefile编译TLD系统 zouxy09@qq.com http://blog.csdn.net/zouxy09 为了对TLD系统做一些功能的填充,例如添加语音合成来提 ...

  2. make的使用及Makefile万能模板

    make的使用及Makefile万能模板 前言 为什么用make make的使用 Makefile万能模板 前言 gcc 的编译,是将源码生成可执行程序. 例如: gcc hello.c -o hel ...

  3. ARM学习(15)Makefile编译以及CortexM4命令行STLINK 烧录

    笔者来聊聊Makefile编译以及CortexM4命令行STLINK 烧录 Makefile编译以及CortexM4命令行STLINK 烧录 1.简单Makefile编译STM32工程 1.1 mak ...

  4. Mac 从Makefile 编译 Rocksdb 源码的一些注意事项

    文章目录 前言 Makefile 编译流程 1. 平台变量/环境变量的初始化. 2. 编译需要的源码文件变量初始化. 3. include 目录的设置. 4. 编译的执行逻辑. 问题记录1:可能的打包 ...

  5. linux makefile 编译标记 EXTRA_CFLAGS 简介

    1.介绍 EXTRA_CFLAGS,  EXTRA_AFLAGS,  EXTRA_LDFLAGS,  EXTRA_ARFLAGS 所有的EXTRA_变量只能使用在定义该变量后的makefile文件中. ...

  6. 机器视觉:makefile编译调用Caffe框架的C++程序

    Caffe作为在众多公司搞深度学习时较多使用的框架,其在使用的友好程度上显然要比后起的一些深度学习框架要差一些,虽然如此,其作为深度学习的第一个开源框架,自有它的很多优势,比如设计结构.关于Caffe ...

  7. 在windows下写makefile编译代码

    From: http://blog.163.com/xjming487@126/blog/static/212951352007625114849843/ 在windows下写makefile编译代码 ...

  8. 加快linux编译速度,Linux Makefile 编译速度的优化【转】

    前言 如何提高 Makefile 的编译速度呢?既然是提高,那肯定是对于大项目而言,因为小项目本身源文件不多,Makefile 优化与否,对于编译速度而言,影响并不大.当然对于那些追求速度达到极致的人 ...

  9. Makefile编译忽略warning或者将warning视为error

    在Makefile编译命令后面: 添加 -w(小写) 可以忽略warning: 添加 -Werror 可以将warning当作error,出现warning时停止编译; 添加 -Wall 可以输出所有 ...

最新文章

  1. 连续八个季度双位数增长,这家公司业务成功得不像技术派
  2. Python学习之并发基础知识
  3. datax导入MySQL报错_导入MySQL方法对比
  4. 前端学习(1802):前端调试之事件伪类练习
  5. 杭电2066--一个人的旅行(Floyd)
  6. Android各个版本API的区别
  7. 如何以子类的形式运行多进程?
  8. UnityShader19.1:渲染纹理(下)之GrabPass
  9. 【JOURNAL】《题虾壶》
  10. windows 编写的硬件驱动_黑科技or大势所趋?谈谈手机GPU驱动升级那点事
  11. Java集合框架关系图
  12. Windows Security Center注册分析
  13. 五点菱形格式MATLAB,五点菱形格式-拉普拉斯第一边值问题-计算实习报告.docx
  14. python3 练习题 day02
  15. 键盘快捷键使用,背熟这些你就无需再用鼠标了!
  16. 软件质量管理体系 type:pdf_荆门医疗器械软件注册价格,三类医疗器械注册_上海峦灵...
  17. 51单片机制作脉冲发生器
  18. 【app测试】adb常用指令及华为卸载预置软件
  19. rpm包制作之openssh8.7升级
  20. db2 reorg详解

热门文章

  1. 利用python制作简单播放器
  2. java 发送 mail 纯文本发送和html格式发送
  3. 阿里云ARMS渲染速度指标
  4. lz77优化_与熊论道(熊曰加密)算法更新和界面优化
  5. starUML工具使用简介
  6. qq无法修改个人资料的解决方法 手机qq编辑资料失败如何解决
  7. Linux内核活动之中断1
  8. 基于C++OpenGL实现的小桌茶壶纹理图形绘制
  9. PageAdmin环境配置要求
  10. android 8.0 nexus7,Android 7.0即将推送 Nexus用户最迟8月22日更新