【发布时间】: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