【问题标题】:Let make fail, if Makefile encounters undefined variable让 make 失败,如果 Makefile 遇到未定义的变量
【发布时间】:2023-02-18 03:23:54
【问题描述】:

我的 Makefile 有一个错误:

verify-prettier:
    $(PRETTIER) --check **/*.yaml **/*.yml

未设置 PRETTIER 变量。

结果:

check **/*.yaml **/*.yml
bash: line 1: check: command not found
make: [Makefile:156: verify-prettier] Error 127 (ignored)

如果我不小心有一个未定义的变量,我想得到一个错误(不会被忽略)。

有没有办法相应地配置make?

版本:GNU Make 4.3

我们不需要支持其他 make 实现。

我知道这一点,但我希望它失败,而不仅仅是警告。

MAKEFLAGS=--warn-undefined-variables

更新,因为这似乎到现在为止还不可用,所以我创建了一个功能请求:https://savannah.gnu.org/bugs/?63737

【问题讨论】:

  • GNU make 中没有选项会在引用空变量时生成致命错误。只有 --warn-undefined-variables 会产生警告,但不会产生错误,它只会在不明确的变量,不空的变量(这些不是一回事)。
  • @MadScientist 感谢您的评论。我现在让我的问题更精确了。
  • 只是另一个顺序:GNU make 调用sh(有些系统,比如 Red Hat,会将 sh 链接到 bash,但其他系统不会); shbash(默认情况下)都不会扩展像** 这样的高级通配符。对于 shell,这与 * 相同。很可能你的**/*.yml 并没有按照你的想法行事。
  • 我在之前的评论中提到了这一点。 globbing 在 POSIX 中的工作方式是 shell 将尝试扩展 globbing。如果它匹配某些东西,那么那个东西就会被传递给命令。如果它不匹配任何内容,则将 glob 传递给命令。因此,如果您运行 echo **/*.yml 并且目录中有一个与 */*.yml 匹配的文件,则该文件将被传递。如果没有匹配*/*.yml 的文件,则将传递字符串**/*.yml。构建系统依赖于存在或不存在的文件是危险的,因此如果您希望传递 glob,则应该引用它。
  • 另外,通过引用它,每个阅读您的命令的人都会理解您正在尝试做什么(将 globbing 字符传递给命令)。否则他们会对为什么你的构建系统中没有 .yml 文件感到困惑。

标签: makefile gnu-make


【解决方案1】:

正如 cmets 中所说,从当前 (4.3) GNU Make 版本开始就没有办法了。并且任何添加都可能需要永远才能到达公众(WSL 仍然停留在 4.2.1!!!)。

我可以想到一些可能会根据情况起作用的拐杖:

  • 传递--warn-undefined-variables进行制作,然后将输出通过管道传输到例如grep 测试警告消息的缺失。适用于命令行长度和复杂性无关紧要的构建自动化,更不用说交互式使用。
  • 在 makefile 的末尾有 ifndeferror 块。每个变量都需要一个特定的块,但这与单元测试的工作方式相差不远,而且这些单元测试通常被接受:-)
  • 默认初始化会失败。在 $(PRETTIER) 的情况下,您可以将其初始化为 false,默默地吃掉任何参数并返回失败。可行性取决于变量的使用方式。对于用作命令的变量效果很好,对于参数可能会更棘手,但我确信一些 hack 应该起作用(因为它有多难故意地编写崩溃代码)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-10-13
    • 1970-01-01
    • 1970-01-01
    • 2022-08-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多