@@ -48,6 +48,9 @@ makefile规则中,如果使用一个没有依赖只有命令行的双冒号规
4848次执行make时,此规则的目标文件将会被无条件的更新(即此规则定义的命令会被无条件执
4949行).
5050
51+ makefile中的命令是和shell有紧密的关系的,除了一些隐含的规则和变量以及make中的函
52+ 数,都是shell中的命令,所以shell是make编译的基石.
53+
5154通常我们在工程中会遇到,其中一个(makefile-A)需要使用另外一个(makefile-B)中所定
5255义的变量和规则.这时候用include(用来包含其它文件)并不保险,因为这两个文件可能存
5356在规则重复定义的问题.如下可解决问题:
@@ -95,6 +98,330 @@ make如何解析makefile文件
9598第二阶段:根据第一阶段已经建立的依赖关系结构链表决定哪些目标需要更新和创建,并使
9699用对应的规则来重建这些目标.
97100
101+ ------------------------------makefile语法------------------------------------
102+
103+ 这里不可能详细的介绍每一个细节,如果要这样的话,我们需要写上一本书了.这里只做大
104+ 致的介绍以方便我们使用.如果你是一个linux的shell用户理解这些并不难,这些东西和我
105+ 们通常使用的shell是浑然天成的. Let's Go>>
106+
107+ ------------------------------makefile语法------------------------------------
108+
109+
110+ GUN make可识别的指示符:
111+
112+
113+ 1)多行的定义
114+ define VARIABLE
115+ endef
116+
117+ 2)条件判断的基本语法
118+ ifdef VARIABLE 如果定义了变量
119+ ifndef VARIABLE 如果没有定义变量
120+ ifeq (A,B) 如果A和B相等
121+ ifeq "A" "B" 如果A和B相等
122+ ifeq 'A' 'B' 如果A和B相等
123+ ifneq (A,B) 如果A和B不相等
124+ ifneq "A" "B" 如果A和B不相等
125+ ifneq 'A' 'B' 如果A和B不相等
126+ else 条件分支
127+ endif 条件分支结束
128+
129+ 3)包含其他makefile文件
130+ include FILE 包含其他的makefile文件
131+ -include FILE 当所要包含的文件不存在时不会有错误提示
132+ sinclude FILE 通-include相同,那个s代表"静默"
133+ 对于FILE可以使用通配符
134+
135+ 4)通过override锁定定义变量
136+ 对于一个在makefile中使用常规方式(使用"=",":="或者"define")定义的变量,我们可以
137+ 通过命令行方式重新指定这个变量的值,如果我不希望命令行指定的变量值代替makefile
138+ 中变量定义,那么可以使用override来对这个变量进行声明.
139+ override VARIABLE = VALUE 声明一个锁定的变量
140+ override VARIABLE := VALUE 声明一个锁定的变量,可以覆盖之前的值
141+ override VARIABLE += VALUE 对声明的锁定变量进行追加的值
142+ override VARIABLE ?= VALUE 对声明的锁定变量如果没有被赋值使用此值
143+ override define VARIABLE 声明多行锁定变量
144+ endef 声明多行锁定变量结束
145+
146+ 5)导入变量关键字(export)
147+ 如果需要在上层make执行的makefile变量传递给子make过程,那么这个在上层makefile文
148+ 件中的变量必须使用export指示符进行声明
149+ export VARIABLE 需要将这层声明的变量传递给子make进程
150+ unexport VARIABLE 不需要将这层声明的变量传递给子make进程
151+
152+ 6)目录搜索(vpath VPATH)
153+ 通过变量VPATH可以指定依赖文件的搜索路径,当规则的依赖文件在当前目录不存在,make
154+ 会在此变量所制定的目录下去寻找这些依赖文件,而关键字vpath则更为灵活,可以为不同
155+ 类型的文件(由文件名区分)指定不同的搜索目录.
156+ vpath PATTERN PATH 为所有符合模式"PATTERN"的文件指定搜索目录"PATH"
157+ vpath PATTERN 清除之前符合模式"PATTERN"的文件设置的搜索路径.
158+ vpath 清除所有已被设置的文件搜索路径.
159+ vpath使用方法中的"PATTERN"需要包含模式字符"%"."%"意思是匹配一个或者多个字符.
160+ 例如,"%.h"表示所有以".h"结尾的文件.
161+
162+
163+ GNU make函数:
164+
165+
166+ 函数的书写$(FUNCTION ARGUMENTS)或者${FUNCTION ARGUMENTS}
167+ 对于用户自己的函数需要通过make的call函数来间接调用
168+ 在makefile中应该这样书写$(sort $(x))
169+ 参数和函数名之间可以使用若干个空格,函数的参数之间不能出现逗号和空格
170+
171+ 1)文本处理函数
172+
173+ subst $(subst $(FROM)$(TO)$(TEXT))
174+ 字符串替换函数
175+ 把字串TEXT中的FROM字串替换为TO.
176+ 返回值:替换后的新字符串.
177+
178+ patsubst $(patsubst $(PATTERN)$(REPLACEMENT)$(TEXT))
179+ 模式替换函数
180+ 搜索TEXT中以空格分开的单词,将符合模式PATTERN替换为REPLACEMENT.
181+ 返回值:替换后的新字符串.
182+
183+ strip $(strip $(STRINT)
184+ 去空格函数
185+ 去掉字串STRINT开头和结尾的空字符,并将其中多个连续空字符合并为一个空字符.
186+ 返回值:无前导和结尾空字符,使用单一空格分割的多单词字符串.
187+
188+ findstring $(findstring $(FIND)$(IN))
189+ 查找字符串函数
190+ 搜索字串IN,查找FIND字串.
191+ 返回值:如果在IN之中存在FIND,则返回FIND,否则返回空.
192+
193+ filter $(filter $(PATTERN...)$(TEXT))
194+ 过滤函数
195+ 过滤掉字串TEXT中所有不符合模式PATTERN的单词,保留所有符合此模式的单词.
196+ 返回值:空格分割的TEXT字串中所有符合模式PATTERN字串.
197+
198+ filter-out $(filter-out $(PATTERN...)$(TEXT))
199+ 反过滤函数
200+ 与filter相反
201+ 返回值:空格分割的TEXT字串中所有不符合模式PATTERN的字串.
202+
203+ sort $(sort $(LIST))
204+ 排序函数
205+ 给字串LIST中的单词以首字母为准进行排序(升序),并去掉重复的单词.
206+ 返回值:空格分割的没有重复单词的字串.
207+
208+ word $(word $(N)$(TEXT))
209+ 取单词函数
210+ 取字串TEXT中第N个单词.
211+ 返回值:返回字串TEXT中第N个单词.
212+
213+ wordlist $(wordlist $(S)$(E)$(TEXT))
214+ 取字串函数
215+ 从字串TEXT中取出从S开始到E的单词串,S和E表示单词位置的数字.
216+ 返回值:字串TEXT中从第S到E的单词字串.
217+
218+ words $(words $(TEXT))
219+ 统计单词数目函数
220+ 计算字串TEXT中单词的数目.
221+ 返回值:TEXT字串中的单词数.
222+
223+ firstword $(firstword $(NAMES...))
224+ 取首单词函数
225+ 取字串NAMES...中的第一个单词.
226+ 返回值:字串NAMES...对的第一个单词.
227+
228+ 2)文件名处理函数
229+
230+ dir $(dir $(NAMES...))
231+ 取目录函数
232+ 从文件名序列NAMES中取出各个文件名的目录部分.
233+ 返回值:空格分割的文件名序列NAMES...中每一个文件的目录部分.
234+
235+ notdir $(notdir $(NAMES...))
236+ 取文件名函数
237+ 从文件名序列NAMES...中取出非目录部分.
238+ 返回值:文件名序列NAMES...中每一个文件的非目录部分.
239+
240+ suffix $(suffix $(NAMES...))
241+ 取后缀函数
242+ 从文件名序列NAMES...中取出各个文件名的后缀.
243+ 返回值:以空格分割的文件名序列NAMES...中每一个文件的后缀序列.
244+
245+ basename $(basename $(NAMES...))
246+ 取前缀函数
247+ 从文件名序列NAMES...中取出各个文件名的前缀部分.
248+ 返回值:空格分割的文件名序列NAMES...中各个文件的前缀序列.如果没有前缀,返回空.
249+
250+ addsuffix $(addsuffix $(SUFFIX)$(NAMES...))
251+ 加后缀函数
252+ 为NAMES...中的每一个文件名添加后缀SUFFIX.
253+ 返回值:以单空格分割的添加了后缀SUFFIX的文件名序列.
254+
255+ addprefix $(addprefix $(PREFIX)$(NAMES...))
256+ 加前缀函数
257+ 为NAMES...中的每一个文件名添加前缀PREFIX.
258+ 返回值:以单空格分割的添加了前缀PREFIX的文件名序列.
259+
260+ join $(join $(LIST1)$(LIST2))
261+ 单词连接函数
262+ 将字串LIST1和字串LIST2各单词进行对应连接.
263+ 返回值:单空格分割的合并后的字(文件名)序列.
264+
265+ wildcard $(wildcard $(PATTERN))
266+ 获取匹配模式文件名函数
267+ 列出当前目录下所有符合模式PATTERN格式的文件名.
268+ 返回值:空格分割的,存在当前目录下的所有符合模式PATTERN的文件名.
269+
270+ 3)杂项函数
271+
272+ error $(error $(TEXT...))
273+ 产生致命错误,并提示TEXT...信息给用户,并退出make的执行.
274+
275+ warning $(warning $(TEXT...))
276+ 函数warning类似于函数error,区别在于它不会导致致命错误(make不退出).
277+
278+ shell $(shell $(....))
279+ shell函数所实现的功能和shell中引用``相同.
280+
281+ origin $(origin VARIABLE)
282+ 函数origin的动作不是操作变量(它的参数).它只是获取此变量(参数)相关的信息,告诉我
283+ 们这个变量的出处(定义方式).
284+ 返回值:undefined(未定义)default(内嵌变量)environment(环境变量)
285+ environment override(锁定环境变量)file(文件)command line(命令行定义)
286+ override(锁定变量)automatic(自动化变量)
287+
288+ foreach $(foreach $(VAR)$(LIST)$(TEXT))
289+ 循环函数
290+ 首先展开变量VAR和LIST的引用,而表达式TEXT中的变量引用不展开.执行时把LIST中使用
291+ 空格分割的单词依次取出赋值给变量VAR,然后执行TEXT表达式.重复直到LIST的最后一个
292+ 单词(为空时结束).
293+
294+ call $(call $(VARIABLE)$(PARAM)$(PARAM))
295+ call函数是唯一一个可以创建定制化参数函数的引用函数.使用这个函数可以实现对用户
296+ 自已定义函数引用.
297+
298+ if $(if $(CONDITION)$(THEN-PART)[$(ELSE-PART)])
299+ 条件函数
300+
301+ eval
302+ 实现复杂通用的模板函数.
303+
304+ value $(value $(VARIABLE))
305+ 函数value提供了一种在不对变量进行展开的情况下获取变量值的方法.
306+
307+
308+ GNU make的自动化变量:
309+
310+
311+ 模式规则中,规则的目标和依赖文件名代表了一类文件名;规则的命令是对所有这一类文件
312+ 重建过程的描述,显然,在命令中不能出现具体的文件名,否则模式规则失去意义.那么在模
313+ 式规则的命令行中该如何表示文件.为了解决这个问题,就需要使用'自动环变量',自动化
314+ 变量的取值是根据具体所执行的规则来决定的,取决于所执行规则的目标和依赖文件名.
315+
316+ $@ 表示规则的目标文件名.
317+ $% 当规则的目标文件是一个静态库文件时,代表静态库的一个成员名.
318+ $< 规则的第一个依赖文件名.
319+ %? 所有比目标文件更新的依赖文件列表,空格分割.
320+ $^ 规则的所有依赖文件列表,使用空格分隔.
321+ $+ 类似$^,但是它保留了依赖文件中重复出现的文件.
322+ $* 表示文件中除后缀以外的部分.
323+
324+ GUN make中,还可以通过这七个自动化变量来获取一个完整文件名中的目录(D)部分和具体
325+ 文件名(F)部分.
326+
327+ $(@D) 表示目标文件的目录部分(不包括斜杠).
328+ $(@F) 目标文件的完整文件名中除目录以外的部分(实际文件名).
329+ $(*D) 表示目录部分.
330+ $(*F) 表示文件名部分.
331+ $(%D) 当以如archive(member)形式静态库为目标时,表示库文件中的目录部分.
332+ $(%F) 当以如archive(member)形式静态库为目标时,表示库文件中的文件名部分.
333+ $(<D) 表示规则中第一个依赖文件的目录部分.
334+ $(<F) 表示规则中第一个依赖文件的文件名部分.
335+ $(^D) 表示所有依赖文件的目录部分.
336+ $(^F) 表示所有依赖文件的文件名部分.
337+ $(+D) 表示所有依赖文件的目录部分(可存在重复文件).
338+ $(+F) 表示所有依赖文件的文件部分(可存在重复文件).
339+ $(?D) 表示被更新的依赖文件的目录部分.
340+ $(?F) 表示被更新的依赖文件的文件名部分.
341+
342+
343+ GNU make环境变量
344+
345+
346+ MAKEFILES
347+ 如果在当前环境定义了一个MAKEFILES环境变量,make执行时首先将此变量的值作为需要读
348+ 入的Makefile文件,多个文件之间使用空格分开.
349+
350+ MAKEFILES_LIST
351+ make程序在读取多个makefile文件时,包括由环境变量MAKEFILES指定,命令行指当前工作
352+ 下的默认的以及使用指示符include指定包含的,在对这些文件进行解析执行之前make读取
353+ 的文件名将会被自动依次追加到变量MAKEFILE_LIST的定义域中.
354+
355+ VPATH
356+ 这个变量已经在和关键字作比较时已经介绍过了.
357+
358+ SHELL
359+ 它作为一个变量,我们也可以在Makefile中明确地给它赋值(指出解释程序的名字,当明确
360+ 指定时需要使用完整的路径名.如/bin/sh),变量SHELL的默认值是/bin/sh.
361+
362+ MAKE
363+ 在使用make的递归调用时,在Makefile规则的命令行中应该使用变量MAKE来代替直接使用
364+ make.
365+
366+ CURDIR
367+ 在make的递归调用中,需要了解一下变量CURDIR,此变量代表make的工作目录.当使用-C选
368+ 项进入一个子目录后,此变量将被重新赋值.
369+
370+ .SUFFIXES
371+ 可识别的后缀指的是特殊目标.SUFFIXES所有依赖的名字.通过给特殊目标SUFFIXES添加依
372+ 赖来增加一个可被识别的后缀.使用如下:
373+ .SUFFIXES: #删除所有已定义的可识别后缀
374+ .SUFFIXES: .c .o .h #重新定义
375+
376+ .LIBPATTERNS
377+ 变量.LIBPATTERNS就是告诉链接器在执行链接过程中对于出现-LNAME的文件如何展开.当
378+ 然也可以将此变量为空,取消链接器对-lNAME格式的展开.
379+
380+
381+ GUN make隐含变量:
382+
383+
384+ AR 函数库打包程序,可创建静态库.a文档,默认是ar.
385+ AS 汇编程序.默认是as.
386+ CC C编译程序.默认是cc.
387+ CXX C++编译程序,默认是g++.
388+ CO 从RCS中提取文件的程序.默认是co.
389+ CPP C程序的预处理器(输出是标准输出设备).默认是$(CC) –E
390+ FC 编译器和预处理Fortran和Ratfor源文件的编译器,默认是f77.
391+ GET 从SCCS中提取文件程序.默认是get.
392+ LEX 将Lex语言转变为C或Ratfor的程序.默认是lex.
393+ PC Pascal语言编译器.默认是pc.
394+ YACC Yacc文法分析器(针对C程序).默认命令是yacc.
395+ YACCR Yacc文法分析器针对于Ratfor程序).默认是yacc –r
396+ MAKEINFO 转换Texinfo源文件.texi到Info文件程序.默认是makeinfo.
397+ TEX 从TeX源文件创建TeX DVI文件的程序.默认是tex.
398+ TEXI2DVI 从Texinfo源文件创建TeX DVI文件的程序.默认是texi2dvi.
399+ WEAVE 转换Web到TeX的程序.默认是weave.
400+ CWEAVE 转换C Web到TeX的程序.默认是cweave.
401+ TANGLE 转换Web到Passcal语言的程序.默认是tangle.
402+ CTANGLE 转换C Web到C.默认是ctangle.
403+ RM 删除命令默认是rm –f.
404+
405+
406+ GUN make隐含命令参数的变量:
407+
408+
409+ 下面的是代表命令执行参数的变量.如果没有给出默认值则默认值为空.
410+
411+ ARFLAGS 执行AR命令的命令行参数.默认值是rv.
412+ ASFLAGS 执行汇编器AS的命令行参数.(当明显的调用.s或.S文件时).
413+ CFLAGS 执行CC编译器的命令行参数(编译.c源文件的选项).
414+ CXXFLAGS 执行g++编译器的命令行参数(编译.cc源文件的选项).
415+ COFLAGS 执行co的命令行参数(在RCS中提取文件的选项).
416+ CPPFLAGS 执行C预处理器cc –E的命令行参数(C和Fortran编译器会用到)
417+ FFLAGS Fotran语言编译器f77执行的命令行参数(编译Fortran源文件的选项).
418+ GFLAGS SCCS "get"程序参数.
419+ LDFLAGS 连接器参数.(如:ld)
420+ LFLAGS Lex文法分析器参数
421+ PFLAGS Pascal语言编译器参数.
422+ RFLAGS Ratfor程序的Fortran编译器参数.
423+ YFLAGS Yacc文法分析器参数.
424+
98425
99426==============================================================================
100427==============================================================================
0 commit comments