学写makefile(《跟我一起写Makefile-陈皓》笔记)
来源:互联网 发布:xilinx mac 编辑:程序博客网 时间:2024/05/22 13:03
1、Makefile用来告诉make命令如何编译和链接文件,规则是:
1) 如果这个工程没有编译过,那么所有C文件都要编译并被链接
2) 如果这个工程的某几个C文件被修改,那么我们只编译被修改的C文件,并链接目标程序。
3) 如果这个工程的头文件被改变了,那么需要编译引用了这几个头文件的C文件并链接目标程序。
2、注意:makefile文件中每行必须要以[table]键开始
3、可以使用include标识符,语法是:include <filename>
4、GNU的make工作时的执行步骤如下:
1) 读入所有的makefile
2) 读入被include指定的其他makefile
3) 初始化文件中的变量
4) 推导隐晦规则,并分析所有规则
5) 为所有的目标文件创建依赖关系链
6) 根据依赖关系,决定哪些目标要重新生成
7) 执行生成命令
1-5为第一阶段:如果定义的变量被使用了,那么make会把其展开在使用的位置。
5、在makefile编写规则中可以使用的通配符:“*”,“?”,“[…]”。
6、特殊变量VPATH,在make寻找文件的依赖关系时,该变量把一个路径告诉make,让他自动寻找。(多个目录之间使用“:”分割)。
7、vpath是make工具的一个关键字,比VPATH更灵活:
1)vpath<pattern> <dir>:为符合模式<pattern>的文件指定搜索目录
2)vpath<pattern>:清楚符合模式<pattern>的文件的所有目录
3)vpath:清除所有已被设置好的文件搜索目录
Vpath使用方法中的<pattern>需要包含“%”字符,表示匹配0或者若干字符(相当与*)。例子:$(objs): %.o: %.c
8、自动化变量:
“$<”:依赖目标中的第一个目标名字。
“$@”: 表示规则中的目标文件集。在模式规则中,如果有多个目标,那么,"$@"就是匹配于目标中模式定义的集合。
“$%”: 仅当目标是函数库文件中,表示规则中的目标成员名。例如,如果一个目标是"foo.a (bar.o)",那么,"$%"就是"bar.o","$@"就是"foo.a"。如果目标不是函数库文件(Unix下是[.a],Windows 下是[.lib]),那么,其值为空。
“$?”: 所有比目标新的依赖目标的集合,以空格分隔。
“$^”:所有的依赖目标的集合。以空格分隔。如果在依赖目标中有多个重复的,那个这个变量会去除重复的依赖目标,只保留一份。
“$+”:这个变量很像"$^",也是所有依赖目标的集合。只是它不去除重复的依赖目标。
“$*”:这个变量表示目标模式中"%"及其之前的部分。如果目标是"dir/a.foo.b",并且目标的模式是"a.%.b",那么,"$*"的值就是"dir/a.foo"。
“$(@D)”:表示"$@"的目录部分(不以斜杠作为结尾),如果"$@"值是"dir/foo.o",那么"$(@D)"
就是"dir",而如果"$@"中没有包含斜杠的话,其值就是"."(当前目录)。
“$(@F)”:表示"$@"的文件部分,如果"$@"值是"dir/foo.o",那么"$(@F)"就是"foo.o","$(@F)"相当于函数"$(notdir$@)"。
9、CFLAGS 表示用于 C 编译器的选项,
CXXFLAGS 表示用于 C++ 编译器的选项。这两个变量实际上涵盖了编译和汇编两个步骤。
CFLAGS: 指定头文件(.h文件)的路径,如:CFLAGS=-I/usr/include -I/path/include。同样地,安装一个包时会在安装路径下建立一个include目录,当安装过程中出现问题时,试着把以前安装的包的include目录加入到该变量中来。
LDFLAGS:gcc 等编译器会用到的一些优化参数,也可以在里面指定库文件的位置。用法:LDFLAGS=-L/usr/lib -L/path/to/your/lib。每安装一个包都几乎一定的会在安装目录里建立一个lib目录。如果明明安装了某个包,而安装另一个包时,它愣是说找不到,可以抒那个包的lib路径加入的LDFALGS中试一下。
LIBS:告诉链接器要链接哪些库文件,如LIBS = -lpthread-liconv
10、参数-M:自动的生成头文件依赖。GNU的c/c++编译器使用的是-MM,否则会把一些标准库的头文件也包含进来。
11、make会把要执行的命令行在命令执行前输出到屏幕上,用@字符在命令行前的话这个命令不被make显示出来。Make –s参数是全面禁止命令的显示。
12、如果要将变量传递到下一级,那么使用export关键字声明(unexport)。
13、在makefile中如果使用“=”为变量赋值,可以嵌套赋值(可能产生递归出错),比如:
A=$(b)
B=$(c)
C=”hello”
但是使用“:=”的话就不能这样赋值了,前边的变量不能使用后边的变量,只能使用在前边已经定义好的变量。
14、“+=”符号给变量追加值,例子:
objs=a.o b.o
objs +=
14、make的系统变量MAKELEVEL表示如果make有一个嵌套执行的动作,那么这个变量会记录当前Makefile的调用层数。
15、makefile中的字符串处理函数:
名称
语法
功能
返回
字符串替换函数-subst
$(subst <from>, <to>, <text>)
把字符串<text>中的<from>字符串替换成<to>
函数返回被替换过后的字符串
模式字符串替换函数-patsubst
$(patsubst <pattern>, <repalcement>, <text>)
查找<text>中的单词是否符合模式<pattern>,如果匹配的话则以<repalcement>替换
函数返回被替换过后的字符串
去空格函数-strip
$(strip <string>)
去掉<string>字串中开头和结尾的空字符
返回被去掉空格的字符串值
查找字符串函数—findstring
$(findstring <find>,<in>)
在字串<in>中查找<find>字串
如果找到,那么返回<find>,否则返回空字符串
过滤函数—filter
$(filter <pattern...>,<text>)
以<pattern>模式过滤<text>字符串中的单词,保留符合模式<pattern>的单词。可以有多个模式。
返回符合模式<pattern>的字串
反过滤函数—filter-out
$(filter-out <pattern...>,<text>)
以<pattern>模式过滤<text>字符串中的单词,去除符合模式<pattern>的单词。可以有多个模式。
返回不符合模式<pattern>的字串
排序函数—sort
$(sort <list>)
给字符串<list>中的单词排序(升序)
返回排序后的字符串(sort 函数会去掉<list>中相同的单词)
取单词函数—word
$(word <n>,<text>)
取字符串<text>中第<n>个单词。(从一开始)
返回字符串<text>中第<n>个单词。如果<n>比<text>中的单词数要大,那么返
回空字符串。
取单词串函数—wordlist
$(wordlist <s>,<e>,<text>)
从字符串<text>中取从<s>开始到<e>的单词串。<s>和<e>是一个数字。
返回字符串<text>中从<s>到<e>的单词字串。如果<s>比<text>中的单词数要大,那么返回空字符串。如果<e>大于<text>的单词数,那么返回从<s>开始,到<text>结束的单词串。
单词个数统计函数—words
$(words <text>)
统计<text>中字符串中的单词个数(如果我们要取<text>中最后的一个单词,我们可以这样:$(word $(words <te
xt>),<text>))。
返回<text>中的单词数
首单词函数—firstword
$(firstword <text>)
取字符串<text>中的第一个单词(这个函数可以用 word 函数来实现:$(word 1,<text>))
返回字符串<text>的第一个单词。
16、字符串处理函数
名称
语法
功能
返回
取目录函数—dir
$(dir <names...>)
从文件名序列<names>中取出目录部分。目录部分是指最后一个反斜杠(“/”)之前的部分。如果没有反斜杠,那么返回“./”。
返回文件名序列<names>的目录部分
取文件函数—notdir
$(notdir <names...>)
从文件名序列<names>中取出非目录部分。非目录部分是指最后一个反斜杠(“ /”)之后的部分。
返回文件名序列<names>的非目录部分
取后缀函数—suffix
$(suffix <names...>)
从文件名序列<names>中取出各个文件名的后缀。
返回文件名序列<names>的后缀序列,如果文件没有后缀,则返回空字串。
取前缀函数—basename
$(basename <names...>)
从文件名序列<names>中取出各个文件名的前缀部分。
返回文件名序列<names>的前缀序列,如果文件没有前缀,则返回空字串。
加后缀函数—addsuffix
$(addsuffix <suffix>,<names...>)
把后缀<suffix>加到<names>中的每个单词后面。
返回加过后缀的文件名序列。
加前缀函数—addprefix
$(addprefix <prefix>,<names...>)
把前缀<prefix>加到<names>中的每个单词后面
返回加过前缀的文件名序列
连接函数—join
$(join <list1>,<list2>)
把<list2>中的单词对应地加到<list1>的单词后面。如果<list1>的单词个数要比<list2>的多,那么,<list1>中的多出来的单词将保持原样。如果<list2>的单词个数要比<list1>多,那么,<list2>多出来的单词将被复制到<list2>中。
返回连接过后的字符串
是用来做循环用的函数-foreach
$(foreach <var>,<list>,<text>)
把参数<list>中的单词逐一取出放到参数<var>所指定的变量中,然后再执行<text>所包含的表达式。每一次<text>会返回一个字符串,循环过程中,<text>
的所返回的每个字符串会以空格分隔,最后当整个循环结束时,<text>所返回的每个字符串所组成的整个字符串(以空格分隔)将会是 foreach 函数的返回值。
if 函数很像 GNU 的 make 所支持的条件语句—ifeq
$(if <condition>,<then-part>)
或者
$(if <condition>,<then-part>,<else-part>)
if 函数可以包含“else”部分,或是不含。即 if 函数的参数可以是两个,也可以是三个。<condition>参数是 if 的表达式,如果其返回的为非空字符串,那么这个表达式就相当于返回真,于是,<then-part>会被计算,否则<else-part>会被计算。
而 if 函数的返回值是,如果<condition>为真(非空字符串),那个<then-part>会是整个函数的返回值,如果<condition>为假(空字符串),那么<else-part>会是整个函数的返回值,此时如果<else-part>没有被定义,那么,整个函数返回空字串。
call 函数
$(call <expression>,<parm1>,
<parm2>,<parm3>...)
个可以用来创建新的参数化的函数。你可以写一个非常复杂的表达式,这个表达式中,你可以定义许多参数,然后你可以用 call 函数来向这个表达式传递参数。
origin函数
$(origin <variable>)
并不操作变量的值,他只是告诉你你的这个变量是哪里来的
shell 函数
它的参数应该就是操作系统 Shell 的命令。它和反引号“`”是相同的功能。这就是说,shell 函数把执行操作系统命令后的输出作为函数返回。于是,我们可以用操作系统命令以及字符串处理命令 awk,sed 等等命令来生成一个变量
控制make 的函数
make 提供了一些函数来控制 make 的运行。通常,你需要检测一些运行 Makefile 时的
运行时信息,并且根据这些信息来决定,你是让 make 继续执行,还是停止。
17、make的命令执行后有三个退出码:
0-表示执行成功
1- 如果make运行时出现任何错误,返回1
2- 如果使用了make的-q选项,并且make使得一些目标不需要更新,那么返回2.
18、GNU make 找寻默认的Makefile 的规则是在当前目录下依次找三个文件“GNUmakefile”、“makefile”和“Makefile”。其按顺序找这三个文件,一旦找到,就开始读取这个文件并执行。也可以使用”-f”或者是”--file”指定make执行的文件。
- 学写makefile(《跟我一起写Makefile-陈皓》笔记)
- 跟我一起学写Makefile
- 跟我一起写 Makefile (陈皓)
- 《跟我一起写makefile》笔记
- 跟我一起写makefile 学习笔记
- 《跟我一起写Makefile》笔记
- 跟我一起写 Makefile
- 跟我一起写 Makefile
- 跟我一起写 Makefile
- 跟我一起写 Makefile
- 跟我一起写 Makefile
- 跟我一起写 Makefile
- 跟我一起写 Makefile
- 跟我一起写 Makefile
- 跟我一起写 Makefile
- 跟我一起写 Makefile
- 跟我一起写 Makefile
- 跟我一起写 Makefile
- RecyclerView的使用以及下拉刷新自动加载(添加点击事件、头部)
- 云帮系列文章:产品设计思想
- POJ 1200 Crazy Search
- SAP webservice 接口
- js实现密码加密
- 学写makefile(《跟我一起写Makefile-陈皓》笔记)
- poj2965深搜+枚举
- sql优化-use index
- list!=null和list.size()>0
- ubuntu Chromium 安装 pepperflashplugin
- Android 内存回收机制学习系列一之对象
- 管理系统UI之一:淡化System Bar(Dimming the System Bars)
- 互联网协议
- 哈希表及处理冲突的方法