【问题标题】:Do Curly Brace Wildcards work in GNU Make 4 (or even POSIX Make)?花括号通配符在 GNU Make 4(甚至 POSIX Make)中有效吗?
【发布时间】:2019-05-07 21:08:02
【问题描述】:

我发现 GNU Make 4.1 和 3.81 之间的行为有所不同,我想知道我的代码是否不符合 POSIX 标准,哪个 4 执行得更严格,或者是否发生了其他事情。

我将失败案例提炼到这个 Makefile

.POSIX:

all: test-b

test-a:
    cat a.txt b.txt c.txt >results.txt

test-b:
    cat {a,b,c}.txt >results.txt

假设这些文件是使用 cat {a,b,c}.txt 创建的,目标 test-a 始终有效,但 test-b 在 Make 3.81 上有效,但在 4.1 上失败。

3.81 的输出:

$ make --version
GNU Make 3.81
Copyright (C) 2006  Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.

This program built for i386-apple-darwin11.3.0
$ make
cat {a,b,c}.txt >results.txt
$ echo $?
0

4.1 的输出:

$ make --version
GNU Make 4.1
Built for x86_64-pc-linux-gnu
Copyright (C) 1988-2014 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
$ make
cat {a,b,c}.txt >results.txt
cat: {a,b,c}.txt: No such file or directory
Makefile:9: recipe for target 'test-b' failed
make: *** [test-b] Error 1
$ echo $?
2

cat 命令实际上可能在 3.81 中失败,只是没有指出这一点,因为更高版本的 GNU Make 提到在调用目标命令时将 -e 标志传递给 shell 以使其更 POSIX合规,但我看不出该命令如何失败。

我假设通配符仅由 shell 处理,所以我看不出通过 make target 命令调用 shell 应该有什么不同。

哪些行为是正确的?如果像这样的通配符在 Makefiles 中不起作用,我可以假设其他哪些通配符起作用?

即使 .POSIX: 从文件中删除,test-b 在 4.1 中仍然失败。

【问题讨论】:

    标签: unix makefile posix gnu-make


    【解决方案1】:

    配方被发送到外壳。它们不被 make 解释。所以你的问题是,shell 是否支持大括号扩展?

    这取决于使用哪个 shell。 POSIX 标准 sh 不支持它们。它们受到 bash(和许多其他 shell)的支持。

    Make 总是调用/bin/sh,不管你个人使用什么shell,除非你专门将make SHELL 变量设置为别的东西。在某些系统上,/bin/sh/bin/bash 的符号链接,因此它们是相同的(当以/bin/sh 调用时,bash 以“POSIX 仿真”模式运行,但大多数 bash 功能仍然可用)。其他系统使用不同的 shell,例如 dash,如 /bin/sh,它们没有额外的 bash 功能。

    因此,您可以 (a) 没有可移植的 makefile 并假设 /bin/sh/bin/bash 相同,(b) 在您的 makefile 中设置 SHELL := /bin/bash 以强制它始终使用 bash(但失败没有安装 bash 的系统),或 (c) 编写您的 makefile 配方以仅使用 POSIX sh 功能,因此无论 /bin/sh 使用哪个 shell,它都能正常工作。

    【讨论】:

      猜你喜欢
      • 2011-01-29
      • 2010-12-01
      • 2011-01-17
      • 1970-01-01
      • 1970-01-01
      • 2023-03-05
      • 1970-01-01
      • 2013-04-14
      • 1970-01-01
      相关资源
      最近更新 更多