1. #”后面是注释;
  2. \”是换行符;(如果想要使用\,需要写成\\才可以)

makefile的规则:

  1. target ... : prerequisites ...
  2. [tab键]command # 注意,一定要以一个tab键作为开头
  3. ...
  4. ...
  5. #或者
  6. targets : prerequisites ; command
  7. ...

变量

在Makefile中的定义的变量,就像是C/C++语言中的宏一样,他代表了一个文本字串,在Makefile中执行的时候其会自动原模原样地展开在所使用的地方。其与C/C++所不同的是,你可以在Makefile中改变其值。在Makefile中,变量可以使用在“目标”,“依赖目标”, “命令”或是Makefile的其它部分中。

变量名字

  • 可以包含:字符、数字,下划线(可以是数字开头);
  • 不应包含::#= 或是空字符(空格、回车等);
  • 变量大小写敏感:如“foo”、“Foo”和“FOO”是三个不同的变量名;

变量中比较特殊的一类是:自动化变量。(见下文)

变量声明与使用

  • 声明时:需要给予初值;
  • 使用时:需要给在变量名前加上 $ 符号,但最好用小括号 () 或是大括号 {} 把变量给包括起来。

    如果你要使用真实的 $ 字符,那么你需要用 $$ 来表示。

例子

变量的声明,可以使用:

  • =(最基本的赋值)
  • +=(追加变量)
  • :=(表示变量的值决定于它在makefile中的位置,而不是整个makefile展开后的最终值。)
  • ?=(表示如果该变量没有被复制,则赋予等号后的值;如果先前被赋值,则该语句什么也不做)

例子:

  1. # 1️⃣“=”将整个makefile展开后,再决定变量的值。也就是说,变量的值将会是整个makefile中最后被指定的值。看例子:
  2. x = foo
  3. y = $(x) bar
  4. x = xyz
  5. # 在上例中,y的值将会是 xyz bar ,而不是 foo bar 。
  6. # 2️⃣ += 操作符给变量追加值,如:
  7. objects = main.o foo.o bar.o utils.o
  8. objects += another.o
  9. # 于是,我们的 $(objects) 值变成:“main.o foo.o bar.o utils.o another.o”(another.o被追加进去了)
  10. # 使用 += 操作符,可以模拟为下面的这种例子:
  11. objects = main.o foo.o bar.o utils.o
  12. objects := $(objects) another.o
  13. # 所不同的是,用 += 更为简洁。
  14. # 3️⃣相比于前面“最普通”的”=”,”:=”就容易理解多了。”:=”就表示直接赋值,赋予当前位置的值。同样举个例子说明:
  15. VIR_A := A
  16. VIR_B := $(VIR_A) B
  17. VIR_A := AA
  18. # 最后变量VIR_B的值是A B,即根据当前位置进行赋值。因此相比于”=”,”:=”才是真正意义上的直接赋值。

变量中的变量

在定义变量的值时,我们可以使用其它变量来构造变量的值,在Makefile中有两种方式来在用变量定义变量的值。

  1. 使用 = 号,在 = 左侧是变量,右侧是变量的值,右侧变量的值可以定义在文件的任何一处,也就是说,右侧中的变量不一定非要是已定义好的值,其也可以使用后面定义的值。如: ```shell foo = $(bar) bar = $(ugh) ugh = Huh?

all: echo $(foo)

  1. 我们执行“make all”将会打出变量 `$(foo)` 的值是 `Huh?` `$(foo)` 的值是 `$(bar)` `$(bar)` 的值是 `$(ugh)` `$(ugh)` 的值是 `Huh?` )可见,变量是可以使用后面的变量来定义的。
  2. <a name="9BeaW"></a>
  3. ## [变量高级用法](https://seisman.github.io/how-to-write-makefile/variables.html#id4)
  4. 第一种是变量值的替换。<br />另外一种变量替换的技术是以“静态模式”(参见前面章节)定义的。
  5. 第二种高级用法是——“把变量的值再当成变量”。
  6. <a name="tf40V"></a>
  7. # 使用隐含规则
  8. 使用隐含规则生成你需要的目标,你所需要做的就是不要写出这个目标的规则。
  9. make会试图去自动推导产生这个目标的规则和命令,如果 make可以自动推导生成这个目标的规则和命令,那么这个行为就是隐含规则的自动推导。
  10. 当然,隐含规则是make事先约定好的一些东西。如:
  11. ```shell
  12. # 这个Makefile中并没有写下如何生成 foo.o 和 bar.o 这两目标的规则和命令。因为make的“隐含规则”功能会自动为我们自动去推导这两个目标的依赖目标和生成命令。
  13. foo : foo.o bar.o
  14. cc –o foo foo.o bar.o $(CFLAGS) $(LDFLAGS)

make会在自己的“隐含规则”库中寻找可以用的规则,如果找到,那么就会使用。如果找不到,那么就会报错

隐含规则一览

预先设置(也就是make内建)的隐含规则,如果我们不明确地写下规则,那么,make就会在这些规则中寻找所需要规则和命令。

如果想取消使用所有的make内建的隐含规则,可以使用make参数的-r--no-builtin-rules 选项来取消所有的预设置的隐含规则

注意:即使是我们指定了 -r 参数,某些隐含规则还是会生效
因为有许多的隐含规则都是使用了“后缀规则”来定义的。所以,只要隐含规则中有 “后缀列表”(也就一系统定义在目标 .SUFFIXES 的依赖目标),那么隐含规则就会生效。默认的后缀列表是:.out, .a, .ln, .o, .c, .cc, .C, .p, .f, .F, .r, .y, .l, .s, .S, .mod, .sym, .def, .h, .info, .dvi, .tex, .texinfo, .texi, .txinfo, .w, .ch .web, .sh, .elc, .el。

常用的隐含规则


``