自动构建Makefile(1)--C/C++编译流程&Makefile规则简介
前言:
大家在Windows上使用VS构建C/C++程序时,不需要自己编辑略显晦涩的Makefile文件,而对于初学者而言, 他们甚至没意识到它的存在。VS是自动生成Makefile文件, 并构建工程项目的。不可否认Visual Studio做为一款全能的IDE,它帮开发者做了很多工作,也降低了C/C++的门槛,意义非常的重大。
但作为进阶的C/C++开发者, 你是有必须了解底层编译和链接原理的。 让我们来梳理下C/C++的编译链接过程,并回顾Makefile的编写规则,最后让我们来尝试实现自动构建工程Makefile文件的机制。本文侧重讲解C/C++的编译过程和Makefile的规则,后文讲述如何实现Makefile的生成器。
编译C/C++程序
C/C++程序的生成, 分为如下几个步骤
1). 预处理: 引入头文件,解析并展开宏定义
2). 编译: 简单一点就是把源代码转化为汇编码(机器指令)
3). 链接: 组装各个子模块和相应的库,并生成最终的可执行程序

评注: 参数-E用于生成预处理后的c/c++文件, 参数-c用于生成编译后的二进制文件,参数-o则只是用于制定某个阶段的产出物名称
Makefile的基础规则
基本规则很简单:
<target> : <prerequisites>
<command>
评注: <target>是目标名称, <prerequisites>是依赖的列表项, <command>则是对应的执行命令
当然有些注意项:
1). Makefile第一项执行规则为默认的最终目标
2). 命令必须"\t"作为开头
Makefile常见的宏定义:
$^ 依赖项列表
$@ 目标对象
$< 依赖列表中的第一个对象
Makefile的变量定义和使用, 如下所示:
CC = g++
CFLAG = -g -WALL app: main.cpp
$(CC) $(CFLAG) -o $@ $^
评注:变量CC/CFLAG展示了Makefile的定义和引用语法
伪目标对象的引入, 对于make clean特别有用
.PHONY : clean
clean:
-rm $(OBJECTS)
其实PHONY的引入, 是针对文件系统中,刚好有名为"clean"文件的特殊情形。各位看官, 你还记得大明湖畔的夏雨荷吗? 就是这种感觉
Makefile的小实战
对于如下工程:

