模式规则和目录

时间:2017-10-18 16:34:54

标签: makefile

我正在使用macOS默认内置版本的make(如果它有任何区别)。我正在尝试创建一个makefile来管理单独目录中的超小项目,这些目录由另一个目录包含makefile。所以,不是写关于每个项目的信息 - 这将永远需要 - 我已经采用了模式规则。但是每当目标依赖项中有一个目录时,它就会变得疯狂,说“没有任何目标要做”或“目标是最新的”。例如:

%: %.c
    gcc -o $@ $<

工作得很好。但是,如果我这样做:

%: %/%.c
    gcc -o $@ $<

“目标是最新的”,无论我做什么。我已经尝试过.PHONY,但没有结果。我甚至试过这样做:

define FUNC
$1: $1/$1.c
    gcc -o $1 $1.c
endef
%:
    $(call FUNC,$@)

而且,即使我再次.PHONY,也没有任何变化。 (当然,不像.PHONY: %,类似于.PHONY: a,然后我尝试make a)为什么第二个例子不起作用?它有解决方法吗?

1 个答案:

答案 0 :(得分:1)

首先请注意,由于Apple非常害怕GPLv3软件,因此MacOS附带的GNU make版本已经很老了。不仅如此,我还看到有关他们已经应用于他们的版本的补丁破坏了它的报道。我建议您使用Homebrew或MacPorts(或者自己从源代码构建它)以获得更现代的,受支持的GNU make版本。

然而,这对你没有帮助。首先,在模式的每个目标或先决条件中只能有一个%。第二个及后续的不会被替换,因此像%/%.c这样的先决条件是不合法的。

对于你的第二次尝试,这没有任何意义。您无法在配方中定义生成规则:将配方传递给shell以执行,因此它们是shell语法,而不是makefile语法。

但除此之外,你的规则从根本上是有问题的。考虑一下如果你要写一个明确的规则会是什么样子:

foo: foo/foo.c
        gcc -o foo foo/foo.c

在这里,您要创建一个与已存在的目录foo同名的可执行文件foo(大概)。即使您直接从shell运行gcc,也会因此而失败,甚至不考虑make。

make的原因是&#34;无事可做&#34;:目标foo已经存在(它是一个目录)并且make无法找到规则更新它(因为foo/%.c不存在因此模式规则不适用)。由于它存在并且没有更新它的规则,因此没有什么可以做的。

所以你需要重新考虑你想要在这里完成什么。