自动构建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文件,它的核心思想是什么?又该如何去实现? 请期待下文......

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。