前言:
  大家在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规则简介的更多相关文章

  1. esp8266 SDK开发之编译流程

    最近刚完成自己8266的小项目,已经发布在github上,有兴趣的朋友可以看一下 github地址:esp-ujn 1. 通过MQTT协议与服务器交互 2. 内置HTTP服务器,支持通过浏览器进行参数 ...

  2. 实现自动构建编译javaweb项目并发布到N台服务器

    前言 当你使用nginx实现了负载均衡,当你有了超过3台以上的应用服务器时,一个特别头疼的问题就来了,发布项目好麻烦. 你每次都要在本地编译打包一遍,然后手动复制到每一台服务器上面去,如果只有一两台服 ...

  3. 联盛德 HLK-W806 (十二): Makefile组织结构和编译流程说明

    目录 联盛德 HLK-W806 (一): Ubuntu20.04下的开发环境配置, 编译和烧录说明 联盛德 HLK-W806 (二): Win10下的开发环境配置, 编译和烧录说明 联盛德 HLK-W ...

  4. 基于GitLab CI搭建Golang自动构建环境

    基于GitLab CI搭建Golang自动构建环境 Golang发布遇到的问题 对于golang的发布,之前一直没有一套规范的发布流程,来看看之前发布流程: 方案一 开发者本地环境需要将环境变量文件改 ...

  5. 使用cmake自动构建工程

    公司引擎是用cmake根据目标平台来构建工程的,刚接触的时候深深体会到cmake的方便:如果目标平台是windows,它可以帮你自动构建出vs工程:如果是安卓,自动构建出eclipse工程,如果是IO ...

  6. 利用ant脚本 自动构建svn增量/全量 系统程序升级包

    首先请允许我这样说,作为开发或测试,你一定要具备这种 本领.你可以手动打包.部署你的工程,但这不是最好的方法.最好的方式就是全自动化的方式.开发人员提交了代码后,可以自动构建.打包.部署到测试环境. ...

  7. Gulp自动构建Web前端程序

    这两天在一个朋友在项目上碰到了一个这样的问题,在运营过程中,用户在浏览器上对某个表单进行数据提交时,需要引入新的平台接口数据的业务,通过评估,开发团队马上修改了相关后台代码和部分的前端脚本代码,通过简 ...

  8. iOS 自动构建套件 - flow.ci + fir.im + Coding

    编者按:本文转载自 flow.ci 用户 GitHub@mzying2013 的实践分享,原文链接这里. 前言 相信很多最开始接触自动构建都是从 Jenkins 开始的.都是纯手工搭建,本地代码创库也 ...

  9. 利用ant脚本 自动构建svn增量/全量 系统程序升级包【转】

    引文:我们公司是做自己使用产品,迭代更新周期短,每次都花费较多时间和精力打包做增量更新,发现了一篇文章用于 自动构建svn增量/全量 系统程序升级包,收藏之,希望可以通过学习,更加简化我们的工作. 文 ...

随机推荐

  1. libpcap文件格式分析

    第一部分:PCAP包文件格式 一 基本格式: 文件头 数据包头数据报数据包头数据报...... 二.文件头: 文件头结构体  sturct pcap_file_header  {       DWOR ...

  2. 一模 (2) day2

    第一题: 题目大意:给出n种物品和每种物品的件数,求拿k件的方案数.N<=30 解题过程: 1.一开始总想着是组合数学的模型,结果怎么都想不出来..然后写了个爆搜,数据很弱,只有1个点超时. 2 ...

  3. NOIP 2001解题报告

    第一题:  有形如:ax3+bx2+cx+d=0  这样的一个一元三次方程.给出该方程中各项的系数(a,b,c,d  均为实数),并约定该方程存在三个不同实根(根的范围在-100至100之间),且根与 ...

  4. visualsvn server 安装提示无法启动

    需要在服务里面给visualsvn server 用本地账户登陆权限

  5. Tasklist and TaskKill

    C:\Users\Administrator>tasklist /? TASKLIST [/S system [/U username [/P [password]]]]         [/M ...

  6. Android文件Apk下载变ZIP压缩包

    在azure云存储中 上传apk文件 使用ie下载 变成zip压缩包 解决方法 编辑 blob 属性和元数据 修改 内容类型 为 application/vnd.android.package-arc ...

  7. NSString的几种常用方法

    NSString的几种常用方法   要把 “2011-11-29” 改写成 “2011/11/29”一开始想用ios的时间格式,后来用NSString的方法搞定. [string stringByRe ...

  8. Bayeux

    Bayeux是一种用来在客户端和服务器端传输低延迟的异步消息(主要通过http)的一种协议.它定义的消息通过命名通道进行路由并且能够进行交互传 送:server -> client, clien ...

  9. 2016-1-10 手势解锁demo的实现

    一:实现自定义view,在.h,.m文件中代码如下: #import <UIKit/UIKit.h> @class ZLLockView; @protocol ZLLockViewDele ...

  10. 桟的min实现:O(1)时间复杂度

    实现桟的push和pop操作,以及桟的min操作返回桟中的最小值,要求这三个操作的时间复杂度均为O(1). 在Java中可以使用LinkedList实现桟的各种操作,这里使用双向链表实现桟的push和 ...