tartarus's bolg tartarus's bolg
  • Linux and Unix Guide
  • CMake
  • gcc
  • gdb
  • bash
  • GNU Make
  • DDCA-ETH
  • CS106L
  • CS144
  • NJU PA
  • NJU OS(jyy)
  • C
  • C++
  • Python
  • reveal-md
  • LaTex
  • Paper Reading
  • TBD
  • Linux and Unix Guide
  • CMake
  • gcc
  • gdb
  • bash
  • GNU Make
  • DDCA-ETH
  • CS106L
  • CS144
  • NJU PA
  • NJU OS(jyy)
  • C
  • C++
  • Python
  • reveal-md
  • LaTex
  • Paper Reading
  • TBD
  • pdb

  • make

    • 1.0 声明😁
    • 2.0 makefile介绍
    • 3.0 书写makefile
    • 3.0 书写规则
    • 4.0 书写命令
    • 5.0 使用变量
    • 6.0 使用条件判断
    • 7.0 使用函数
    • 8.0 make的运行
      • make的退出码
      • 定义模式规则
      • 模式规则示例
      • 自动化变量:
      • MAKECMDGOALS
  • cmake

  • Linux and Unix

  • Basic_Software
  • make
tartarus
2023-09-02
目录

8.0 make的运行

# make 的运行

# make 的退出码

make 命令执行后有三个退出码:
0 : 表示成功执行
1 : 如果 make 运行时出现任何错误,其返回 1
2 : 如果你使用了 make 的 “-q” 选项,并且 make 使得一些目标不需要更新,那么返回 2。

# 指定 Makefile

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

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

make –f hchen.mk
1

如果在 make 的命令行中不只一次地使用了 -f 参数,那么,所有指定的 makefile 将会被连在一起传递给 make 执行。

# 定义模式规则

模式规则中,至少在规则的目标定义中要包含 % ,否则,就是一般的规则。目标中的 % 定义表示对文件名的匹配,** % 表示长度任意的非空字符串。** 例如: %.c 表示以 .c 结尾的文件名(文件名的长度至少为 3),而 s.%.c 则表示以 s. 开头, .c 结尾的文件名(文件名的长度至少为 5)。

如果 % 定义在目标中,那么,依赖中的 % 的值决定了目标中的 % 的值,也就是说,依赖中的模式的 % 决定了目标中 % 的样子。例如有一个模式规则如下:

%.o : %.c ; <command ......>;
1

其含义是,指出了怎么从所有的 .c 文件生成相应的 .o 文件的规则。如果存在文件 a.c b.c ,那么要生成的目标就是 a.o b.o .

一旦依赖目标中的 % 模式被确定,那么,make 会被要求去匹配当前目录下所有的文件名,一旦找到,make 就会规则下的命令,所以,在模式规则中,目标可能会是多个的,如果有模式匹配出多个目标,make 就会产生所有的模式目标,此时,make 关心的是依赖的文件名和生成目标的命令这两件事。

# 模式规则示例

下面这个例子表示了,把所有的 .c 文件都编译成 .o 文件.

%.o : %.c
    $(CC) -c $(CFLAGS) $(CPPFLAGS) $< -o $@
1
2

其中, $@ 表示所有的目标的挨个值, $< 表示了所有依赖目标的挨个值。这些奇怪的变量我们叫 “自动化变量”,后面会详细讲述。

# 自动化变量:

自动化变量 ** 把模式中所定义的一系列的文件自动地挨个取出,直至所有的符合模式的文件都取完了。** 这种自动化变量只应出现在规则的命令中。
下面是所有的自动化变量及其说明:

  • $@ : 表示规则中的目标文件集。在模式规则中,如果有多个目标,那么, $@ 就是匹配于目标中模式定义的集合。
  • $% : ** 仅当目标是函数库文件中,表示规则中的目标成员名。** 例如,如果一个目标是 foo.a(bar.o) ,那么, $% 就是 bar.o , $@ 就是 foo.a 。如果目标不是函数库文件(Unix 下是 .a ,Windows 下是 .lib ),那么,其值为空。
  • $< : ** 依赖目标中的第一个目标名字。** 如果依赖目标是以模式(即 % )定义的,那么 $< 将是符合模式的一系列的文件集。注意,其是一个一个取出来的。

$? : ** 所有比目标新的依赖目标的集合。** 以空格分隔。
$^ : ** 所有去重的依赖目标的集合。** 以空格分隔。如果在依赖目标中有多个重复的,那么这个变量会去除重复的依赖目标,只保留一份。
$+ : 不去除重复的依赖目标的集合。和 $^ 很像。

$* : ** 这个变量表示目标模式中 % 及其之前的部分。** 如果目标是 dir/a.foo.b ,并且目标的模式是 a.%.b ,那么, $* 的值就是 dir/foo 。这个变量对于构造有关联的文件名是比较有效。

  • 如果目标中没有模式的定义,那么 $* 也就不能被推导出
  • 如果目标文件的后缀是 make 所识别的,那么 $* 就是除了后缀的那一部分。例如:如果目标是 foo.c ,因为 .c 是 make 所能识别的后缀名,所以, $* 的值就是 foo 。
    (这个特性是 GNU make 的,很有可能不兼容于其它版本的 make,所以,你应该尽量避免使用 $*,除非是在隐含规则或是静态模式中。如果目标中的后缀是 make 所不能识别的,那么 $* 就是空值。)

# MAKECMDGOALS

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

sources = foo.c bar.c
ifneq ( $(MAKECMDGOALS),clean)
    include $(sources:.c=.d)
endif
1
2
3
4

基于上面的这个例子,只要我们输入的命令不是 “make clean”,那么 makefile 会自动包含 “foo.d” 和 “bar.d” 这两个 makefile。

上次更新: 12/27/2023, 8:55:47 AM
7.0 使用函数
Introduction

← 7.0 使用函数 Introduction→

Theme by Vdoing | Copyright © 2023-2023 tartarus | CC BY-NC-SA 4.0
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式