我有以下递归makefile:
.PHONY: all clean
%.subdir:
$(MAKE) -C src $*
$(MAKE) -C dict $*
all: all.subdir
clean: clean.subdir
Run Code Online (Sandbox Code Playgroud)
它工作正常:
$ make all
make -C src all
make[1]: Entering directory `/or-1.3.6-fix/src'
make[1]: Nothing to be done for `all'.
make[1]: Leaving directory `/or-1.3.6-fix/src'
make -C dict all
make[1]: Entering directory `/or-1.3.6-fix/dict'
make[1]: Nothing to be done for `all'.
make[1]: Leaving directory `/or-1.3.6-fix/dict'
Run Code Online (Sandbox Code Playgroud)
但将%.subdir
规则定义为虚假更合乎逻辑:
.PHONY: all clean all.subdir clean.subdir
Run Code Online (Sandbox Code Playgroud)
现在让我停止工作:
$ make all
make: Nothing to be done for `all'.
$ make -d all
...
Updating goal targets....
Considering target file `all'.
File `all' does not exist.
Considering target file `all.subdir'.
File `all.subdir' does not exist.
Finished prerequisites of target file `all.subdir'.
Must remake target `all.subdir'.
Successfully remade target file `all.subdir'.
Finished prerequisites of target file `all'.
Must remake target `all'.
Successfully remade target file `all'.
make: Nothing to be done for `all'.
Run Code Online (Sandbox Code Playgroud)
有人可以解释我为什么(甚至更好地指出我制作文档)?
Bet*_*eta 25
你是对的,将子网规则定义为PHONY会更有意义.但Make不考虑PHONY目标的隐含规则,因此您必须重写该规则.我建议如下:
SUBDIR_TARGETS = all.subdir clean.subdir
.PHONY: all clean $(SUBDIR_TARGETS)
$(SUBDIR_TARGETS): %.subdir:
$(MAKE) -C src $*
$(MAKE) -C dict $*
all: all.subdir
clean: clean.subdir
Run Code Online (Sandbox Code Playgroud)
hum*_*ace 14
GNU使得声明为.PHONY
明确的所需目标已在其他答案中说明,这也为此提供了一些补救措施.
在这个额外的答案中,我想添加一个替代品,当我测试时结合了"虚假"行为,即每次无论是否存在同名文件(都被忽略),都会触发目标.替代方案如下:
.PHONY: phony_explicit
phony_explicit:
%.subdir: phony_explicit
$(MAKE) -C src $*
$(MAKE) -C dict $*
Run Code Online (Sandbox Code Playgroud)
它的工作前提是,虽然只有明确的目标可以设置为.PHONY,但是依赖于明确的伪目标的任何东西本身都会继承很多(据我所知)虚假属性.一个隐含的,即模式匹配目标,%.subdir
如上所述,就好像被添加到.PHONY
(这是不可能的,因为它本身不是明确的),但通过其先发制人的虚假变成虚假phony_explicit
.
它归结为每个规则 - 也通过模式匹配隐含 - 在其先决条件中具有明确的虚假目标(即添加到其中的目标.PHONY
)是通过这种依赖性也以虚假的方式执行(每次,无条件地文件系统错误地执行)有一个具有一个令人难以置信的名字的文件).
实际上,GNU make文档提到了FORCE
目标,在某些版本的GNU中,不提供.PHONY
目标的部分模拟了.PHONY
行为.此处提供的替代方法使用此FORCE
目标approuch,但由于使用了GNU make,它还将FORCE
目标设置为.PHONY
避免与现有的同名文件发生潜在冲突.
有了这个解决方案甚至
touch clean.subir; make clean.subdir
Run Code Online (Sandbox Code Playgroud)
将产生所需的调用
make -C src clean
make -C dist clean
Run Code Online (Sandbox Code Playgroud)
可能这个替代方案的潜在优点是它不需要显式声明clean.subdir
和all.subdir
,但实际上是使用隐式%.subdir
模式匹配.
bta*_*bta 10
从制作手册的这一部分:
对于.PHONY目标,将跳过隐式规则搜索(请参阅隐式规则).这就是为什么将目标声明为.PHONY有利于提高性能,即使您不担心实际存在的文件.
因此,永远不会搜索您的隐式目标,因为它们是虚假的.
你可以通过另一种方式实现你想做的事情.试试这个:
SUBDIRS := all clean
.PHONY: $(SUBDIRS)
$(SUBDIRS):
echo $(MAKE) -C src $@
echo $(MAKE) -C dict $@
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
14684 次 |
最近记录: |