make编译六

如果要使用隐含规则生成你需要的目标,你所需要做的就是不要写出这个目标的规则。那么,make 会试图去自动推导产生这个目标的规则和命令,如果make 可以自动推导生成这个目标的规则和命令,那么这个行为就是隐含规则的自动推导。当然,隐含规则是make 事先约定好的一些东西。例如,有下面的一个Makefile

test:test.o func1.o

         gcc -o test test.o func1.o

对应的文件是:

test1.c

#include<stdio.h>

 

int main()

{

         print_info();

         return 1;

}

func1.c

#include<stdio.h>

 

void print_info()

{

         printf("print_info\n");

}

执行结果如下:

cc    -c -o test.o test.c

cc    -c -o func1.o func1.c

gcc -o test test.o func1.o

这个Makefile 中并没有写下如何生成test.o 和func1.o这两目标的规则和命令。因为make 的“隐含规则”功能会自动为我们自动去推导这两个目标的依赖目标和生成命令。make 会在自己的“隐含规则”库中寻找可以用的规则,如果找到,那么就会使用。如果找不到,那么就会报错。在上面的那个例子中,make 调用的隐含规则是,把[.o]的目标的依赖文件置成[.c],并使用C的编译命令“cc –c $(CFLAGS) [.c]”来生成[.o]的目标。也就是说,我们完全没有必要写下下面的两条规则:

test.o:test.c

cc    -c -o test.o test.c

func1.o:func1.c

cc    -c -o func1.o func1.c

我们也可以用-r –no-builtin-rules选项来取消所有的预设置的隐含规则。此时make文件的时候就会报错。

make -r -f makefile1.cfg

make: *** No rule to make target 'test.o', needed by 'test'。 停止。

 

 

常用的隐含规则有很多。下面我们之看下对c和C++相关的规则

一 编译C 程序的隐含规则。

“<n>.o”的目标的依赖目标会自动推导为“<n>.c”,并且其生成命令是

“$(CC) –c $(CPPFLAGS) $(CFLAGS)”

 

二 编译C++程序的隐含规则。

“<n>.o”的目标的依赖目标会自动推导为“<n>.cc”或是“<n>.C”,并且其生成命令是“$(CXX) –c $(CPPFLAGS) $(CFLAGS)”。(建议使用“.cc”作为C++源文件的后缀,而不是“.C”)

 

三 汇编和汇编预处理的隐含规则。

“<n>.o” 的目标的依赖目标会自动推导为“<n>.s”,默认使用编译品“as”,并且其生成命令是:“$(AS) $(ASFLAGS)”。“<n>.s” 的目标的依赖目标会自动推导为“<n>.S”,默认使用C 预编译器“cpp”,并且其生成命令是:“$(AS) $(ASFLAGS)”。

 

四 链接Object 文件的隐含规则。

“<n>”目标依赖于“<n>.o”,通过运行C 的编译器来运行链接程序生成(一般是“ld”),其生成命令是:“$(CC) $(LDFLAGS) <n>.o $(LOADLIBES) $(LDLIBS)”。这个规则对于只有一个源文件的工程有效,同时也对多个Object 文件(由不同的源文件生成)的也有效。例如如下规则:

x : y.o z.o

并且“x.c”、“y.c”和“z.c”都存在时,隐含规则将执行如下命令:

cc -c x.c -o x.o

cc -c y.c -o y.o

cc -c z.c -o z.o

cc x.o y.o z.o -o x

rm -f x.o

rm -f y.o

rm -f z.o

如果没有一个源文件(如上例中的x.c)和你的目标名字(如上例中的x)相关联,那么,你最好写出自己的生成规则,不然,隐含规则会报错的。

 

隐含规则使用的变量

在隐含规则中的命令中,基本上都是使用了一些预先设置的变量。你可以在你的makefile 中改变这些变量的值,或是在make 的命令行中传入这些值,或是在你的环境变量中设置这些值,无论怎么样,只要设置了这些特定的变量,那么其就会对隐含规则起作用。当然,你也可以利用make 的“-R”或“--no–builtin-variables”参数来取消你所定义

的变量对隐含规则的作用。

例如,第一条隐含规则——编译C程序的隐含规则的命令是“$(CC) –c $(CFLAGS) $(CPPFLAGS)”。Make 默认的编译命令是“cc”,如果你把变量“$(CC)”重定义成“gcc”,把变量“$(CFLAGS)”重定义成“-g”,那么,隐含规则中的命令全部会以“gcc –c -g $(CPPFLAGS)”的样子来执行了。

 

关于命令的变量:

AR

函数库打包程序。默认命令是“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 或Ratfor)。默认命令是“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”。

 

关于命令参数的变量

ARFLAGS

函数库打包程序AR 命令的参数。默认值是“rv”。

ASFLAGS

汇编语言编译器参数。(当明显地调用“.s”或“.S”文件时)。

CFLAGS

C语言编译器参数。

CXXFLAGS

C++语言编译器参数。

COFLAGS

RCS 命令参数。

CPPFLAGS

C预处理器参数。( C 和Fortran 编译器也会用到)。

FFLAGS

Fortran 语言编译器参数。

GFLAGS

SCCS “get”程序参数。

LDFLAGS

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

LFLAGS

Lex 文法分析器参数。

PFLAGS

Pascal语言编译器参数。

RFLAGS

Ratfor 程序的Fortran 编译器参数。

YFLAGS

Yacc 文法分析器参数。

posted @ 2019-01-11 14:59  red_leaf_412  阅读(255)  评论(0编辑  收藏  举报