在桌面系统上开发常使用VS、eclipse、Keil等IDE,编译点一下按钮,就可以完成。但在无桌面的服务器上开发,改怎么做?而编译内部是怎么实现的?改动文件后如何增量文件?掌握Makefile文件写法就可以得到答案。

1、Makefile是什么

Makefile定义了整个工程的编译规则,一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作,因为makefile就像一个Shell脚本一样,其中也可以执行操作系统的命令。makefile带来的好处就是——“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。make是一个命令工具,是一个解释makefile中指令的命令工具,一般来说,大多数的IDE都有这个命令,比如:Delphi的make,Visual C++的nmake,Linux下GNU的make。不同厂商的make各不相同,也有不同的语法,但其本质都是在“文件依赖性”上做文章,这里,我仅对GNU的make进行讲述,必竟,这个make是应用最为广泛的,也是用得最多的。而且其还是最遵循于IEEE 1003.2-1992 标准的(POSIX.2)。

2、Makefile的主要架构

3、一个简单Makefile示例

TARGET := testCC := g++ #注意每行后面不要有空格,否则会算到目录名里面,导致问题
SRC_DIR = src
BUILD_DIR = tmp
OBJ_DIR = $(BUILD_DIR)/obj
DEPS_DIR  = $(BUILD_DIR)/deps#这里添加其他头文件路径
INC_DIR = \-I./include \-I./src \#这里添加编译参数
CC_FLAGS := $(INC_DIR) -g -std=c++11
LNK_FLAGS := \-L/usr/local/lib #这里递归遍历3级子目录
DIRS := $(shell find $(SRC_DIR) -maxdepth 3 -type d)#将每个子目录添加到搜索路径
VPATH = $(DIRS)#查找src_dir下面包含子目录的所有cpp文件
SOURCES   = $(foreach dir, $(DIRS), $(wildcard $(dir)/*.cpp))
OBJS   = $(addprefix $(OBJ_DIR)/,$(patsubst %.cpp,%.o,$(notdir $(SOURCES))))
DEPS  = $(addprefix $(DEPS_DIR)/, $(patsubst %.cpp,%.d,$(notdir $(SOURCES))))  $(TARGET):$(OBJS)$(CC) $^ $(LNK_FLAGS) -o $@#编译之前要创建OBJ目录,确保目录存在
$(OBJ_DIR)/%.o:%.cpp@if [ ! -d $(OBJ_DIR) ]; then mkdir -p $(OBJ_DIR); fi;$(CC) -c $(CC_FLAGS) -o $@ $<#编译之前要创建DEPS目录,确保目录存在
#前面加@表示隐藏命令的执行打印
$(DEPS_DIR)/%.d:%.cpp@if [ ! -d $(DEPS_DIR) ]; then mkdir -p $(DEPS_DIR); fi;\set -e; rm -f $@;$(CC) -MM $(CC_FLAGS) $< > $@.$$$$;sed 's,\($*\)\.o[ :]*,$(OBJ_DIR)/\1.o $@ : ,g' < $@.$$$$ > $@;\rm -f $@.$$$$
#前面加-表示忽略错误-include $(DEPS)
.PHONY : clean
clean:rm -rf $(BUILD_DIR) $(TARGET)

参考文档2 中的例子,中间文件放在tmp目录下,直接在根目录执行make;

root@ubuntu:~/projects/MakeFileProject1# tree .
.
├── makefile
├── src
│   └── main.cpp
├── test
└── tmp
    ├── deps
    │   └── main.d
    └── obj
        └── main.o

4、Reference

玩转Makefile | 系列综述
makefile将中间文件生成到临时目录
Makefile教程(绝对经典,所有问题看这一篇足够了)

转载于:https://www.cnblogs.com/wnwin/p/11179960.html

Makefile(1):基本使用相关推荐

  1. 浅显易懂 Makefile 入门 (12)— Makefile 常见的错误信息

    1. 常见的错误信息 make 执行过程中所产生错误并不都是致命的,特别是在命令行之前存在 -.或者 make 使用 -k 选项执行时. make 执行过程的致命错误都带有前缀字符串 ***.错误信息 ...

  2. 浅显易懂 Makefile 入门 (10)— 嵌套执行 make、export 的使用

    1. 嵌套执行 make 在一个大的工程文件中,不同的文件按照功能被划分到不同的模块中,每个模块可能都会有自己的编译顺序和规则,如果在一个 Makefile 文件中描述所有模块的编译规则,就会很乱,执 ...

  3. 浅显易懂 Makefile 入门 (09)— include 文件包含、MAKECMDGOALS

    1. include文件包含 当 make 读取到 include 关键字的时候,会暂停读取当前的 Makefile,而是去读 include 包含的文件,读取结束后再继读取当前的 Makefile ...

  4. 浅显易懂 Makefile 入门 (08)— 默认 shell (/bin/sh)、命令回显、make参数(-n 只显示命令但不执行,-s 禁止所有回显)、单行命令、多行命令、并发执行

    1. shell 相关 1.1 默认 shell Makefile 所使用的命令是由 shell 命令行组成,他们是一条一条执行的. 多个命令之间要使用分号隔开,Makefile 中的任何命令都要以 ...

  5. 浅显易懂 Makefile 入门 (07)— 其它函数(foreach 、if、call、origin )

    1. foreach 函数 foreach 函数定义如下: $(foreach <var>,<list>,<text>) 函数的功能是:把参数 <list&g ...

  6. 浅显易懂 Makefile 入门 (06)— 文件名操作函数(dir、notdir、suffix、basename、addsuffix、addperfix、join、wildcard)

    编写 Makefile 的时候,很多情况下需要对文件名进行操作.例如获取文件的路径,去除文件的路径,取出文件前缀或后缀等等. 注意:下面的每个函数的参数字符串都会被当作或是一个系列的文件名来看待. 1 ...

  7. 浅显易懂 Makefile 入门 (03)— 目标文件搜索(VPATH 和 vpath 的区别和使用)、隐含规则

    1. 目标文件搜索(VPATH和vpath) 如果需要的文件是存在于不同的路径下(即源文件与 Makefile 文件不在同一个路径下),在编译的时候就用到了 Makefile 中为我们提供的目录搜索文 ...

  8. 浅显易懂 Makefile 入门 (02)— 普通变量和自动变量定义、使用($@、$^、$< 作用)、变量覆盖 override、变量的来源 origin

    1. 变量的定义 Makefile 文件中定义变量的基本语法如下: 变量的名称=值列表 变量的名称可以由大小写字母.阿拉伯数字和下划线构成.等号左右的空白符没有明确的要求,因为在执行 make 的时候 ...

  9. 浅显易懂 Makefile 入门 (01)— 什么是Makefile、为什么要用Makefile、Makefile规则、Makefile流程如何实现增量编译

    1. 什么是 Makefile Makefile 文件描述了 Linux 系统下 C/C++ 工程的编译规则,它用来自动化编译 C/C++ 项目.一旦写编写好 Makefile 文件,只需要一个 ma ...

  10. Android 的NDK的Makefile编写

    Android.mk 是google根据Linux GNU Makefile精简编译脚本.具体来说:这就是GNU Makefile的一小部分. 举一个简单例子: LOCAL_PATH := $(cal ...

最新文章

  1. 新雨个人面试经验总结
  2. CISCO NAT 配置
  3. linux 切图软件下载,学会23个linux常用命令,不做前端切图仔~
  4. 从Mixin到hooks,谈谈对React16.7.0-alpha中即将引入的hooks的理解
  5. WIFI篇(3.python破解wifi--pywifi的介绍)
  6. matlab线性同余发生器,用MATLAB进行随机数模拟--线性同余法
  7. 目标检测_CVPR2020
  8. C++异常处理的问题
  9. 你还不知道高情商表现怎么表现?
  10. 细胞工程1、2-实验室组成与无菌操作
  11. 联想服务器安装系统 F11,教你联想thinkpad系统还原f11一键恢复方法
  12. Kali离线安装Nessus及过程中可能遇到的问题解决方案
  13. leetcode——回溯
  14. 微信授权登陆接入第三方App(步骤总结)Android。
  15. php 邮件上传类阿里云邮件上传接口
  16. 当button具有disabled属性时,el-tooltip也失效。解决办法
  17. Spring学习笔记(完结)
  18. python 变量前怎么加r
  19. kermit的安装和配置
  20. 【有料】面试必备:什么时候要打破双亲委派机制?什么是双亲委派? (图解+秒懂+史上最全)

热门文章

  1. python网络编程之 一 socket(套接字)
  2. ASP.NET获取真正的客户端IP地址的6种方法
  3. 换手率与股价成交量 关系
  4. [深度学习-实战篇]情感分析之卷积神经网络-TextCNN,包含代码
  5. 深度学习-函数-tf.nn.embedding_lookup 与tf.keras.layers.Embedding
  6. 马士兵 redis 百度网盘_西甲周六攻略:巴萨 马竞 塞维利亚出战
  7. 【图像处理】直方图均衡化(附带Matlab及OpenCV3自编程实现代码)
  8. 【C++】C++类的学习(二)——构造函数、析构函数、拷贝构造函数以及this指针
  9. 基于狄利克雷-多项式分布做文档聚类代码(dirichlet multinomial mixture model)
  10. 基于Kmeans算法的文档聚类(包含Java代码及数据格式)