linux学习笔记-makefile2

makefile文件构成:

一个完整的makefile文件由5部分构成:显式规则、隐含规则、使用变量、文件指示和注释。


#显式规则:一条显式规则指明了目标文件、目标文件的依赖文件、生成或更新目标文件所使用的命令。有些规则没有命令,这样的规则只描述文件之间的依赖关系。


#隐含规则:由make根据目标文件(典型的是根据文件名的后缀)自动推导出的规则。make根据目标文件的文件名,自动产生目标的依赖文件和生成目标的命令。
module1.o:head1.h;
make会根据module1.o的后缀.o自动产生目标的依赖文件module1.c和生成目标使用的命令gcc -c module1.c -o module1.o;因此它等价于:
module1.o:module1.c head1.h;
gcc -c module1.c -o module1.o
因此前面整个makefile可以简写为:
main:main.o module1.o module2.o;
   gcc main.o module1.o module2.o -o main
main.o:head1.h head2.h commo_head.h;
module1.o:head1.h;
module2.o:head2.h;


#使用变量:makefile中的变量类似与C语言的宏。


#文件指示:包括3个部分:1.一个makefile中包含另一个makefile,类似C语言中的include;2.根据某些情况指定makefile中的有效部分,就像C语言中的预编译#if一样;3.定义一个多行的命令。


#注释:以#开头,一般注释独立一行。




1.显式规则:
foo.o:foo.c defs.h
   gcc -c -g foo.c
两个表现:
1.如何确定目标文件过时:比较foo.o在时间戳上比依赖文件中的任何一个晚。
2.如何重新生成目标文件:说明使用什么命令重新生成目标。
一般形式:
目标文件列表 分隔符 依赖文件列表 [;命令]
    [命令]
    [命令]
其中[]中的内容是可选的。


规则中目标文件列表可以是以空格分开的多个文件名,也可以是一个标签。目标文件列表中的文件名可以使用通配符,格式”A(M)“表示库文件(.a 文件)的成员M。通常规则中只有一个目标文件。建议不要包含多个文件。
注意:
1.目标文件:依赖文件
2.$有特殊含义。
3.断行,反斜杠



2.依赖的类型:
makefile中有两种依赖,一种是上面的类型。还有一种依赖如下所示:
foo : foo.c | somelib;
   gcc -o foo foo.c somelib
|前面的文件是普通依赖文件,如果|后面的文件过时,foo不会重新生成,第二行不会被执行。

3.命令行属性:
一条规则中可以有一个或者多个命令行,每个命令行以tab开头。可以在tab后面加+、-或者@,然后写上命令。如果tab后面没有符合,make使用缺省的命令行属性:执行该命令的命令行时打印出命令,命令行遇到错误就会推出make。
-:执行命令行的命令如果遇到错误,忽略错误继续执行make;
+:命令行命令始终被执行,技术make命令时使用了 -n,-q,-t选项(前提是本行命令所在规则的目标文件已经过时,需要执行命令以更新目标文件)。
@:执行本行命令时不在屏幕上打印命令内容。


4.伪目标:
makefile文件中,目标分为实目标和伪目标。实目标文件是真正要生成的以文件的形式放在硬盘的目标。伪目标不要求生成实际文件,而是为了让make执行一些辅助命令,如打印一些信息,删除无用的中间文件的等。
如:
clean:
-rm -f *.o
make扫描到这一行时,发现clean没有依赖文件,因此总认为是最新的,从而不会执行下面的命令。为了让make执行clean之后的语句,shell后面应使用make clean命令。
严格来讲可以将clean使用.PHONY声明成一个伪目标:
.PHONY : clean
这样不需要担心clean会是一个文件,或者文件重命名等问题。
完整格式:
.PHONY : clean
clean:
-rm -f *.o

一个伪目标可以有自己的依赖。一个目录下如果需要生成多个可执行程序,通常做法是使用一个”all“的伪目标作为最终目标,如:
all : program1 program2 program3 
.PHONY : all
program1 : program1.c program1.h;
gcc -o program1 program1.c;
program2 : program2.c program2.h;
gcc -o program2 program2.c;
program3 : program3.c program3.h;
gcc -o program3 program3.h;
执行make时,目标all作为最终目标,为了完成对它的更新,make会生成最终目标”all”的所有依赖文件。


5.特殊目标:
makefile文件中有一些文件以.开头,具有特殊含义。
.PHONY:所有依赖被作为伪目标。
.IGNORE:后面跟的依赖文件,生成这些依赖文件的命令在执行时遇到错误会忽略并继续执行make,类似“-”。
.SUFFIXES:该目标的依赖被认为是一个后缀列表,在检查后缀规则时使用。
.SILENT:执行生成依赖文件的命令时,make不会打印出所执行的命令。如果后面没有依赖文件,则makefile中所有命令都不会打印。
.PRECIOUS:该目标的依赖文件会受到特别对待。如果make被kill终止或遇到以外而被终止,这些依赖并不会被删除,而且这些依赖文件是中间文件,在不需要时也不会删除。
.INTERMEDIATE:后面的依赖文件被当做中间文件对待。如果后面没有依赖文件,那么该规则是没有意义的。


6.含有多个目标的规则:
一个规则中可以有多个目标,规则所定义的命令对所有目标都有效。一个具有多个目标规则相当于多个规则。多目标规则意味着所有目标具有相同的依赖文件。在规则的命令中可以使用自动变量,从而可以把几条规则归为一条。如:
module1.o module2.o module3.o : command.h
等价与3条规则:
module1.o:module1.c command.h;
   gcc -c module1.c -o module1.o
module2.o:module2.c command.h;
   gcc -c module2.c -o module2.o
module3.o:module3.c command.h;
   gcc -c module3.c -o module3.o


7.搜索目录:

通常一个较大的项目中会把源文件、头文件、库文件放在不同的目录里。在这种情况下,我们要让make在不同的目录中寻找依赖文件。当我呢句所在的目录发生变化后,可以不用更改makefile中的规则,只需改变依赖文件的搜索目录。

#VPATH
make可以识别一个特殊变量“VPATH”。通过VPATH可以指定依赖文件的搜索目录。当规则的依赖文件在当前的目录不存在时,make会在次变量指定的目录下寻找这些依赖文件。VPATH所指定的是makefile所有文件的搜索路径包括了规则的依赖文件和目标文件。
定义VPATH时可以使用:(冒号)将多个需要的搜索目录分开。如:
VPATH = /usr/src:../headers
这样就为所有规则指定了两个搜索目录。


#vpath
另一个设置文件搜索目录的方法是使用make的“vpath”关键字(小写的),它不是变量,而是make的关键字,它更加灵活,可以为不同的文件指定不同的搜索目录。使用方法:
1. vpath <pattern> <directories>
为符合模式<pattern>的文件指定搜索目录<directories>。
2. vpath <pattern>
清除符合模式<pattern>的文件指定的搜索目录。
3. vpath 
清除所有已经配置好的文件搜索目录。

vpath使用方法中的<pattern>需要包含%字符, % 意思是匹配零或若干字符。如 %.h 代表了所有.h结尾的文件。<directories>则指定了文件搜集的目录,如:
vpath %.h ../headers
可以连续使用vpath,make会按照vpath语句的先后顺序来执行搜索:
vpath %.c src1
vpath % src2
vpath %.c src3
一条vpath也可以指定多个目录,中间以:隔开:
vpath %.h headers:src


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值