Unix 大括号通配符在GNU Make 4(甚至POSIX Make)中有效吗?

Unix 大括号通配符在GNU Make 4(甚至POSIX Make)中有效吗?,unix,makefile,posix,gnu-make,Unix,Makefile,Posix,Gnu Make,我发现GNU Make 4.1和3.81之间的行为有所不同,我想知道我的代码是否与POSIX不兼容,而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创建的,那么ta

我发现GNU Make 4.1和3.81之间的行为有所不同,我想知道我的代码是否与POSIX不兼容,而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
创建的,那么target
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
$make--version
GNU Make 4.1
为x86_64-pc-linux-gnu构建
版权所有(C)1988年至2014年自由软件基金会。
许可证GPLv3+:GNU GPL版本3或更高版本
这是自由软件:您可以自由更改和重新发布它。
在法律允许的范围内,不存在任何担保。
$make
cat{a,b,c}.txt>results.txt
cat:{a,b,c}.txt:没有这样的文件或目录
生成文件:9:目标“test-b”的配方失败
make:**[test-b]错误1
$echo$?
2.
在3.81中,
cat
命令可能实际上失败了,它只是没有指出,因为GNU的更高版本提到在调用目标命令时将
-e
标志传递给shell,以使其更符合POSIX,但我看不出该命令是如何失败的

我假设通配符完全由shell处理,所以我看不出通过make-target命令调用shell会有什么不同

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


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

配方被发送到shell。它们不是由make解释的。所以你的问题是,shell支持花括号扩展吗

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

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

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