2017-10-18 70 views
0

我正在使用macOS的默认内置版本(如果它有任何区别)。我试图制作一个makefile来管理单独目录中的超小型项目,这些目录由其中包含makefile的另一个目录包含。所以,与其写出关于每个项目的信息 - 这需要永远 - 我已经遵循模式规则。但是,无论何时在目标依赖关系中存在一个目录,它都会变得疯狂,并说“无法完成目标”或“目标是最新的”。例如:模式规则和目录

%: %.c 
    gcc -o [email protected] $< 

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

%: %/%.c 
    gcc -o [email protected] $< 

“目标是最新的”,无论我做什么。我试过让它.PHONY,并没有结果。我甚至试着这样做:

define FUNC 
$1: $1/$1.c 
    gcc -o $1 $1.c 
endef 
%: 
    $(call FUNC,[email protected]) 

再次,没有什么变化,即使我让它再次.PHONY。 (不像.PHONY: %,当然,像.PHONY: a,然后我试着做make a)为什么第二个例子没有工作?有没有解决方法?

回答

1

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

但是,这不会帮助你在这里。首先,每个目标或模式的先决条件只能有一个%。第二个和后续的不会被替换,所以像%/%.c这样的先决条件是不合法的。

对于第二次尝试,这没有任何意义。您不能在配方中定义make规则:配方会传递到shell以执行,因此它们是shell语法,而不是makefile语法。

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

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

在这里,我们创建具有相同名称的可执行foo作为目录foo已经存在(大概)。即使你直接从shell运行gcc,它也会因此而失败,甚至不考虑make。

这就是make说“无事可做”的原因:那个目标foo已经存在(它是一个目录),并且make找不到规则来更新它(因为foo/%.c不存在,所以模式规则不会)不适用)。由于它存在并且没有更新它的规则,所以没有什么可以做的。

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