您的位置:首页 > 其它

Makefile常用变量和规则备忘

2010-01-04 11:03 232 查看

1

0.3


隐含变量

内嵌隐含规则的命令中,所使用的变量都是预定义的变量。我们将这些变量称为“隐含变量”。这些变量允许对它进行修改:在
Makefile
中、通过命令行参数或者设置系统环境变量的方式来对它进行重定义。无论是用那种方式,只要
make
在运行时它的定义有效,
make
的隐含规则都会使用这些变量。当然,也可以使用“
-R
”或“
--no

builtin-variables
”选项来取消所有的隐含变量(同时将取消了所有的隐含规则)。

例如,编译
.c
源文件的隐含规则为:“
$(CC)
-c $(CFLAGS) $(CPPFLAGS)
”。默认的编译命令是“
cc
”,执行的命令是:“
cc
–c
”。我们可以同上述的任何一种方式将变量“
CC
”定义为“
ncc
”,那么编译
.c
源文件所执行的命令将是“
ncc
-c
”。同样我们可以对变量“
CFLAGS
”进行重定义。对这些变量重定义后如果需要整个工程的各个子目录有效,同样需要使用关键字“
export
”将他们导出;否则目录间编译命令可能出现不一致。编译
.c
源文件时,隐含规则使用“
$(CC)
”来引用编译器;“
$(CFLAGS)
”引用编译选项。

隐含规则中所使用的变量(隐含变量)分为两类:
1.

代表一个程序的名字(例如:“
CC
”代表了编译器这个可执行程序)。
2.

代表执行这个程序使用的参数(例如:变量“
CFLAGS
”),多个参数使用空格分开。当然也允许在程序的名字中包含参数。但是这种方式建议不要使用。

以下是一些作为程序名的隐含变量定义:

1
0.3.1

代表命令的变量



AR


函数库打包程序,可创建静态库
.a
文档。默认是“
ar
”。



AS


汇编程序。默认是“
as
”。



CC


C
编译程序。默认是“
cc
”。



CXX


C++
编译程序。默认是“
g++
”。



CO




RCS
中提取文件的程序。默认是“
co
”。



CPP


C
程序的预处理器(输出是标准输出设备)。默认是“
$(CC)
-E
”。



FC


编译器和预处理
Fortran



Ratfor

源文件的编译器。默认是“
f77”。



GET



SCCS
中提取文件程序。默认是“
get
”。



LEX




Lex

语言转变为

C



Ratfo

的程序。默认是“
lex
”。



PC


Pascal
语言编译器。默认是“
pc
”。



YACC


Yacc
文法分析器(针对于
C
程序)。默认命令是“
yacc
”。



YACCR


Yacc
文法分析器(针对于
Ratfor
程序)。默认是“
yacc
-r
”。



MAKEINFO


转换
Texinfo
源文件(
.texi
)到
Info
文件程序。默认是“
makeinfo
”。



TEX



TeX
源文件创建
TeX
DVI
文件的程序。默认是“
tex
”。



TEXI2DVI



Texinfo
源文件创建
TeX
DVI

文件的程序。默认是“
texi2dvi
”。



WEAVE


转换
Web

TeX
的程序。默认是“
weave
”。



CWEAVE


转换
C
Web



TeX
的程序。默认是“
cweave
”。



TANGLE


转换
Web

Pascal
语言的程序。默认是“
tangle
”。



CTANGLE


转换
C
Web



C
。默认是“
ctangle
”。



RM


删除命令。默认是“
rm
-f
”。

1
0.3.2

命令参数的变量

下边的是代表命令执行参数的变量。如果没有给出默认值则默认值为空。



ARFLAGS


执行“
AR
”命令的命令行参数。默认值是“
rv
”。



ASFLAGS


执行汇编语器“
AS
”的命令行参数(明确指定“
.s
”或“
.S
”文件时)。



CFLAGS


执行“
CC
”编译器的命令行参数(编译
.c
源文件的选项)。



CXXFLAGS


执行“
g++
”编译器的命令行参数(编译
.cc
源文件的选项)。



COFLAGS


执行“
co
”的命令行参数(在
RCS
中提取文件的选项)。



CPPFLAGS


执行
C
预处理器“
cc
-E
”的命令行参数(
C



Fortran

编译器会用到)。



FFLAGS


Fortran
语言编译器“
f77”执行的命令行参数(编译
Fortran
源文件的选项)。



GFLAGS


SCCS


get
”程序参数。



LDFLAGS


链接器(如:“
ld
”)参数。



LFLAGS


Lex
文法分析器参数。



PFLAGS


Pascal
语言编译器参数。



RFLAGS


Ratfor

程序的
Fortran

编译器参数。



YFLAGS


Yacc
文法分析器参数。

