Linux下C/C++开发必备技能_Makefile项目管理

Linux环境下的程序员如果不会使用GNU make来构建和管理自己的工程,应该不能算是一个合格的专业程序员,至少不能称得上是 Unix 程序员

在 Linux(unix)环 境下使用 GNU 的 make 工具能够比较容易的构建一个属于你自己的工程,整个工程的 编译只需要一个命令就可以完成编译、连接以至于最后的执行。不过这需要我们投入一 些时间去完成一个或者多个称之为 Makefile 文件的编写。

在执行 make 之前,需要一个命名为 Makefile 文件来告诉 make 需要做什么(完成什么任务),该 怎么做。通常,make 工具主要被用来进行工程编译和程序链接。

当使用 make 工具进行编译时,工程中以下几种文件在执行 make 时将会被编译(重新编译):

1.所有的源文件没有被编译过,则对各个C源文件进行编译并进行链接,生成最 后的可执行程序;

2.每一个在上次执行make之后修改过的C源代码文件在本次执行make时将会 被重新编译;

3.头文件在上一次执行make之后被修改。则所有包含此头文件的C源文件在本 次执行 make 时将会被重新编译。

后两种情况是 make 只将修改过的 C 源文件重新编译生成 .o 文件,对于没有修改 的文件不进行任何工作。重新编译过程中,任何一个源文件的修改将产生新的对应的 .o 文件,新的 .o 文件将和以前的已经存在、此次没有重新编译的 .o 文件重新连接生成最 后的可执行程序。

总得来说Makefile的用途:

1,项目代码编译管理
2,节省编译项目时间
3,一次编写终身受益
4,操作实例文件:add.c sub.c mul.c dive.c main.c
Makefile是由一组规则组成的,规则如下
目标:依赖
(tab)命令

#例如:
add.o:add.c
(一个tab缩进)gcc -Wall -g -c add.c -o add.o

目标:要生成的目标文件

依赖:目标文件由哪些文件生成

命令:通过执行该命令由依赖文件生成目标

Makefile工作原理

基本原则:

  1. 若想生成目标,检查规则中的依赖条件是否存在,若不存在,就寻找是否有规则用来生成依赖文件
  2. 检查规则中的目标是否需要更新,必须先检查他的所有依赖,依赖中有任一个被更新,则目标必须更新

分享各个目标和依赖之间的关系

根据依赖关系自底向上执行命令

根据修改文件最后修改时间如果比目标文件新,那么就确定更新

如果目标不依赖任何条件,则执行对应命令,以示更新

Makefile变量

在makefile中使用变量有点类似于 C语言中的宏定义,使用该变量相当于内容替换,使用变量可以是makefile抑郁维护,修改内容变得简单。

变量的定义和使用:

foo = abc #变量定义之间使用 ‘=’
bar = $(foo)  #使用变量值用 $(变量名)

定义了两个变量foo和bar,其中bar的值是foo变量值的引用。

通常我们在makefile中会定义一些变量,方便makefile的修改维护

src = main.c func1.c func2.c 
CC = gcc #arm-linux-gcc
CPPFLAGS :  C预处理的选项 如:-I 
CFLAGS :  C编译器的选项 –Wall –g -c 
LDFLAGS :  链接器选项 –L -l

自动变量:

  1. $@ : 表示规则中的目标
  2. $< : 表示规则中的第一个条件
  3. $^ : 表示规则中的所有条件,组成一个列表,以空格隔开,如果这个列表中有重复的项则消除重复项。

模式规则:

至少在规则的目标定义中要包含‘%’,% 表示一个或者多个,在依赖条件中同样可以使用 ‘%’,依赖条件中的 % 的取值,取决于其目标。

%.o:%.c
$(CC) –c $(CFLAGS) $(CPPFLAGS) $< -o $@ 

#其中,“$@”表示依次取出目标值,$<表示依次取出依赖条件。

注意:只有写成模式规则的时候,$<才表示了所有依赖条件的依次取值,否则只是取依 赖条件中的第一个。

Makefile 函数

GNU make 函数的调用格式类似于变量的引用,以“$”开始表示一个引用。语法

格式如下:

$(FUNCTION ARGUMENTS)

或者:

${FUNCTION ARGUMENTS}

src = $(wildcard *.c) 
#找到当前目录下所有后缀为.c的文件,赋值给src 

obj = $(patsubst %.c,%.o, $(src)) 
#把src变量里所有后缀为.c的文件替换成.o

make clean

用途:清除编译生成的中间.o文件和最终目标文件

#clean的用途演示
clean:
rm *.o temp

但是如果在当前工作目录下存在文件“clean”,情况就不一样了,同样我们输入 “make clean”,由于这个规则没有任何依赖文件,所以目标被认为是最新的而不去执 行规则所定义的命令,因此命令“rm”将不会被执行。

这并不是我们的初衷。为了解 决这个问题,我们需要将目标“clean”声明为伪目标。将一个目标声明为伪目标的方 法是将它作为特殊目标.PHONY”的依赖。如下:

.PHONY : clean

这样目标“clean”就被声明为一个伪目标,无论在当前目录下是否存在“clean”这个 文件。我们输入“make clean”之后。“rm”命令都会被执行。

make常用参数

  1. make 默认执行第一个出现的目标,可通过make dest指定要执行的目标distclean目标
  2. install目标
  3. make -C 指定目录 进入指定目录,调用里面的Makefile
  4. make -n:只打印要执行的命令,不会真正执行命令
  5. make -p:显示隐含规则数据库中的信息
  6. make -C:切换到另一个目录中执行该目录下的Makefile
  7. make -f:-f执行一个makefile文件名称,使用make执行指定的makefile
庄朋龙
庄朋龙

一个爱生活的技术菜鸟

留下评论

您的电子邮箱地址不会被公开。 必填项已用 * 标注