Makefile系列之二 : 命令
一、显示命令 echo
“@”字符可以控制命令是否在屏幕上显示,如
@echo 正在编译XXX模块......
输出:
正在编译XXX模块......
如果没有“@"则输出 :
echo 正在编译XXX模块......
正在编译XXX模块......
二、make参数
下面列举了所有GNU make 3.80版的参数定义。
1)make “-n”或“--just-print”
——只显示命令,但不会执行命令。
make “-s”或“--slient”
——全面禁止命令的显示。
2)make “-i”或“--ignore-errors”
——Makefile中所有命令都会忽略错误。而如果某规则是以“.IGNORE”作为目标的,那么该规则中的所有命令将会忽略错误。
注意 : makefile是由许多规则组成,而规则又由目标、依赖及命令组成,每当命令运行完后,make会检测每个命令的返回码,如果命令返回成功,那么make会执行下一条命令,当规则中所有的命令成功返回后,这个规则就算是成功完成了。如果一个规则中的某个命令出错了(命令退出码非零),那么make就会终止执行当前规则,这将有可能终止所有规则的执行。而有些命令执行不成功并不会影响后续命令的执行,所以为了让命令继续执行,可以通过在命令前加“-”来忽略执行命令的错误,如
clean:
-rm -f *.o #忽略删除文件时遇到的错误,让命令继续执行
3)make “-w”或“--print-directory”
——会在make的过程中输出目前的工作目录的信息。比如,如果下级make目录是“/home/hchen/gnu/make”,当使用“make -w”来执行时,那么当进入该目录时,屏幕会输出:
make: Entering directory `/home/hchen/gnu/make'.
而在完成下层make后离开目录时,屏幕会输出:
make: Leaving directory `/home/hchen/gnu/make'
当你使用“-C”参数来指定make下层Makefile时,“-w”会被自动打开的。如果参数中有“-s”(“--slient”)或是“--no-print-directory”,那么,“-w”总是失效的。
4)“-b” “-m”
——这两个参数的作用是忽略和其它版本make的兼容性。
5)“-B” “--always-make”
——认为所有的目标都需要更新(重编译)。
6) “-C <dir>” “--directory=<dir>”
——指定读取makefile的目录。如果有多个“-C”参数,make的解释是后面的路径以前面的作为相对路径,并以最后的目录作为被指定目录。如:
“make –C ~hchen/test –C prog” 等价于 “make –C ~hchen/test/prog”。
7) “--debug[=<options>]”
——输出make的调试信息。它有几种不同的级别可供选择,如果没有参数,那就是输出最简单的调试信息。下面是<options>的取值:
a —— 也就是all,输出所有的调试信息。(会非常的多)
b —— 也就是basic,只输出简单的调试信息。即输出不需要重编译的目标。
v —— 也就是verbose,在b选项的级别之上。输出的信息包括哪个makefile被解析,不需要被重编译的依赖文件(或是依赖目标)等。
i —— 也就是implicit,输出所以的隐含规则。
j —— 也就是jobs,输出执行规则中命令的详细信息,如命令的PID、返回码等。
m —— 也就是makefile,输出make读取makefile,更新makefile,执行makefile的信息。
“-d” 相当于 “--debug=a”。
8)“-e” “--environment-overrides”
——指明环境变量的值覆盖makefile中定义的变量的值。
9)“-f=<file>” “--file=<file>” “--makefile=<file>”
——指定需要执行的makefile。
10) “-h” “--help”
——显示帮助信息。
11)“-i” “--ignore-errors”
——在执行时忽略所有的错误。
12)“-I <dir>” “--include-dir=<dir>”
——指定一个被包含makefile的搜索目标。可以使用多个“-I”参数来指定多个目录。
13) “-j [<jobsnum>]” “--jobs[=<jobsnum>]”
——指同时运行命令的个数。如果没有这个参数,make运行命令时能运行多少就运行多少。如果有一个以上的“-j”参数,那么仅最后一个“-j”才是有效的。(注意这个参数在MS-DOS中是无用的)
14) “-k” “--keep-going”
——出错也不停止运行。如果生成一个目标失败了,那么依赖于其上的目标就不会被执行了。
15)“-l <load>” “--load-average[=<load]” “—max-load[=<load>]”
——指定make运行命令的负载。
16)“-n” “--just-print” “--dry-run” “--recon”
——仅输出执行过程中的命令序列,但并不执行。
17)“-o <file>” “--old-file=<file>” “--assume-old=<file>”
——不重新生成的指定的<file>,即使这个目标的依赖文件新于它。
18)“-p” “--print-data-base”
——输出makefile中的所有数据,包括所有的规则和变量。这个参数会让一个简单的makefile都会输出一堆信息。如果你只是想输出信息而不想执行makefile,你可以使用“make -qp”命令。如果你想查看执行makefile前的预设变量和规则,你可以使用“make –p –f /dev/null”。这个参数输出的信息会包含着你的makefile文件的文件名和行号,所以,用这个参数来调试你的makefile会是很有用的, 特别是当你的环境变量很复杂的时候。
19)“-q” “--question”
——不运行命令,也不输出。仅仅是检查所指定的目标是否需要更新。如果是0则说明要更新,如果是2则说明有错误发生。
20)“-r” “--no-builtin-rules”
——禁止make使用任何隐含规则。
21)“-R” “--no-builtin-variabes”
——禁止make使用任何作用于变量上的隐含规则。
22)“-s” “--silent” “--quiet”
——在命令运行时不输出命令的输出。
23)“-S” “--no-keep-going” “--stop”
——取消“-k”选项的作用。因为有些时候,make的选项是从环境变量“MAKEFLAGS”中继承下来的。所以你可以在命令行中使用这个参数来让环境变量中的“-k”选项失效。
24)“-t” “--touch”
——相当于UNIX的touch命令,只是把目标的修改日期变成最新的,也就是阻止生成目标的命令运行。
25)“-v” “--version”
——输出make程序的版本、版权等关于make的信息。
26)“-w” “--print-directory”
——输出运行makefile之前和之后的信息。这个参数对于跟踪嵌套式调用make时很有用。
27)“--no-print-directory”
——禁止“-w”选项。
28) “-W <file>” “--what-if=<file>” “--new-file=<file>” “--assume-file=<file>”
——假定目标<file>需要更新,如果和“-n”选项使用,那么这个参数会输出该目标更新时的运行动作。如果没有“-n”那么就像运行UNIX的“touch”命令一样,使得<file>的修改时间为当前时间。
29)“--warn-undefined-variables”
——只要make发现有未定义的变量,那么就输出警告信息。
三、执行命令
如果要让上一条命令的结果应用在下一条命令时,必须用分号分隔这两条命令。比如你的第一条命令是cd命令,如:
示例一:
exec:
cd /home/hchen
pwd
示例二:
exec:
cd /home/hchen; pwd
当执行“make exec”时,第一个例子中的cd没有作用,pwd会打印出当前的Makefile目录,而第二个例子中,cd就起作用了,pwd会打印出“/home/hchen”。
四、命令包定义
如果Makefile中出现一些相同命令序列,那么我们可以为这些相同的命令序列定义一个变量。定义这种命令序列的语法以“define”开始,以“endef”结束,如:
define run-yacc
yacc $(firstword $^)
mv y.tab.c $@
endef
“run-yacc”是这个命令包的名字,不能与Makefile中的变量重名。在
“define”和“endef”中的两行就是命令序列。这个命令包中的第一个命令是运行Yacc程序,因为Yacc程序总是生成“y.tab.c”的文件,所以第二行的命令就是把这个文件改改名字。
五、嵌套执行make
在一些大的工程中,我们会把我们不同模块或是不同功能的源文件放在不同的目录中,我们可以在每个目录中都书写一个该目录的Makefile,这有利于让我们的Makefile变得更加地简洁,而不至于把所有的东西全部写在一个Makefile中,这样会很难维护我们的Makefile,这个技术对于我们模块编译和分段编译有着非常大的好处。
例如,我们有一个子目录叫subdir,这个目录下有个Makefile文件,来指明了这个目录下文件的编译规则。那么我们总控的Makefile可以这样书写:
subsystem:
cd subdir && $(MAKE)
其等价于:
subsystem:
$(MAKE) -C subdir
定义$(MAKE)宏变量可以让我们更方便地为make添加一些参数,这样比较利于维护。这两个例子的意思都是先进入“subdir”目录,然后执行make命令。
我们把这个Makefile叫做“总控Makefile”,总控Makefile的变量可以传递到下级的Makefile中(如果你显式的声明),但是不会覆盖下层的Makefile中所定义的变量,除非指定了“-e”参数。
如果你要传递变量到下级Makefile中,那么你可以使用这样的声明:
export <variable ...>
如果你不想让某些变量传递到下级Makefile中,那么你可以这样声明:
unexport <variable ...>
export variable = value
其等价于:
variable = value
export variable
其等价于:
export variable := value
传递所有的变量,那么,只要一个export就行了。后面什么也不用跟,表示传递所有的变量。
六、检查规则
1)不想makefile中的规则执行起来,只是检查一下命令或是执行的序列。
“-n”
“--just-print”
“--dry-run”
“--recon”
不执行参数,这些参数只是打印命令,不管目标是否更新,把规则和连带规则下的命令打印出来,但不执行,这些参数对于我们调试makefile很有用处。
2)
“-t”
“--touch”
这个参数的意思就是把目标文件的时间更新,但不更改目标文件。也就是说,make假装编译目标,但不是真正的编译目标,只是把目标变成已编译过的状态。
3)
“-q”
“--question”
这个参数的行为是找目标的意思,如果目标存在,那么其什么也不会输出,当然也不会执行编译,如果目标不存在,其会打印出一条出错信息。
4)
“-W <file>”
“--what-if=<file>”
“--assume-new=<file>”
“--new-file=<file>”
这个参数需要指定一个文件。一般是是源文件(或依赖文件),Make会根据规则推导来运行依赖于这个文件的命令,一般来说,可以和“-n”参数一同使用,来查看这个依赖文件所发生的规则命令。
Makefile系列之二 : 命令的更多相关文章
- nginx高性能WEB服务器系列之二命令管理
nginx系列友情链接:nginx高性能WEB服务器系列之一简介及安装https://www.cnblogs.com/maxtgood/p/9597596.htmlnginx高性能WEB服务器系列之二 ...
- ES6+ 现在就用系列(二):let 命令
系列目录 ES6+ 现在就用系列(一):为什么使用ES6+ ES6+ 现在就用系列(二):let 命令 ES6+ 现在就用系列(三):const 命令 ES6+ 现在就用系列(四):箭头函数 => ...
- 《sed的流艺术之四》-linux命令五分钟系列之二十四
本原创文章属于<Linux大棚>博客,博客地址为http://roclinux.cn.文章作者为rocrocket. 为了防止某些网站的恶性转载,特在每篇文章前加入此信息,还望读者体谅. ...
- 《sed的流艺术之三》-linux命令五分钟系列之二十三
本原创文章属于<Linux大棚>博客,博客地址为http://roclinux.cn.文章作者为rocrocket. 为了防止某些网站的恶性转载,特在每篇文章前加入此信息,还望读者体谅. ...
- 《sed的流艺术之二》-linux命令五分钟系列之二十二
本原创文章属于<Linux大棚>博客,博客地址为http://roclinux.cn.文章作者为rocrocket. 为了防止某些网站的恶性转载,特在每篇文章前加入此信息,还望读者体谅. ...
- 《sed的流艺术之一》-linux命令五分钟系列之二十一
本原创文章属于<Linux大棚>博客,博客地址为http://roclinux.cn.文章作者为rocrocket. 为了防止某些网站的恶性转载,特在每篇文章前加入此信息,还望读者体谅. ...
- Java命令学习系列(二)——Jstack
Java命令学习系列(二)——Jstack 2015-04-18 分类:Java 阅读(512) 评论(0) jstack是java虚拟机自带的一种堆栈跟踪工具. 功能 jstack用于生成java虚 ...
- Open vSwitch系列之二 安装指定版本ovs
在ovs学习过程中,如果自己想要安装一个ovs交换机其实一条简单的命令 apt install openvswitch 就可以了,但是这种方法只能安装低版本的ovs.在特殊情况下需要安装指定版本,例 ...
- 【转】RHadoop实践系列之二:RHadoop安装与使用
RHadoop实践系列之二:RHadoop安装与使用 RHadoop实践系列文章,包含了R语言与Hadoop结合进行海量数据分析.Hadoop主要用来存储海量数据,R语言完成MapReduce 算法, ...
随机推荐
- [洛谷P3181][HAOI2016]找相同字符
题目大意:给你两个字符串,求从两个字符串中各选择一个字串使得这两个字串相同的方案数. 题解:建广义$SAM$,对每个点求出在第一个串中出现次数和第二个串中出现次数,乘起来就行了 卡点:无 C++ Co ...
- [bzoj] 3673 3674 可持久化并查集 || 可持久化数组
原题 加强版 题意: 可持久化并查集模板-- 题解: 用可持久化线段树维护一个可持久化数组,来记录每一次操作后的状态. 不能用路径压缩,但是要按置合并,使复杂度保证在O(log) #include&l ...
- HDOJ(HDU).1003 Max Sum (DP)
HDOJ(HDU).1003 Max Sum (DP) 点我挑战题目 算法学习-–动态规划初探 题意分析 给出一段数字序列,求出最大连续子段和.典型的动态规划问题. 用数组a表示存储的数字序列,sum ...
- bzoj2326:[HNOI2011]数学作业(分段矩阵乘法)
题目大意:输入n(n<=10^18)和m,将1~n的整数连起来模m输出,比如n=13则输出12345678910111213模m的数. 设f[i]为1~i整数连起来模m的数,i的位数为k,则有f ...
- middle中间件
什么事中间件: http://www.crazyant.net/1001.html dd
- Qt -------- 多线程编程
一.继承QThread(不推荐) 定义一个类,继承QThread,重写run(),当调用方法start(),启动一个线程,run()函数运行结束,线程结束. 二.继承QRunnable Qrunnab ...
- 使用 Rational AppScan 保证 Web 应用的安全性,第 1 部分: Web 安全与 Rational AppScan 入门
前言 当今世界,Internet(因特网)已经成为一个非常重要的基础平台,很多企业都将应用架设在该平台上,为客户提供更为方便.快捷的服务支持.这些应用 在功能和性能上,都在不断的完善和提高,然而在非常 ...
- javascript实现正整数分数约分
//m,n为正整数的分子和分母 function reductionTo(m, n) { var arr = []; if (!isInteger(m) || !isInteger(n)) { con ...
- overflow:auto产生的滚动条在安卓系统下能平滑滚动,而在ios下滚动不平滑
由于系统的问题,加上-webkit-overflow-scrolling : touch; 即可解决平滑滚动问题
- LightOJ 1093 - Ghajini 线段树
http://www.lightoj.com/volume_showproblem.php?problem=1093 题意:给定序列,问长度为d的区间最大值和最小值得差最大是多少. 思路:可以使用线段 ...