1

0.4

make

隐含规则链

有时,一个目标文件需要多个(一系列)隐含规则来创建。例如:创建文件“
N.o
”的过程可能是:首先执行“
yacc
”由“
N.y
”生成文件“
N.c
”,之后由编译器将“
N.c
”编译成为“
N.o
”。如果一个目标文件需要一系列隐含规则才能完成它的创建,我们就把这个系列称为一个“链”。

我们来看上边例子的执行过程。有两种情况:

1.

如果文件“
N.c
”存在或者它在
Makefile
中被提及,那就不需要进行其它搜索,
make
处理的过程是:首先,
make
可以确定出“
N.o
”可由“
N.c
”创建;之后,
make
试图使用隐含规则来重建“
N.c
”。它会寻找“
N.y
”这个文件,如果“
N.y
”存在,则执行隐含规则来重建“
N.c
”这个文件。之后再由“
N.c
”重建“
N.o
”;当不存在“
N.y
”文件时,直接编译“
N.c
”生成“
N.o
”。

2.

文件“
N.c
”不存在也没有在
Makefile
中提及的情况,只要存在“
N.y
”这个文件,那么
make
也会经过这两个步骤来重建“
N.o
”(
N.y



N.c



N.o
)。这种情况下,文件“
N.c
”作为一个中间过程文件。
Make
在执行规则时,如果需要一个中间文件才能完成目标的重建,那么这个文件将会自动地加入到依赖关系链中(和
Makefile
中明确提及的目标作相同处理),并使用合适的隐含规则对它进行重建。

make
的中间过程文件和那些明确指定的文件在规则中的地位完全相同。但
make
在处理时两者之间存在一些差异:

第一:中间文件不存在时,
make
处理两者的方式不同。对于一个普通文件来说,因为
Makefile
中有明确的提及,此文件可能是作为一个目标的依赖,
make
在执行它所在的规则前会试图重建它。但是对于中间文件,因为没有明确提及,
make
不会去试图重建它。除非这个中间文件所依赖的文件(上例第二种情况中的文件“
N.y
”;
N.c
是中间过程文件)被更新。

第二:如果
make
在执行时需要用到一个中间过程文件,那么默认的动作将是:这个过程文件在
make
执行结束后会被删除(
make
会在删除中间过程文件时打印出执行的命令以显示那些文件被删除了)。因此一个中间过程文件在
make
执行结束后就不再存在了。


Makefile
中明确提及的所有文件都不被作为中间过程文件来处理,这是缺省地。不过我们可以在
Makefile
中使用特殊目标“
.INTERMEDIATE
”来指除将那些文件作为中间过程文件来处理(这些文件作为目标“
.INTERMEDIATE
”的依赖文件罗列),即使它们在
Makefile
中被明确提及,这些作为特殊目标“
.INTERMEDIATE
”依赖的文件在
make
执行结束之后会被自动删除。

另一方面,如果我们希望保留某些中间过程文件(它没有在
Makefile
中被提及),不希望
make
结束时自动删除它们。可以在
Makefile
中使用特使目标“
.SECONDARY
”来指出这些文件(这些文件将被作为“
secondary
”文件;需要保留的文件作为特殊目标“
.SECONDARY
”的依赖文件罗列)。注意:“
secondary
”文件也同时被作为中间过程文件来对待。

需要保留中间过程文件还存在另外一种实现方式。例如需要保留所有
.o
的中间过程文件,我们可以将
.o
文件的模式(
%.o
)作为特殊目标“
.PRECIOUS
”的依赖。

一个“链”可以包含两个以上隐含规则的调用过程。同一个隐含规则在一个“链”中只能出现一次。否则就会出现像“
foo
”依赖“
foo.o.o
”甚至“
foo.o.o.o.o…
”这样不合逻辑的情况发生。因为,如果允许在一个“链”中多次调用同一隐含规则(
N
: N.o; $(LINK.o) $(LDFLAGS) N.o $(LOADLIBES) $(LDLIBS)

),将会导致
make
进入到无限的循环中去。

隐含规则链中的某些隐含规则,在一些情况会被优化处理。例如:从文件“
foo.c
”创建可执行文件“
foo
”,这一过程可以是:使用隐含规则将“
foo.c
”编译生成“
foo.o
”文件,之后再使用另一个隐含规则来完成对“
foo.o
”的链接,最后生成执行文件“
foo
”。这个过程中对源文件的编译和对
.o
文件的链接分别使用了两个独立的规则(它们组成一个隐含规则链)。但是实际情况是,对源文件的编译和对
.o
文件的链接是在一个规则中完成的,规则使用命令“
cc
foo.c foo
”。
make
的隐含规则表中,所有可用的优化规则处于首选地位。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: