Makefile:与子目录相同名称的规则被忽略。

6
这是我的makefile文件:
all: first second

second:
    @echo "==Building second=="

first:
    @echo "==Building first=="

如果存在名为second的目录,则与之相同名称的规则将完全被makefile忽略。如果没有,则一切照常进行。
请注意,无论second文件夹中是否有Makefile,在此情况下均会发生这种情况。
当我组织项目时,遇到了这个问题:我想创建一个通用的Makefile,然后调用每个目录中的Makefile..所以对我来说,规则与文件夹具有相同的名称似乎很自然。
解决方案很简单:更改Makefile内的规则名称...但是这种行为似乎相当奇怪:您有任何想法/见解吗?是否有其他可能的解决方案?
我正在使用GNU Make 3.81,在Ubuntu 12.04.2 LTS下的Bash 4.2.25中。

你希望second规则从second/目录中调用second/Makefile,是这样吗? - Beta
3个回答

9
如果你只是想知道规则为什么没有运行,那很简单:make试图构建目标。目标通常由文件系统中的存在的构件来表示(默认情况下)。无论构件是文件还是目录(或者在理论上,任何其他东西),这对于make来说都没有关系。
为了使make认为一个文件已经过时并需要更新(因此,为了使make运行与目标相关联的配方),至少必须满足以下两个条件之一:要么目标(即文件或目录)不存在,或者如果它存在,则其最后修改时间必须早于其前提条件之一。
在你的情况下,你有"second",它存在,所以重建的第一个要求不满足,它没有前提条件,所以第二个要求也不满足......因此目标被认为不过时,配方也不会被调用。
正如bobbogo所建议的那样,你可以告诉make始终重新构建目标,而不考虑其他任何事情,方法是将目标声明为".PHONY"。 make会明白目标不代表文件系统中的构件,而只是makefile中用于组织构建的虚假目标。

2

看起来你希望第二条规则始终运行,无论文件(或目录)“second”是否已存在。你可以通过将其声明为.PHONY的先决条件来使第二个成为这种符号目标。

.PHONY: all
all: first second

.PHONY: second
second:
    @echo "==Building second=="
...

0

如果我理解你的问题陈述正确,你没有调用echo,而是$(MAKE) -Csecond。是时候阅读Miller的递归式Make被认为是有害的了!虽然这些不是传统make的固有问题,但要用它们做得更好会很困难和笨拙。

出于这个原因,makepp被创建了。你可以拥有大致相同的makefile,但你不需要指定递归。如果你的目标目录有makefile,它们通常会自动加载到同一个进程中。或者如果你的目标生成到另一个目录,你必须告诉makepp要加载哪些makefile。无论哪种方式,一个进程都可以概览所有(自动检测到的!)依赖项。

makepp还有更多功能。除了几乎可以做到GNU make的所有事情外,还有很多有用的东西,你甚至可以用一些Perl编程扩展你的makefile。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接