RISC-V Binutils工具链17之make命令的使用

Linux ELF 分析17之make工具的使用

在 C/C++ 等编译型语言的开发中,一个稍微复杂点的项目可能包含成百上千个源文件,如果每次修改了一行代码,你都要手动去敲几十条 gcc 命令来重新编译和链接,那绝对是一场灾难。

make 就是为了解决这个问题而生的,主要有如下三个作用:

  1. 自动化执行编译命令,需配合Makefile使用
  2. 增量编译
  3. 维护复杂的依赖关系

1 make 工具常用选项

$ make --help

输出log见:make_help

1.1 帮助与版本

选项 长选项 说明
-h --help 显示帮助信息并退出
-v --version 打印 make 版本信息并退出

1.2 目录与环境控制

选项 长选项 说明
-C DIRECTORY --directory=DIRECTORY 在执行前切换到指定目录,常用于子项目构建
-w --print-directory 每次进入目录时打印当前路径(常与 -C 配合)
--no-print-directory 禁用 -w,即使隐式启用也关闭

1.3 Makefile 输入控制

选项 长选项 说明
-f FILE --file=FILE, --makefile=FILE 指定使用的 Makefile 文件(可多次使用)
-I DIRECTORY --include-dir=DIRECTORY 添加包含目录,用于 include 指令查找 Makefile 片段
-E STRING --eval=STRING STRING 作为 Makefile 语句直接求值(类似内联定义)
-r --no-builtin-rules 禁用所有内置的隐式规则(如 .c.o:
-R --no-builtin-variables 禁用所有内置变量定义

1.4 目标构建行为控制

选项 长选项 说明
-B --always-make 无条件重新构建所有目标(忽略时间戳)
-n --just-print, --dry-run, --recon 只打印命令,不执行(模拟运行)
-s --silent, --quiet 不回显(不打印)执行的命令
--no-silent 启用命令回显(取消 --silent
-t --touch 不执行命令,而是 touch 目标文件(更新时间戳)
-q --question 不运行任何命令,仅通过退出码判断目标是否已是最新的(0=是,2=否)
-W FILE --what-if=FILE, --new-file=FILE, --assume-new=FILE 假设 FILE 是最新的
-o FILE --old-file=FILE, --assume-old=FILE 假设 FILE 是极旧的,且不重新生成它

1.5 并行与性能控制

选项 长选项 说明
-j [N] --jobs[=N] 允许同时运行 N 个作业(任务)
无参数时为无限并行
-l [N] --load-average[=N], --max-load[=N] 当系统负载 ≥ N 时,不再启动新 job
-O[TYPE] --output-sync[=TYPE] 同步并行 job 的输出,避免混杂
类型:target, line, recurse

使用make -j 还是make -j$(nproc)?

推荐使用 make -j$(nproc),而不是简单的 make -j,其区别如下:

对比项 make -j make -j$(nproc)
并行度 无限,make 会尽可能多地启动任务(无限制) 根据 CPU 核心数自动设置并行任务数
安全性 极低
效率 可能崩溃 最大化利用资源

1.6 错误与容错控制

选项 长选项 说明
-i --ignore-errors 忽略命令执行错误,继续构建
-k --keep-going 即使某些目标失败,也尽可能继续构建其他目标
-S --no-keep-going, --stop 取消 -k 行为,遇到失败立即停止

尽量多的构建:

比如某个工程有许多错误,默认是发现一处错误就停止构建,有时想尽量一次暴露所有错误,然后修正,可以使用如下命令:

$ make -k                  # 尽可能完成所有可构建目标,从而方便修复所有错误

1.7 调试与诊断选项

选项 长选项 说明
-d 打印大量调试信息(包括依赖关系、决策过程)
--debug[=FLAGS] 更细粒度的调试输出
常见标志:a(all), b(basic), m(makefile), v(verbose)
-p --print-data-base 打印 make 内部数据库(所有变量、规则、目标)
--trace 打印每个目标的构建原因和时间戳信息
--warn-undefined-variables 当引用未定义变量时发出警告

如何查看 Makefile 的 include build.mk 依赖?

如果某个系统的构建比较复杂,我们有时需要梳理Makefile,mk文件之间的关系,可以使用 make 命令本身提供的选项来查看其解析 Makefile 的过程:

方法1:make -d:会输出 make 执行过程中的所有调试信息,包括:

  1. 解析了哪些 Makefile。

  2. include 了哪些文件(成功或失败)。

  3. 变量的展开过程。

  4. 目标是否需要重建。

  5. 执行的命令。

方法2:make -p:打印出 make 读取的所有 Makefile 的内容(包括内置规则和你 include 的文件),以及所有的规则、变量和隐含规则。

构建过程与编译过程有不同的问题及定位问题的方法:

问题 工具 正确方法
查看 include build.mk 是否被处理 make 使用 make -dmake -p
查看编译器详细信息(头文件搜索路径等) riscv64-unknown-linux-gnu-gcc 使用 -v

2 典型使用场景

场景 推荐命令
查看会执行什么命令 make -n
不实际构建,检查是否最新 make -q
构建时显示目录切换 make -w
多核并行加速构建 make -j$(nproc)
忽略错误继续构建 make -k
调试 Makefile 逻辑 make -d 或 make --debug=m
查看所有变量和规则 make -p
强制重新构建所有 make -B
假设某文件已修改 make -W file.c
posted @ 2026-08-29 16:27  sureZ_ok  阅读(7)  评论(0)    收藏  举报