Makefile %和*一起放在依赖项行上

Makefile %和*一起放在依赖项行上,makefile,gnu-make,Makefile,Gnu Make,很长时间以来,我一直在使用这种奇怪的规则,但突然之间,它们在一个新的环境中被打破了 有没有一种可靠的方法可以做到这一点 all: test.1.out test.%.out: %/test*.out /bin/cp -f $< $@ 其他人的Mac电脑、ubuntu机器、ubuntu虚拟机上的这种代码没有问题。我不知道他们所有的make版本,但似乎代码还可以 在我的mageia服务器上,在清除后位于同一目录中 [dushoff@yushan make_insanity]$ ma

很长时间以来,我一直在使用这种奇怪的规则,但突然之间,它们在一个新的环境中被打破了

有没有一种可靠的方法可以做到这一点

all: test.1.out

test.%.out: %/test*.out
    /bin/cp -f $< $@
其他人的Mac电脑、ubuntu机器、ubuntu虚拟机上的这种代码没有问题。我不知道他们所有的make版本,但似乎代码还可以

在我的mageia服务器上,在清除后位于同一目录中

[dushoff@yushan make_insanity]$ make --version
GNU Make 3.82
Built for x86_64-mageia-linux-gnu
Copyright (C) 2010  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.
[dushoff@yushan make_insanity]$ make
make: *** No rule to make target `test.1.out', needed by `all'.  Stop.
[dushoff@yushan make_insanity]$ 
[dushoff@yushan使疯狂]$make--版本
GNU Make 3.82
为x86_64-mageia-linux-gnu构建
版权所有(C)2010免费软件基金会。
许可证GPLv3+:GNU GPL版本3或更高版本
这是自由软件:您可以自由更改和重新发布它。
在法律允许的范围内,不存在任何担保。
[dushoff@yushan制造疯狂]$make
make:**没有规则使目标'test.1.out'为'all'所需。停止
[dushoff@yushan使精神错乱]$

%
*
更改为适当的文本“修复”了问题,但当然不会产生所需的通用性。

我不是绝对确定,但我认为您需要

test.<name>.out
可以使用和通配符函数执行此操作。请注意,如果没有这个,它永远都是无效的,所以您看到的任何代码都应该被视为已被破坏

.SECONDEXPANSION:

all: test.1.out

test.%.out: $$(wildcard $$*/test*.out)
    @echo Prerequisites found: $^
请注意,模式匹配(请参阅)中使用的是
$*
而不是
%
,这是由一个额外的
$
转义的,整个过程设置为展开两次,因此两组值都会展开


也就是说,整个布局看起来是错误的。您使用的是
$有人向我建议,可能是将make 3.81更改为3.82。我查看了发行说明,但没有发现任何适用的内容。谢谢这对于学习make的酷东西很有用,但我可以使用原始规则而不使用*。此外,在这个特定的应用程序中,规则的可读性也很重要。这个简单的规则在各种平台上运行了一段时间。如果我能用一些简单的东西来保存它就好了。谢谢。这就是我想要的。我确实理解你们两人对结构的看法。这个特定的用例涉及到人们实时提供名称稍有不一致的文件,因此我被糟糕的结构困住了(当然我本可以尝试修复make的上游,但我通常认为make优先于一切)。我本来应该这么说的。
<name>/test.out
targs := test.1.out test.a.out

define src_of =
$(patsubst .%,%,$(suffix $(basename $(1))))/$(basename $(basename $(1)))$(suffix $(1))
endef

all: $(targs)

test.%.out: $(call src_of,test.%.out)
    cp -f $< $@

clean:
    rm -f *.*.out
$ ls -LR
.:
1  a  Makefile

./1:
test.out

./a:
test.out
$ make
cp -f 1/test.out test.1.out
cp -f a/test.out test.a.out
.SECONDEXPANSION:

all: test.1.out

test.%.out: $$(wildcard $$*/test*.out)
    @echo Prerequisites found: $^