Makefile是什么
Makefile与make命令一起使用。makefile定义了一系列规则来指定哪些文件需要先编译再编译,哪些文件需要重新编译,甚至执行更复杂的功能操作。和Shell脚本一样,Makefile也可以执行操作系统命令。
一个项目中有无数个源文件,根据它们的类型、功能、模块放在几个目录中。makefile定义了一系列规则来指定哪些文件需要首先编译,哪些文件需要稍后编译,哪些文件需要重新编译,甚至对于更复杂的功能操作也是如此,因为makefile和Shell脚本一样,也可以执行操作系统命令。
定义
总结
Linux的程序员,如果不能用GNU make来构建和管理自己的项目,就不能算合格的专业程序员,至少不能算Unix程序员。在Linux(unix)环境下使用GNU的make工具,可以轻松构建自己的项目,整个项目只需要一个命令就可以编译、连接、最后执行。然而,这需要我们投入一些时间来完成一个或多个名为Makefile的文件的编写。
要完成的Makefile描述了整个项目的编译和连接规则。它包括:需要编译哪些源文件,如何编译,需要创建哪些库文件,如何创建这些库文件,最后如何产生我们想要的可执行文件。虽然看起来很复杂,但是为项目编写Makefile的好处是,一旦提供了一个(通常不止一个)正确的Makefile,它就可以使用一行命令来完成“自动编译”。要编译整个项目,只需在shell提示符下输入make命令。整个项目是自动编译的,大大提高了效率。
Make是一个解释Makefile中指令的命令工具。在Makefile中,描述了整个项目中所有文件的编译顺序和规则。Makefile有自己的编写格式,关键字,函数。就像C语言有自己的格式,关键字,函数一样。并且在Makefile中,可以使用系统shell提供的任何命令来完成想要的工作。Makefile在大多数IDE开发环境中使用,已经成为一种工程编译方法。
例子
上面Makefile中的“$ @ & # 8221”;, “$^”, “$ & lt”叫做自动变量。
自动编译
主要功能
Make工具最重要最基本的功能就是描述源程序之间的关系,通过makefile自动维护编译工作。makefile文件需要按照一定的语法编写。文件需要说明如何编译每个源文件并连接生成一个可执行文件,需要定义源文件之间的依赖关系。Makefile文件是很多编译器& # 8211;包括Windows NT下的编译器& # 8211;维护编译信息的常用方法是用户在集成开发环境中通过友好的界面修改makefile。
在UNIX系统中,makefile作为Makefile使用。如果要将其他文件用作生成文件,可以使用如下生成命令选项来指定生成文件:
发出命令
$ make -f Makefile.debug
例如,一个名为prog的程序由三个C源文件filea.c、fileb.c和filec组成
Makefile项目示例
# include & # 8220defs & # 8221
以下文档描述了这些文件之间的相互关系:
这是一个描述makefile注释行的例子
1 prog: filea.o fileb.o filec.o #指定通过链接三个目标文件filea.o、fileb.o和filec.o来生成prog。
2 cc filea。o文件b。o文件c。如何从程序依赖的文件中创建可执行文件
3 filea.o: filea.c a.h defs #指定filea.o目标文件,并且。c和。他们所依赖的h文件和defs文件
4 cc -c filea.c #如何从目标所依赖的文件构建目标,即如何从filea.c构建filea.o。
5 fileb.o: fileb.c b.h defs #指定fileb.o目标文件,并且。c和。他们所依赖的h文件和defs文件
6 cc -c fileb.c #如何从目标所依赖的文件构建目标,即如何从fileb.c构建fileb.o。
7 filec.o: filec.c.h #指定filec.o目标文件和。c和。他们所依赖的文件
8 cc -c filec.c #如何从目标所依赖的文件建立目标,即如何从filec.c建立filec.o。
这个描述文档是一个简单的makefile。我们对上面例子中的代码做了一些基本的解释:CC是全局变量,指定了你的Makefile中使用的编译器,一般默认为gcc;那个。o文件是unix下的中间代码目标文件,就像。windows下的obj文件。生成的过程。unix下的o文件称为编译,是从大量的。o文件称为链接。有时候你会看到。unix界面下的一个文件,是Archive File,相当于windows下的Library File。的作用。一个文件是:因为源文件太多(上例指太多。c和。h文件),中间目标文件太多(。o文件)由编译生成,但是链接时需要明确指出中间目标文件名,对于编译来说非常不方便,所以我们需要给中间目标文件命名。
make工具可以在编译后修改filea.c或a.h文件时自动重新编译filea.o。如果filea.c和filea.h都没有被修改,并且filea.o仍然存在,则没有必要重新编译。这种依赖性在编译具有多个源文件的程序时尤其重要。通过这种依赖性的定义,make工具可以避免许多不必要的编译工作。当然,使用Shell脚本也可以达到自动编译的效果,但是Shell脚本会编译所有的源文件,包括那些不需要重新编译的,而make工具可以根据目标的上次编译时间和目标所依赖的源文件的更新时间自动判断应该编译哪些源文件。
Makefile准备好之后,在Makefile所在的目录中键入make命令。根据Makefile,告诉make命令如何编译链接目标程序。
规则
让我们粗略地看一下Makefile的规则。
目标& # 8230;:先决条件& # 8230;
命令
…
…
目标:依赖
执行指令& # 8230;
目标也是目标文件,可以是目标文件,也可以是执行文件。它也可以是一个标签。
(1)先决条件是生成目标所需的文件或目标。
(2)命令是make需要执行的命令。(任意外壳命令)
这是一种文件依赖关系,也就是说,目标的一个或多个目标文件依赖于前提条件中的文件,其生成规则在命令中定义。说白了,如果先决条件中有一个以上的文件比目标文件新,就会执行命令定义的命令(命令必须以Tab键开头,否则编译器不会识别命令),减少重复编译,提高其软件工程管理效率。
文件定义和命令
Makefile作为一个描述文档通常需要包括以下内容
在命令行上执行makefile
◆宏定义◆源文件之间的相互依赖
◆可执行命令
Makefile允许简单的宏引用源文件及其相关的编译信息,在Linux中宏也被称为变量。引用宏时,只需在变量前加$符号,但值得注意的是,如果变量名长度超过一个字符,引用时必须加括号()。
有效的宏引用
$(CFLAGS)
$Z
$(Z)
最后两个参考文献是相同的。
需要注意的是,一些宏预定义变量,在Unix系统中,$ *,$ @,$?和美元
#为目标文件定义宏
OBJECTS= filea.o fileb.o filec.o
#为库文件定义宏
LIBES= -LS
#使用宏重写makefile
prog: $(对象)
cc $(OBJECTS) $(LIBES) -o prog
此时,如果执行不带参数的make命令,将连接三个目标文件和库文件ls;但是如果在make命令之后加上一个新的宏定义:
制作& # 8220;LIBES =-LL-LS & # 8221;#如何?
命令行末尾的宏定义会覆盖makefile中的宏定义。如果LL也是一个库文件,make命令将连接三个目标文件和两个库文件ls和LL。
在Unix系统中,常量NULL没有明确定义,所以我们在定义NULL字符串时应该使用下面的宏定义:
STRINGNAME= //这里需要验证
makefile中的变量(宏)
GNU的make工具不仅提供了建立目标的基本功能,还提供了许多表达依赖关系的便利
以及设置目标的命令的特点。其中之一是定义变量或宏的能力。如果你想用相同的
选项来同时编译十几个c源文件,如果你为每个目标的编译指定冗长的编译选项,它将是真的和假的
经常无聊。但是,通过使用一个简单的变量定义,可以避免这项繁琐的工作:
#为编译器的名称定义宏
CC = gcc
#为抄送标志定义一个MAC
CCFLAGS = -D_DEBUG -g -m486
#建立目标文件的规则
test.o: test.c test.h
$(CC) -c $(CCFLAGS)测试. c
在上面的例子中,CC和CCFLAGS是make的变量。GNU make通常被称为变量,
而其他UNIX制作的工具叫做宏,其实是一回事。引用makefile中的变量值
,只需在变量名前添加$符号,如上面的$(CC)和$(CCFLAGS)。
GNU make有很多预定义的变量,有特殊的含义,可以用在规则中。表13-2
给出了一些主要的预定义变量。除了这些变量,GNU make还将所有环境变量作为自己的变量
的预定义变量。
预定义变量
意义
$*
不带扩展名的目标文件的名称。
$+
所有依赖文件由空分隔,按照出现的顺序,它们可能包含重复的依赖文件。
$ & lt
第一个依赖文件的名称。
$?
所有依赖文件之间用空隔开,这些依赖文件的修改日期晚于目标的创建日期。
$@
目标的全名。
$
所有相关文件由空分隔,不包含重复的相关文件。
$%
如果目标是归档成员,此变量表示目标的归档成员名称。例如,如果目标名称为
(image.o),$ @为,$%为image.o。
阿肯色州
存档维护程序的名称。默认值是ar。
ARFLAGS
档案维护者选项。
如同
汇编程序的名称,默认值为。
ASFLAGS
汇编程序选项。
抄送
c编译器的名字,默认值是cc。
编译用
c编译器选项。
卡片打印处理机(Card Print Processor的缩写)
c预编译器的名称,默认值为$ (cc)-e。
设置
c预编译选项。
创
C++编译器的名称。默认值是g++。
CXXFLAGS
C++编译器的选项。
足球俱乐部
FORTRAN编译器的名称。默认值为f77。
FFLAGS
FORTRAN编译器选项。
Makefile以文件名:文件名的形式比较冒号右边的文件是否比左边的文件新,有更新就执行下一行程序代码。因此,Makefile可以关联文件。
0条评论