2015-11-10 110 views
5

我一直在使用像这样的奇怪规则很长一段时间,但突然间他们打破了新的环境。%*和依赖关系线上的*

有没有一个强大的方法来做到这一点?

all: test.1.out 

test.%.out: %/test*.out 
    /bin/cp -f $< [email protected] 

在我的箱子(Ubuntu的):

alishan:~/Dropbox/make_insanity> 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 x86_64-pc-linux-gnu 
alishan:~/Dropbox/make_insanity> make 
/bin/cp -f 1/test.out test.1.out 

与这种对别人的Mac电脑代码,Ubuntu机器,Ubuntu的虚拟机没有问题。不知道他们的所有版本,但它似乎是OK代码。

清除后,在我的mageia服务器在同一目录。

[[email protected] 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. 
[[email protected] make_insanity]$ make 
make: *** No rule to make target `test.1.out', needed by `all'. Stop. 
[[email protected] make_insanity]$ 

更改%*到适当的文本“修复”的问题,但当然不会产生所期望的一般性。

+0

有人向我暗示,从3.81改为3.82是可能的罪魁祸首。我查看了发行说明,但没有发现任何似乎适用的内容。 https://lists.gnu.org/archive/html/make-alpha/2010-07/msg00025.html –

回答

1

我没有绝对的把握,但我想你想

test.<name>.out 

<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 $< [email protected] 

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 
+0

谢谢。这在学习关于make的很酷的东西方面很有用,但是我可以使用没有*的原始规则来完成。此外,在这个特定的应用程序中,规则的可读性也很重要。 这个简单的规则在各种平台上工作了一段时间。如果我可以用简单的方法保存它将会很好。 –

0

你可以做到这一点使用secondary expansion和通配符功能。注意,如果没有这个,它永远不会有效,所以无论你看到这个代码是什么都应该被认为是破坏的

.SECONDEXPANSION: 

all: test.1.out 

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

注意使用$*而非%的模式匹配(见automatic variables)是由一个额外的$逃跑了,整个事情被设置为扩大两次,两组值得到扩展。

这就是说这整个布局看起来不对。您正在使用$<,它只匹配先决条件的第一个单词,即使使用通配符,您可能会有很多这样的单词。 Mike's answer可能是一个更好的选择,因为重新组织Makefile实际上很健壮。

+0

谢谢。这就是我想要的。 我明白你们俩在说什么结构。 这个特殊的用例涉及到实时提供名称稍微不一致的文件的人,所以我被困在了糟糕的结构中(当然,我可能试图修复make的上游文件,但我通常认为首先为所有内容制作)。首先我应该这样说。 –