GNU提出的是一个开发工具,它决定一个特定的代码库是重新编译,并可以发出命令来对代码库执行这些操作的部分。 这个特定的化妆工具可以与设置其汇编可以从外壳通过发出命令来完成的任何编程语言一起使用。
Linux中的Makefile
为了使用GNU做 ,我们需要有一些规则集,它定义在我们的程序不同的文件之间的关系,以及更新每一个文件的命令。 这些被写入到称为“ 生成文件 ”的特殊文件。 ' 制作 '命令使用“ 生成文件 ”数据库和文件的最后修改时间来决定,所有文件都再重新编译。
Makefile的内容
一般来说''makefile文件包含5个各种各样的事情,即: 潜规则 , 显规则 , 变量定义 , 指令和注释 。
- 一个明确的规则指定如何使/改造一个或多个文件(称为目标,将在稍后说明),并且当这样做。
- 隐式规则指定如何使/改造的基础上他们的名字一个或多个文件。 它描述了目标文件名如何与名称类似于目标的一个文件相关。
- 变量的定义是一条线,它指定一个变量稍后取代的字符串值。
- 一个指令是化妆做一些特别的东西,而在读入makefile的指令。
- 使用“#”符号代表里面的makefile 注释的开始。 以'#'的行会被忽略。
Makefile的结构
告诉make该怎么重新编译系统的信息来自读取称为makefile文件的数据库。 一个简单的makefile将包含以下语法规则:
target ... : prerequisites ... recipe ... ...
的靶被定义为由程序生成的输出文件。 它可以是也伪目标 ,这将在下面解释。 目标文件的例子包括可执行文件 , 目标文件或类似的清洁 伪目标 , 安装 , 卸载等。
前提条件是用于作为输入来创建所述目标文件的一个文件。
配方是使执行用于创建基于的前提目标文件的操作。 有必要把制表符的生成文件内每个配方之前,除非我们指定'.RECIPEPREFIX'变量定义一些其他的字符作为前缀配方。
示例Makefile
final: main.o end.o inter.o start.o gcc -o final main.o end.o inter.o start.o main.o: main.c global.h gcc -c main.c end.o: end.c local.h global.h gcc -c end.c inter.o: inter.c global.h gcc -c inter.c start.o: start.c global.h gcc -c start.c clean: rm -f main.o end.o inter.o start.o
在上面的例子中,我们使用了4个C源文件和两个头文件创建可执行文件决赛 。 在这里,每个' 的.o“文件既是目标和Makefile里的先决条件。 现在来看看最后的目标名称干净 。 它只是一个动作,而不是目标文件。
因为我们通常在编译期间不需要它,所以它不被写为任何其他规则的先决条件。 不引用文件,但只是动作的目标称为伪目标 。 它们不具有作为其他目标文件的任何先决条件。
如何GNU Make过程一个Makefile
默认与第一目标开始了在“ 生成文件 '和被称为” 缺省目标 '。 考虑到我们的例子中,我们最终为我们的第一个目标。 因为它的先决条件包括其他目标文件的创建决赛之前进行更新。 每个先决条件都根据自己的规则进行处理。
如果有源文件或头文件或对象文件不存在于所有的修改时重新编译。 重新编译必要的目标文件后, 作出决定是否重新链接最终还是不行。 这必须完成,如果该文件最终不存在,或者如果任何对象文件是比它新。
因此,如果我们改变文件inter.c,然后在运行使其将重新编译源文件来更新目标文件inter.o,然后链接决赛 。
在Makefile中使用变量
在我们的例子中,我们不得不两次列出最终规则所有的目标文件 ,如下图所示。
final: main.o end.o inter.o start.o gcc -o final main.o end.o inter.o start.o
为了避免这样的重复,我们可以引入变量来存储正在生成文件内使用的对象的文件的列表。 通过该变量OBJ我们可以重写的Makefile如下所示类似的一个。
OBJ = main.o end.o inter.o start.o final: $(OBJ) gcc -o final $(OBJ) main.o: main.c global.h gcc -c main.c end.o: end.c local.h global.h gcc -c end.c inter.o: inter.c global.h gcc -c inter.c start.o: start.c global.h gcc -c start.c clean: rm -f $(OBJ)
清除源目录的规则
正如我们在这个例子生成文件所看到的,我们可以定义规则,编译后,去除不需要的目标文件清理源目录。 假设我们碰巧有一个叫做清洁的目标文件。 怎样才能使区分以上两种情况? 这里谈到的假目标的概念。
假目标是一个是不是一个真正的文件名,而这仅仅是一个每当明确要求从生成文件提出要执行的配方名。 使用假目标的一个主要的原因是为了避免具有相同名称的文件有冲突。 其他原因是提高性能。
为了解释这个事情,我会揭示一个意想不到的扭曲。 清洁配方将不会默认运行make执行。 相反,有必要通过发出命令make clean来调用相同。
.PHONY: clean clean: rm -f $(OBJ)
现在试着为自己的代码库创建makefile文件 。 随意在这里评论你的疑惑。