0%

Makefile入门

make是一个根据指定的shell命令进行构建的工具,规则很简单,规定要构建哪个文件、它依赖哪些源文件,当那些文件有变动时,如何重新构建它。

一、Make

      make命令执行时需要一个makefile文件,以告诉make命令需要怎么样的去编译和链接程序。它是一个根据指定的Shell命令进行构建的工具,规则很简单,你规定要构建哪个文件、它依赖哪些源文件,当那些文件有变动时,如何重新构建它。

二、Makefile

  1. Makefile文件由一系列规则rules构成,每条规则就明确两件事:构建目标的前置条件是什么,以及如何构建。每条规则的形式如下
1
2
<target> : <prerequisites> 
[tab] <commands>
  • 目标target:一个目标target就构成一条规则,它通常是文件名(一个或多个,多个用空格分开),指明Make命令所要构建的对象目标是一/多个文件名。
    • target除了可以是文件名,还可以是某个操作的名字,这称为”伪目标”(phony target)。
  • 前置条件prerequisites:它通常是一组文件名,之间用空格分隔。
    • 前置条件指定了目标是否重新构建的判断标准:只要有一个前置文件不存在,或者有过更新(前置文件的last-modification时间戳比目标的时间戳新)目标就需要重新构建。
  • 制表键tab:每行命令之前必须有一个制表键tab
    • 如果想用其他键可以用内置变量.RECIPEPREFIX声明。
  • 命令commands:表示如何更新目标文件,由一行或多行的shell命令组成。它是构建目标的具体指令,它的运行结果通常就是生成目标文件。
    • 每行命令在一个单独的shell中执行,这些shell之间没有继承关系。若要一次性执行执行多行shell有三种方案:
      • 将多行shell写在一行,中间用逗号分隔
      • 在每行shell后加反斜杠\转义
      • 使用内置变量.ONESHELL
  1. Makefile语法
    • 注释:用#,跟shell脚本一样
    • 回声echoing:正常情况下make会打印每条命令,然后再执行,这就叫做回声。
      • 在命令的前面加上@可以关闭回声。
    • 通配符wildcard:用来指定一组符合条件的文件名。
      • Makefile的通配符与Bash一致,主要有*?[...],如*.o表示所有后缀名为o的文件。
    • 模式匹配:Make命令允许对文件名进行类似正则运算的匹配,主要用到的匹配符是%
      • 使用匹配符%可以将大量同类型的文件只用一条规则就完成构建。
    • 变量和赋值符:和大多数变成语言类似,使用等号=进行赋值给变量
      • 调用shell变量需要在美元符号前再加一个美元符号,如echo $$PATH
1
2
3
4
VARIABLE = value # 在执行时扩展,允许递归扩展
VARIABLE := value # 在定义时扩展
VARIABLE ?= value # 只有在该变量为空时才设置值
VARIABLE += value # 将值追加到变量的尾端
  • 内置变量Implicit Variables:Make命令提供一系列内置变量,比如$(CC)指向当前使用的编译器,$(MAKE)指向当前使用的Make工具。
  • 自动变量Automatic Variables:自动变量的值与当前规则有关,常用的如下:
    • $@指代当前目标,就是Make命令当前构建的目标。
    • $<指代第一个前置条件,如规则为t: p1 p2,那么$<就指代p1
    • $^指代所有前置条件,之间以空格分隔。
    • $+表示所有依赖文件的集合(不去重)。
    • $?指代比目标更新的所有前置条件,之间以空格分隔。
    • $*指代匹配符%匹配到的部分。
    • $(@D)$(@F)分别指向$@的目录名和文件名。
    • $(<D)$(<F)分别指向$<的目录名和文件名。
  • 判断和循环:Makefile使用Bash语法完成判断和循环。
  • 函数:Makefile还可以使用函数,格式为:$(function arguments)或${function arguments},一些常用的函数如下:
    • shell函数用来执行shell命令。
    • wildcard函数用来在Makefile中替换Bash的通配符。
    • subst函数用来文本替换。
    • patsubst函数用于模式匹配的替换。
    • strip函数用于去除头部和尾部的空格。
    • filter函数用于过滤特定模式的字符串。
    • word函数用于取单词。

三、参考

  1. 参考一
  2. 参考二