程序维护工具-Makefile
程序维护工具make
功能:
在Linux系统下,make是用来自动完成大批量源文件编译工作的编译工具。
利用make工具,程序开发人员只需定一个文件之间的依赖关系及在此基础上应执行的操作,然后make工具就可以根据这些内容,以及各文件的修改日期的顺序,自动识别被修改的源文件并重新予以编译。
一、 make的工作机制
make的工作过程:
- 依次读入各makefile文件;
- 初始化其中的变量;
- 推导隐式规则,分析所有的规则
- 为所有的目标文件创建依赖关系
- 根据依赖关系和时间数据,确定目标文件的生成
- 执行命令
1、makefile文件
在使用make工具时,用户需要提供一个文件,用来说明源文件之间的依赖关系和构建规则,这个文件称为makefile。
说明:
Makefile需要按照某种语法进行编写,其中说明了如何编译各个源文件并链接生成可执行文件,并定义了源文件之间的依赖关系。
默认情况下,GNU make工具在当前工作目录中按如下顺序搜索Makefile:
GNUmakefile
makefile
Makefile
makefile文件的内容:目标文件,相依文件,操作命令
makefile规则的通用格式:
目标文件:[相依文件…]
<tab>命令1[#注释]
<tab>命令2[#注释]
…
<tab>命令n[#注释]
例子:
假如有一个源文件test.c,该源文件包含有自定义的头文件test.h,
分析:
则目标文件test.o明确依赖两个源文件:test.c和test.h
用makefile来定义test.o的创建规则:
test.o: test.c test.h
gcc -c -g test.c
说明:
makefile中的命令必须以Tab键开始。
2、依赖关系图
体现各个文件之间的依赖关系。
合理的构造依赖关系图,对于编制makefile文件和提高make的执行效率很重要。
说明:
生成一个目标文件可以有不同的途径,相应生成不同的依赖关系。
make工具可以根据目标文件上一次编译的时间和目标所依赖的源文件的更新时间而自动判断应当编译哪个源文件。
例子1:
一个程序包括以下内容。
三个C语言源文件:x.c y.c z.c。x.c和y.c都使用了defs.h中的声明。
汇编语言源文件:assmb.s
使用了数学运算函数库:/home/mqc/lib/libm.so
makefile文件:
prog:x.c y.c z.c assmb.s
gcc x.c y.c z.c assmb.s -L /home/mqc/libm -lm -o prog
makefile文件:
prog:x.o y.o z.o assmb.o
gcc x.o y.o z.o assmb.o -L /home/mqc/libm -lm -o prog
x.o: x.c defs.h
gcc -c x.c
y.o: y.c defs.h
gcc -c y.c
z.o: z.c
gcc -c z.c
assmb.o: assmb.s
as -o assmb.o assmb.s
例子2:
main函数将调用function1、function2函数。各模块间的依赖关系如图所示。
//function1.c
#include "function1.h"
void function1_print(char *str)
{
printf("This is function1 print %s\n", str);
}
//function2.c
#include "function2.h"
void function2_print(char *str)
{
printf("This is function2 print %s\n", str);
}
//main.c
#include "function1.h"
#include "function2.h"
int main(int argc, char **argv)
{
function1_print("hello");
function2_print("hello");
}
makefile 文件
main:main.o function1.o function2.o
gcc -o main main.o function1.o function2.o
main.o:main.c function1.h function2.h
gcc -c main.c
function1.o:function1.c function1.h
gcc -c function1.c
function2.o:function2.c function2.h
gcc -c function2.c
clean:
rm -f main.o function1.o funtion2.o
3、make命令
功能:可根据makefile文件自动完成程序的编译连接,生成可执行文件。
例子:
#make
#make prog
#make -f makefile
#make clean //清除中间文件
二、使用变量
1、变量的定义和使用
make的变量又称为宏定义,就像是C/C++语言中的宏一样,它代表了一个文本字符串,在make文件执行的时候,变量会自动按原样展开在所使用的位置。
变量的命名规则:
可以包含数字、字符、下划线(可以是数字开头),
但不能含有“: # =”或是空字符(空格,回车等)。
大小写敏感
定义变量的格式:变量名 = 字符串
变量的引用:$(变量名)
说明:
最好加括号,这样可以使代码更清晰。
与引用shell变量类似。
例子
objects = program.o foo.o utils.o
program : $(objects)
gcc -o program $(objects)
2、预定义变量
类别 |
预定义变量 |
说明 |
C编译命令 |
CC |
c编译器的名称,默认为cc |
CPP |
c预编译器的名称,默认为 gcc -E |
|
CFLAGS |
传给c语言编译程序的参数,无默认值 |
|
CPPFLAGS |
传给c预处理程序的参数,无默认值 |
|
C++编译命令 |
CXX |
c++语言编译程序,默认为g++ |
XCCFLAGS |
传给c++语言编译程序的参数,无默认值 |
|
汇编命令 |
AS |
汇编程序,默认是as |
隐式规则
在makefile文件中显示的指定的一些规则,称为显示规则。此外,make还有一套隐式规则。
隐式规则就是一种惯例,不需要在makefile中写出来。
可以极大地简化makefile文件的内容。
下面是几个常用的隐式规则:
编译C语言程序的隐式规则:
对于每一个.o文件,make都会首先找到与之对应的.c文件,并且用gcc命令进行编译,生成.o目标文件。
命令为:$(CC) -c $(CPPFLAGS) $(CFLAGS)
编译C++程序的隐式规则:命令为:$(CXX) -c $(CPPFLAGS) $(CFLAGS)
汇编的隐式规则:命令为:$(AS) $(ASFLAGS)
例子:通过使用makefile变量和隐含规则,上例中的makefile文件可以简化成以下形式:
objects=main.o function1.o function2.o
main:$(objects)
gcc $(objects) -o main
main.o:function1.h function2.h
function1.o:function1.h
function2.o:function2.h
clean:
rm -f *.o
例子:通过使用makefile变量和隐含规则,上例中的makefile文件可以简化成以下形式:
objects=main.o function1.o function2.o
main:$(objects)
gcc $(objects) -o main
clean:
rm -f *.o