include包含工程的头文件,src包含工程的C/C++文件
其具体的Makefile文件,可以编辑如下所示:
CC = g++
CFLAG = -g -Wall
OBJECTS := $(wildcard *.o) app : app.o cache.o
g++ $(CFLAG) -o $@ $^ app.o : src/app.cpp include/cache.h
g++ -c -o $@ src/app.cpp -Iinclude cache.o : src/cache.cpp include/cache.h
g++ -c -o $@ src/cache.cpp -Iinclude .PHONY : clean
clean:
-rm $(OBJECTS)
这个实战项目就算完成了, Makefile文件具备了它所需要的功能:生成/清理。
挑战
实战的工程还是比较小,手动维护Makefile还是相对简单的,那如果工程有上百个头文件/C文件呢?还有相关的依赖库?是不是很麻烦
如果说,增量去编写还能接受的话,那么时间一长,回过头来回顾,或者移交给他人,都是件麻烦的事, 是不是?
那能不能自动生成和维护该Makefile文件,它的核心思想是什么?又该如何去实现? 请期待下文......
自动构建Makefile(1)--C/C++编译流程&Makefile规则简介的更多相关文章
- esp8266 SDK开发之编译流程
最近刚完成自己8266的小项目,已经发布在github上,有兴趣的朋友可以看一下 github地址:esp-ujn 1. 通过MQTT协议与服务器交互 2. 内置HTTP服务器,支持通过浏览器进行参数 ...
- 实现自动构建编译javaweb项目并发布到N台服务器
前言 当你使用nginx实现了负载均衡,当你有了超过3台以上的应用服务器时,一个特别头疼的问题就来了,发布项目好麻烦. 你每次都要在本地编译打包一遍,然后手动复制到每一台服务器上面去,如果只有一两台服 ...
- 联盛德 HLK-W806 (十二): Makefile组织结构和编译流程说明
目录 联盛德 HLK-W806 (一): Ubuntu20.04下的开发环境配置, 编译和烧录说明 联盛德 HLK-W806 (二): Win10下的开发环境配置, 编译和烧录说明 联盛德 HLK-W ...
- 基于GitLab CI搭建Golang自动构建环境
基于GitLab CI搭建Golang自动构建环境 Golang发布遇到的问题 对于golang的发布,之前一直没有一套规范的发布流程,来看看之前发布流程: 方案一 开发者本地环境需要将环境变量文件改 ...
- 使用cmake自动构建工程
公司引擎是用cmake根据目标平台来构建工程的,刚接触的时候深深体会到cmake的方便:如果目标平台是windows,它可以帮你自动构建出vs工程:如果是安卓,自动构建出eclipse工程,如果是IO ...
- 利用ant脚本 自动构建svn增量/全量 系统程序升级包
首先请允许我这样说,作为开发或测试,你一定要具备这种 本领.你可以手动打包.部署你的工程,但这不是最好的方法.最好的方式就是全自动化的方式.开发人员提交了代码后,可以自动构建.打包.部署到测试环境. ...
- Gulp自动构建Web前端程序
这两天在一个朋友在项目上碰到了一个这样的问题,在运营过程中,用户在浏览器上对某个表单进行数据提交时,需要引入新的平台接口数据的业务,通过评估,开发团队马上修改了相关后台代码和部分的前端脚本代码,通过简 ...
- iOS 自动构建套件 - flow.ci + fir.im + Coding
编者按:本文转载自 flow.ci 用户 GitHub@mzying2013 的实践分享,原文链接这里. 前言 相信很多最开始接触自动构建都是从 Jenkins 开始的.都是纯手工搭建,本地代码创库也 ...
- 利用ant脚本 自动构建svn增量/全量 系统程序升级包【转】
引文:我们公司是做自己使用产品,迭代更新周期短,每次都花费较多时间和精力打包做增量更新,发现了一篇文章用于 自动构建svn增量/全量 系统程序升级包,收藏之,希望可以通过学习,更加简化我们的工作. 文 ...
随机推荐
- Time, Clocks, and the Ordering of Events in a Distributed System
作者:Leslie Lamport(非常厉害的老头了) 在使用消息进行通信的分布式系统中,使用物理时钟对不同process进行时间同步与事件排序是非常困难的.一是因为不同process的时钟有差异,另 ...
- 用PHP做服务器接口客户端用http协议POST访问安全性一般怎么做
我的问题是,如果不做安全相关处理的话,一些可能改变数据库的操作可能会遭遇垃圾数据提交什么的,毕竟要找到这些信息只要找个http包就可以了 系统无用户登录 新手问题(从来没做过服务端开发),如果可以,给 ...
- Pogo-Cow
题目大意: 给出直线上N个点的坐标和分数,任意选一个点出发,每次只能跳到另外一个点上并获得相应的分数,且每次跳的方向要相同,本次跳的距离不小于上次跳的距离. 求最大得分. N<=1000. ...
- 一模 (5) day1
第一题: 题目大意:求出1-10^n 这些数中,包含数字3的有多少个. n<=1000: 解题过程: 1.这题一看就是高精度+递推..如果n=1000,那么假设个位是3,其他999位任意..那么 ...
- 如何让DIV在窗口水平和垂直居中
本实例以新文档开始 2 先放置一个div,并且设置class名为aa,赋予它css属性: width:0;height:0;position:fixed;left:50%;rigth:50%;top: ...
- “System.Threading.ThreadAbortException”类型的第一次机会异常在 mscorlib.dll 中发
问题原因: Thread.Abort 方法 .NET Framework 4 其他版本 1(共 1)对本文的评价是有帮助 - 评价此主题 在调用此方法的线程上引发 ThreadAbortExce ...
- SharedPreference 存储小量数据,一般首次启动显示引导界面就用这个。
写://添加一个SharedPreference并传入数据SharedPreference sharedPreferences = getSharedPreferences("share_d ...
- Matlab与C/C++联合编程之Matlab以MEX方式调用C/C++代码(二)
如果我有一个用C语言写的函数,实现了一个功能,如一个简单的函数: double add(double x, double y) { return x + y; } 现在我想要在Matlab中使用它,比 ...
- A380上11万一张的机票什么享受?来看看
上个月底,全球奢华航班排行榜出炉,新加坡航空头等舱荣登第一.不过,比头等舱更豪奢的,将近两万美元一张往返票的“套间”又是怎么样的呢? 新加坡航空的一名常旅客Derek Low就体验了一把全球最豪奢的坐 ...
- 记录一些容易忘记的属性 -- NSTimer
使定时器停止的方法: 1. //将定时器的启动时间设置为很久以后的将来,到这个时间,定时器才会开始工作 [_timer setFireDate:[NSDate distantFu ...