shell 函数 :和反引号“`”是相同的功能 。

shell 函数把执行操作系统命令后的输出作为函数返回。

  1. contents := $(shell cat foo)
  2. files := $(shell echo *.c)
    这个函数会新生成一个 Shell 程序来执行命令,所以你要注意其运行性能,如果你的 Makefile 中有一些比较复杂的规则,并大量使用了这个函数,那么对于你的系统性能是有害的。特别是 Makefile 的隐晦的规则可能会让你的 shell 函数执行的次数比你想像的多得多

控制 make 的函数 :make 提供了一些函数来控制 make 的运行。通常,你需要检测一些运行 Makefile 时的运行时信息,并且根据这些信息来决定,你是让 make 继续执行,还是停止。

  1. $(error <text ...>)
  2. 产生一个致命的错误, <text ...>是错误信息。注意, error 函数不会在一被使用就会产生错误信息,所以如果你把其定义在某个变量中,并在后续的脚本中使用这个变量,那么也是可以的

eg:

  1. ifdef ERROR_001
  2. $(error error is $(ERROR_001))
  3. endif
  4.  
  5. 示例二:
  6. ERR = $(error found an error!)
  7. .PHONY: err
  8. err: ; $(ERR)
  9.  
  10. 示例一会在变量 ERROR_001 定义了后执行时产生 error 调用,而示例二则在目录 err被执行时才发生 error 调用
  1. $(warning <text ...>)
  2. error 函数,只是它并不会让 make 退出,只是输出一段警告信息,而make 继续执行。

make的运行:make 命令执行后有三个退出码: 

  1. —— 表示成功执行。
  2. —— 如果 make 运行时出现任何错误,其返回
  3. —— 如果你使用了 make 的“-q”选项,并且 make 使得一些目标不需要更新,那么返回

指定makefile:

找寻默认的 Makefile 的规则是在当前目录下依次找三个文件:“GNUmakefile”、“makefile”和“Makefile”。其按顺序找这三个文件,一旦找到,就开始读取这个文件并执行。

也可以给 make 命令指定一个特殊名字的 Makefile。要达到这个功能,我们要使用 make 的“-f”或是“--file”参数(“--makefile”参数也行)。例如,我们有个makefile 的名字是“hchen.mk”

  1. make f hchen.mk

一般来说:make 的最终目标是 makefile 中的第一个目标 ,其它目标一般是由这个目标连带出来的 。

任何在 makefile 中的目标都可以被指定成终极目标,但是除了以“-”打头,或是包含了“=”的目标,因为有这些字符的目标,会被解析成命令行参数或是变量。

有一个 make 的环境变量叫“MAKECMDGOALS,这个变量中会存放你所指定的终极目标的列表,如果在命令行上,你没有指定目标,那么,这个变量是空值。这个变量可以让你使用在一些比较特殊的情形下。

  1. sources = foo.c bar.c
  2. ifneq ( $(MAKECMDGOALS),clean)
  3. include $(sources:.c=.d)
  4. endif
    只要我们输入的命令不是“make clean”,那么 makefile 会自动包含“foo.d”和“bar.d”这两个 makefile

使用指定终极目标的方法可以很方便地让我们编译我们的程序,例如下面这个例子:

  1. .PHONY: all
  2. all: prog1 prog2 prog3 prog4
  3.  
  4. 这个 makefile 中有四个需要编译的程序——“prog1”,“prog2”, prog3”和 prog4”,我们可以使用“make all”命令来编译所有的目标(如果把 all 置成第一个目标,那么只需执行“make”),我们也可以使用“make prog2”来单独编译目标“prog2”。

当然 make 可以指定所有 makefile 中的目标,那么也包括“伪目标”

  1. all :这个伪目标是所有目标的目标,其功能一般是编译所有的目标。
  2. clean :这个伪目标功能是删除所有被 make 创建的文件。
  3. install :这个伪目标功能是安装已编译好的程序,其实就是把目标执行文件拷贝到指定的目标中去。
  4. print :这个伪目标的功能是例出改变过的源文件。
  5. tar :这个伪目标功能是把源程序打包备份。也就是一个 tar 文件。
  6. dist :这个伪目标功能是创建一个压缩文件,一般是把 tar 文件压成 Z 文件。或是 gz 文件。
  7. TAGS :这个伪目标功能是更新所有的目标,以备完整地重编译使用。
  8. check”和“test :这两个伪目标一般用来测试 makefile 的流程。

四、检查规则

不想让我们的 makefile 中的规则执行起来,我们只想检查一下我们的命令,或是执行的序列 ,于是我们可以使用 make 命令的下述参数: 

  1. “-n
  2. “--just-print
  3. “--dry-run
  4. “--recon

不执行参数,这些参数只是打印命令,不管目标是否更新,把规则和连带规则下的命令打印出来,但不执行,这些参数对于我们调试 makefile 很有用处。、

  1. “-t
  2. “--touch

这个参数的意思就是把目标文件的时间更新,但不更改目标文件。也就是说, make 假装编译目标,但不是真正的编译目标,只是把目标变成已编译过的状态。

  1. “-q
  2. “--question

这个参数的行为是找目标的意思,也就是说,如果目标存在,那么其什么也不会输出,当然也不会执行编译,如果目标不存在,其会打印出一条出错信息。

  1. “-W <file>
  2. “--what-if=<file>”
  3. “--assume-new=<file>”
  4. “--new-file=<file>”

这个参数需要指定一个文件。一般是是源文件(或依赖文件), Make 会根据规则推导来运行依赖于这个文件的命令,一般来说,可以和“-n”参数一同使用,来查看这个依赖文件所发生的规则命令。

另外一个很有意思的用法是结合“-p”和“-v”来输出 makefile 被执行时的信息

GNU make 3.80 版的参数定义 :

  1. “-b
  2. “-m
  3. 这两个参数的作用是忽略和其它版本 make 的兼容性。
  4.  
  5. “-B
  6. “--always-make
  7. 认为所有的目标都需要更新(重编译)。
  8.  
  9. “-C <dir>
  10. “--directory=<dir>”
  11. 指定读取 makefile 的目录。如果有多个“-C”参数, make 的解释是后面的路径以前面的作为相对路径,并以最后的目录作为被指定目录。如:“make C ~hchen/test C prog”等价于“make C ~hchen/test/prog”。
  12.  
  13. “—debug[=<options>]”
    输出 make 的调试信息。它有几种不同的级别可供选择,如果没有参数,那就是输出最简单的调试信息。下面是<options>的取值:
    a —— 也就是 all,输出所有的调试信息。(会非常的多)
    b —— 也就是 basic,只输出简单的调试信息。即输出不需要重编译的目标。
    v —— 也就是 verbose,在 b 选项的级别之上。输出的信息包括哪个 makefile 被解析,不需要被重编译的依赖文件(或是依赖目标)等。
    i —— 也就是 implicit,输出所以的隐含规则。
    j —— 也就是 jobs,输出执行规则中命令的详细信息,如命令的 PID、返回码等。
    m —— 也就是 makefile,输出 make 读取 makefile,更新 makefile,执行makefile 的信息
  14.  
  15. “-d”相当于“--debug=a
  16. “-e
    “--environment-overrides”指明环境变量的值覆盖 makefile 中定义的变量的值。
  17.  
  18. “-f=<file>”
    “--file=<file>”
    “--makefile=<file>” 指定需要执行的 makefile
  19.  
  20. “-h
    “--help
    显示帮助信息

  21. “-i
    “--ignore-errors
  22. 在执行时忽略所有的错误
  23.  
  24. “-I <dir>
    “--include-dir=<dir>”
    指定一个被包含 makefile 的搜索目标。可以使用多个“-I”参数来指定多个目录。

  25. “-j [<jobsnum>]”
    “--jobs[=<jobsnum>]” 指同时运行命令的个数。如果没有这个参数, make 运行命令时能运行多少就运行多少。如果有一个以上的“-j”参数,那么仅最后一个“-j”才是有效的。(注意这个参数在 MS-DOS中是无用的)
  26.  
  27. “-k
    “--keep-going
    出错也不停止运行。如果生成一个目标失败了,那么依赖于其上的目标就不会被执行了。

  28. “-l <load>
    “--load-average[=<load]”
    “—max-load[=<load>]”
    指定 make 运行命令的负载。

  29. “-n
    “--just-print
    “--dry-run
    “--recon
    仅输出执行过程中的命令序列,但并不执行。
  30.  
  31. “-o <file>
    “--old-file=<file>”
    “--assume-old=<file>”
    不重新生成的指定的<file>,即使这个目标的依赖文件新于它

  32. “-p
    “--print-data-base
    输出makefile 中的所有数据,包括所有的规则和变量。这个参数会让一个简单的makefile都会输出一堆信息。如果你只是想输出信息而不想执行 makefile,你可以使用“make -qp”命令。如果你想查看执行 makefile 前的预设变量和规则,你可以使用“make p f/dev/null”。
    这个参数输出的信息会包含着你的 makefile 文件的文件名和行号,所以,用这个参数来调试你的 makefile 会是很有用的,特别是当你的环境变量很复杂的时候。

  33. “-q
    “--question
    不运行命令,也不输出。仅仅是检查所指定的目标是否需要更新。如果是 0 则说明要更新,如果是 2 则说明有错误发生。
  34.  
  35. “-r
    “--no-builtin-rules
    禁止 make 使用任何隐含规则

  36. “-R
    “--no-builtin-variabes
    禁止 make 使用任何作用于变量上的隐含规则。

  37. “-s
    “--silent
    “--quiet
    在命令运行时不输出命令的输出。

  38. “-S
    “--no-keep-going
    “--stop
    取消“-k”选项的作用。因为有些时候, make 的选项是从环境变量“MAKEFLAGS”中继承下来的。所以你可以在命令行中使用这个参数来让环境变量中的“-k”选项失效。
  39.  
  40. “-t
    “--touch
    相当于 UNIX touch 命令,只是把目标的修改日期变成最新的,也就是阻止生成目标的命令运行

  41. “-v
    “--version
    输出 make 程序的版本、版权等关于 make 的信息。

  42. “-w
    “--print-directory
    输出运行 makefile 之前和之后的信息。这个参数对于跟踪嵌套式调用 make 时很有用。

  43. “--no-print-directory
    禁止“-w”选项。

  44. “-W <file>
    “--what-if=<file>”
    “--new-file=<file>”
    “--assume-file=<file>”
    假定目标<file>需要更新,如果和“-n”选项使用,那么这个参数会输出该目标更新时的运行动作。如果没有“-n”那么就像运行 UNIX 的“touch”命令一样,使得<file>的修改时间为当前时间。
  45.  
  46. “--warn-undefined-variables
    只要 make 发现有未定义的变量,那么就输出警告信息。

跟我学Makefile(六)的更多相关文章

  1. Mina、Netty、Twisted一起学(六):session

    开发过Web应用的同学应该都会使用session.由于HTTP协议本身是无状态的,所以一个客户端多次访问这个web应用的多个页面,服务器无法判断多次访问的客户端是否是同一个客户端.有了session就 ...

  2. 从头开始学JavaScript (六)——语句

    原文:从头开始学JavaScript (六)--语句 一.条件分支语句:if 基本格式: if (<表达式1>){    <语句组1>}else if (<表达式2> ...

  3. 跟我学Makefile(三)

    紧接着跟我学Makefile(二)继续学习:变量高级用法 (1)变量值的替换 :替换变量中的共有的部分,其格式是“$(var:a=b)”或是“${var:a=b}”,把变量“var”中所有以“a”字串 ...

  4. 一起学Makefile(六)

    命令的回显: 通常,make在执行命令之前都会把执行的命令进行输出,例如: 关闭命令回显有以下几种方式: 每个需要关闭回显的命令行之前加上”@”符号: 执行make时机上参数-s 或 –slient进 ...

  5. 一起学makefile

    Unix.Linux必学知识哈哈,网上看到一哥们写得挺好挺详细的,直接复制地址就分享哈哈哈. 跟我一起写 Makefile(一) 概述 跟我一起写 Makefile(二) make是如何工作的 跟我一 ...

  6. 跟我一起学Makefile

    概述 什么是makefile?或许很多Winodws程序员都不知道这个东西,因为那些Windows IDE都为你做了这个工作,但我觉得要做一个好的和professional的程序员,makefile还 ...

  7. 【MySQL函数】MySQL 5.5从零开始学第六章

    说明:本文总结自:<MySQL 5.5从零开始学>第六章 MySQL中的函数包括: 数学函数.字符串函数.日期和时间函数.条件判断函数.系统信息函数和加密函数等. 函数: 表示对输入参数值 ...

  8. 跟我一起写Makefile(六)

    使用条件判断—————— 使用条件判断,可以让make根据运行时的不同情况选择不同的执行分支.条件表达式可以是比较变量的值,或是比较变量和常量的值. 一.示例 下面的例子,判断$(CC)变量是否“gc ...

  9. 跟我学Makefile(七)

    定义模式规则 使用模式规则来定义一个隐含规则.一个模式规则就好像一个一般的规则,只是在规则中,目标的定义需要有“%”字符.“%”的意思是表示一个或多个任意字符.在依赖目标中同样可以使用“%”,只是依赖 ...

随机推荐

  1. 【转】理清基本的git(github)流程

    概述 当我初次接触git时,我需要快速学习基本的git工作流,以便快速接收一个开源Web项目维护.但是,我很难理解工作流程,因为我不太了解git使用关键点. fork,clone,pull.branc ...

  2. Makefile--隐含规则自动推dao(一)

    [版权声明:转载请保留出处:周学伟:http://www.cnblogs.com/zxouxuewei/] 上一节的Makefile勉强可用,但还写的比较繁琐,不够简洁.对每一个.c源文件,都需要写一 ...

  3. Effective C++ Item 17 Store newed objects in smart pointer in standalone statements

    If you trying to do multiple things in one statement, you should think carefully abnormal behavior e ...

  4. 数据库中存储js代码无法json解析

    .net-------------------Microsoft.JScript.GlobalObject.escape(); 编码 Mircorsoft.JScript.GlobalObject.u ...

  5. 如何让IOS中的文本实现3D效果

    本转载至 http://bbs.aliyun.com/read/181991.html?spm=5176.7114037.1996646101.25.p0So7c&pos=9       zh ...

  6. 64位ubuntu下用code::blocks IDE配置opengl开发环境

    http://jingyan.baidu.com/article/c74d60007d104f0f6b595d6d.html 样例程序: #include <GL/glut.h> #inc ...

  7. Mybatis头文件

    <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-/ ...

  8. 【PHP】 解决报错:Error: php71w-common conflicts with php-common-5.4.16-43.el7_4.x86_64

    背景: 手动安装的PHP7 环境 问题:在安装扩展的时候.无论输入 php-*  来安装任何扩展.都会报错 Error: php71w-common conflicts with php-common ...

  9. BNU4208:Bubble sort

    冒泡排序(BubbleSort)的基本概念是:依次比较相邻的两个数,将小数放在前面,大数放在后面.即首先比较第1个和第2个数,将小数放前,大数放后.然后比较第2个数和第3个数,将小数放前,大数放后,如 ...

  10. SenchaTouch 的一些问题记录

    1 : textfield 的 focus事件在手机上会被触发很多次,原因不明,在pc上测试无问题