Makefile
Make的基本规则:
Target [属性] 分隔符 [依赖文件] [;命令行 ]
{Tab 命令行}
注:命令行间可以加入任意多个空行,但空行也要以tab开头。Cat –v -t -e Makefile会使Makefile文件中tab以^]显示,行尾以$显示。
注:命令过长,用\来连接多行成一行。注释以#开头,如果#要用作字符符号,“#”。
分隔符:
::目标有多个规则。哪条规则中的依赖文件比目标新,执行哪条规则。如果多条规则的依赖文件都比目标新,多条规则都执行。由于后面的规则可能覆盖前面规则的执行结构,所以规则顺序不同,执行结构也不同。
:^把本规则依赖文件和目标文件已有的依赖文件合起来,生成目标新的依赖文件列表。
:-清除目标已有依赖文件,把本规则依赖文件作为目标依赖文件列表。
:!对每个更新过的依赖文件都执行一次命令菜单。
:|内部规则专用。
如:
file.o :file.c
file.o :^ filef.c
现依赖文件为file.c filef.c
file.o :- filef.c
现依赖文件为 filef.c
令行属性:
- 若本命令的执行错误,忽略掉,继续向下执行。(不加该标志,make会停止)
+ 始终执行本命令,即使make参数使用了-n-q-t。(前提是本规则中依赖文件新与目标文件,命令行需要执行)
@ 本命令行不在标准输出显示。
Target属性:
指定多个目标文件属性: 属性 属性 …… :目标 目标 ……
规则中指定单个目标属性:目标 属性:[依赖文件] ……
·IGNORE 类似与命令行属性-
·SILENT 类似与命令行属性@
·PRECIOUS 保留中间文件
·LIBRARY 目标是一个库。如果make发现目标是lib(member)或lib((entry))形式,会自动给名为lib的目标加上该属性。
·
LIBRARYM 目标是库的一个成员。如果make发现目标是lib(member)形式,会自动给lib目标加上·LIBRARY,被member目标加上·LIBRARYM。本属性不可在makefile文件显式声明。
·SYMBOL 目标是指定入口的库成员。Make会自动给lib((entry))的目标和依赖文件加上本属性。本属性不可在makefile文件显式声明。
伪目标:
Linux提供的内部伪目标:
·ERROR : Make遇到错误,执行该目标规则。
·INCLUDE :file1 …… 包含其他makefile文件,其他makefile文件位于
·INCLUDE规则的依赖文件位置。实际上,是把包含的文件内容copy到当前位置。比如:包含一个宏定义文件,以便在当前位置展开,本makefile文件可以用这些宏。形式:
·INCLUDE :filename1 filename2…… 或要包含的文件不在当前文件夹
·INCLUDE :filename1 filename2…… 或要包含的文件不在当前文件夹
·
INCLUDE :路径1 路径2 ……
·INCLUDE :filename1 filename2 …… 或者
·INCLUDE :<路径/filename> ……
·IMPORT :宏 …… 使用环境变量中的宏。
·IMPORT :·ENVERTHING 可以使用环境中所有宏了。
·EXPORT :宏 …… 将宏及当前值输入环境变量中。
·SETDIR=路径 改变当前工作路径。
注:有时候要定义的伪目标可能与文件名重。比如存在clean这个文件。可以用: PHONY:clean cean: ………… PHONY的作用是确保下面的clean是伪目标,非文件,从而避免混乱。
宏:
宏 赋值号 值
赋值号: = 将后面的字符串赋给宏 := 后面跟字符串常量,将常量的内容赋给宏
?= 貌似不对
+= 宏原值加空格,加字符串,构成新宏值
宏引用:
$(宏) 或${宏}。宏只有一个字符,可用$宏。如$A,等同$(A)
注意:makefile中,宏的引用必须在宏的定义之后。
注意:宏可以嵌套。如:INDEX=1 则$(DEADFILE$(INDEX)),等同$(HEADFILE1)
注意:宏可以在make命令参数定义、makefile中定义、引自环境宏,当make命令参数定义的宏含空格是,应用“宏=值”括起来。
注意:宏处理顺序:内定义宏——shell环境宏——makefile中定义的宏——make命令参数
宏。由于后面的宏处理会覆盖前面的宏,所以优先级为:make命令参数宏——makefile宏——shell环境宏——内定义宏。所有我们可以在不改变makefile的情况下,在命令行给宏赋新值而使用新宏值。
内定义宏:
普通宏,代表特殊的值:
DIRSETSTR 路径和文件间分割符一般为‘/’
MAKEDIR make的绝对路径 N
ULL 空字符传,多用于条件表达式中比较
OS 运行的操作系统名称
PWD 运行make是活动工作目录绝对路径
SHELL 运行的shell 属性宏,用于整个makefile中目标文件属性,作用域是整个makefile文件
IGNORE=yes 把所有目标文件属性设置成·IGNORE,yes可以用任何非空字符串代替。
SILENT
PRECIOUS
动态宏:
$@$%:目标文件名称。当目标是lib(member)形式时,$@表示库名lib,$%表示成员名member。
$> :适用与目标文件是lib(member)的情形,$>代表lib。
$>不适用与目标是普通文件。
$* :目标文件去掉后缀的名称。
$^ :本规则中的依赖文件。
$& :本规则中目标在所有规则中的所有依赖文件。
$< :当前规则的依赖文件列表中比目标新的依赖文件。
$?:当前目标的所有依赖文件中比目标新的依赖文件。
用于依赖文件列表的动态宏:
$$@ :目标文件名。如果目标是库,表示库名。
$$% :目标文件名。如果目标是库,表示成员名。
$$> :去掉后缀的目标文件名。
$$* :仅当目标文件是库的成员时使用,表示库名。
修改宏:
适用与代表文件名(或文件列表)、或者至少有着文件名形式的宏: 如
FILE=/home/friky/hello.o /home/h.c mf.h
$(FILE:d) 展开路径 /home/friky /home .
$(FILE:b) 展开无扩展名的文件名 hello h mf
$(FILE:f) 展开文件名 hello.o h.c mf.h
$(FILE:db) /home/friky/hello ……
替换宏中字符串:
宏:s/原字符串/替换字符串 替换
宏:原扩展名=新扩展名
仅适用与表示文件列表的宏
宏:^”前缀”
宏:+”后缀”
如:FILE:^”/usr/” :+”.o”
注:前缀、后缀的修改,make默认为宏表示文件名列表,如果宏中有空格,make会任务有多个文件名,对每个文件名都进行前缀、后缀操作。如果前缀、后缀中也有空格,就会以空格为分割,从前缀、后缀中逐个提取字符串,分别与各个文件名组合。 如:FILE=h d $(FILE:^”1 2”)为1h 1d 2h 2d
Make预定义的宏:
AR:Ar 库管理命令
ARFLAGS:-ruv
AS:as 汇编程序
ASFLAGS:
CC:cc c编译器
CFLAGS:-O
C++C:CC c++编译器
C++FLAGS:-O
CXX:g++ c++编译器
CXXFLAGS:
CPP:$(CC) –E 带标注输出的预处理程序
CPPFLAGS:
LD:ld 链接器
LDFLAGS:
RM:rm –f
MAKE:make
MAKEFLAGS:NULL
LIBSUFFIXE:.a 库扩展名 A:.a
MAKE和MAKEFLAGS这两个宏用于makefile中嵌套make命令行,来完成程序不同模块间makefile的互相调用。即使make命令中用了-n,MAKE宏也要执行。makefile phony
内部规则:
内部规则根据目标文件和依赖文件的扩展名定义,在正式执行make前就已经定义好了,如果makefile没有显式的定义关于某个目标文件的规则,make就会根据该目标文件的扩展名相应的内部规则,——删掉目标文件后缀,加上预定义的依赖文件后缀,得到完整依赖文件,结合内部规则的命令行生成完整的规则。
.h 头文件
.o 目标文件
.c c源文件
.C c++源文件
.s 汇编源文件
.f FORTRAN源文件
.sh shell文件
.y Yacc-C源语法
.l Lex源语法
内部规则可以是单后缀的或双后缀的。单后缀只给出目标文件后缀,无依赖文件。双后缀,第一个后缀为依赖文件扩展名,第二个后缀为目标文件后缀。如:
.c:
$(CC) $(CFLAGS) –O $@ $<
.c .o:
$(CC) $(CFLAGS) –c $<
注意:可能一个后缀名出现在多条内部规则中,如:.c.o/.f.o等。实际上,make为.o寻内
部规则时,到一个匹配规则,还要看在当前工作目录是否有与目标文件同名、且后缀为规则第一个后缀的文件,到,应用该规则,否则,继续内部规则。
exanple1: main.o proc1.o proc2.o
gcc main.o proc1.o proc2.o -o example1
main.o: main.c mylib.h
gcc -c main.c
proc1.o: proc1.c mylib.h
gcc -c proc1.c
proc2.o: proc2.c
gcc -c proc2.c
利用内部规则,可简写成:
exanple1: main.o proc1.o proc2.o
gcc main.o proc1.o proc2.o -o example1
main.o proc1.o:mylib.h
修改内部规则:
1. 修改内部规则中用到的宏
2. 重写整个内部规则,最好放在makefile最前面,make处理makefile时,运行到该语句,就会用新的定义覆盖原有内部规则,在后面再用到这个规则,就会使用新的规则。
定义新的后缀和内部规则:
定义后缀:NEW ROMAN:后缀名 后缀名
如:SUFFIXES:.n
若定义个.o.n内部规则,但当前工作文件夹只有hello.c文件,执行make hello.n,不能正常工
作,因为make一次只能检查一个内部规则。make hello.o hello.n就OK了,需要一个中间过程生成hello.o供.o.n规则使用。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论