这是我的makefile:
all: first second
second:
@echo "==Building second=="
first:
@echo "==Building first=="
如果存在名为second
的目录,则makefile将完全忽略具有相同名称的规则。如果没有,一切正常。
请注意,无论second
文件夹是否为Makefile,都会发生这种情况。
我在组织项目时遇到了这个问题:我考虑创建一个通用的Makefile,然后在每个目录中调用Makefile ..所以对我来说,规则与文件夹的名称相同是很自然的。
解决方案很简单:更改Makefile中的规则名称...但这种行为似乎很奇怪:您对此有什么想法/见解,还有另一种可能的解决方案吗?
我在Ubuntu 12.04.2 LTS下使用Bash 4.2.25中的GNU Make 3.81。
答案 0 :(得分:5)
如果您只是查找未运行规则的原因,那很简单:尝试构建目标。目标(默认情况下)由文件系统中的工件的存在表示。无论工件是文件还是目录(或者理论上是其他任何东西)都无关紧要。
为了让make考虑一个过时且需要更新的文件(因此,对于make来运行与目标相关的配方),两件事中至少有一件必须是真的:要么是目标(即文件或目录)不能存在,或者如果存在,则其上次修改时间必须早于至少一个先决条件。
在你的情况下你有second
,这是存在的,所以重建的第一个要求不是我,而且没有先决条件,所以不满足第二个要求......所以不考虑目标过时了,没有调用配方。
正如bobbogo建议的那样,你可以通过声明目标是.PHONY
来告诉make,应该始终重建目标,而不管其他什么。 Make会理解目标不代表文件系统中的工件,而只是用于组织构建的makefile中的假目标。
答案 1 :(得分:2)
似乎您希望second
规则始终运行,无论文件(或目录)“second”是否已存在。您可以通过将其声明为.PHONY
的先决条件来制作第二种此类符号目标。
.PHONY: all
all: first second
.PHONY: second
second:
@echo "==Building second=="
...
答案 2 :(得分:0)
如果我理解你的问题陈述,你不是在调用echo
,而是$(MAKE) -Csecond
。很高兴阅读米勒的Recursive Make Considered Harmful!虽然这些并不是传统制作的固有问题,但用它们做得更好会很难也很笨拙。
因此makepp已创建。您可以拥有大约相同的makefile,但不需要指定递归。如果目标目录具有makefile,则它们通常会自动加载到同一进程中。或者,如果您的目标生成到另一个目录,您必须告诉makepp要加载哪个makefile。无论哪种方式,一个进程都具有所有(自动检测到的!)依赖关系的概述。
makepp还有很多。除了做几乎所有GNU make之外,还有更多有用的东西,你甚至可以通过一些Perl编程扩展你的makefile。