Makefile 从先决条件中动态排除目标文件以避免循环依赖
如果目标文件周围的任何文件(同一目录中相同类型的文件)发生了更改,我将尝试构建一个目标文件(使用GNU make)。这似乎很简单,但我却找不到解决办法。以下是此生成文件的关键行:Makefile 从先决条件中动态排除目标文件以避免循环依赖,makefile,target,circular-dependency,prerequisites,Makefile,Target,Circular Dependency,Prerequisites,如果目标文件周围的任何文件(同一目录中相同类型的文件)发生了更改,我将尝试构建一个目标文件(使用GNU make)。这似乎很简单,但我却找不到解决办法。以下是此生成文件的关键行: dir/%.Rd: file1 file2 dir/*.Rd ... 其中/dir中有40-50个*.Rd文件(包括%.Rd)。虽然make将自动删除循环依赖项(上面的代码确实有效),但我希望根据自身情况删除%.Rd的循环性。我试过: (一) (二) (三) (四) 这似乎是一个相对简单的问题,我相信我已经接
dir/%.Rd: file1 file2 dir/*.Rd
...
其中/dir
中有40-50个*.Rd文件(包括%.Rd
)。虽然make
将自动删除循环依赖项(上面的代码确实有效),但我希望根据自身情况删除%.Rd
的循环性。我试过:
(一)
(二)
(三)
(四)
这似乎是一个相对简单的问题,我相信我已经接近了。非常感谢您提供任何解决方案/建议/解决方法
提前感谢…这也许是做你想做的事情最不可怕的方式:
RD := $(wildcard *.Rd)
ifneq ($(TARG),)
RD := $(filter-out $(TARG),$(RD))
$(TARG): $(RD)
do something to update $@
endif
rebuild_%:
@$(MAKE) $*.rd TARG=$*.Rd
现在
make rebuild\u myfile
将更新myfile.Rd
当且仅当它不是目录中最新的Rd
文件,并且没有循环依赖关系时。如果目标文件不是最新的,是否要重新生成?这样一次最多只能有一个是“最新的”?那是一个奇怪的设计,与品牌格格不入。如果同一目录中的任何文件发生更改,我想更新目标。但是,如果我只是使用*.Rd
来定义先决条件,那么目标文件将包含在“*”中,从而创建循环依赖关系。我想避免这种情况。我不相信这个设计违背了制造教条。如果其中任何一个已经改变了?从什么时候开始改变了?你可能有一个简单的、逻辑上自我一致的目标,但我看不出来。嗯…“已更改”应该写为“比目标文件更新”。因此,要改写这个问题:我有一个目录,有大约40个文件,所有文件的扩展名都是.Rd
。其中一个是我的目标文件(比如myfile.Rd
)。我想更新同一目录中任何其他*.Rd
文件的myfile.Rd
比myfile.Rd
更新。我不能简单地使用*.Rd
定义先决条件,因为myfile.Rd
是其中之一,这将产生循环依赖性问题。我想删除myfile.Rd
从目标定义中的*.Rd
。很好…非常感谢。我会试试这个。同时我确实找到了一个解决方法>>dir/%.Rd:file1 file2$$(过滤掉$$@,$(通配符dir/*.Rd))
,它展示了我正在寻找的行为(我想)因此,我必须看看这两种解决方案是否存在缺陷,这会使它比另一种更可取。这个解决方案前面当然有一行.SECONDEXPANSION
。@StuField:我想到了,但它仍然有循环依赖性,因为foo.Rd
依赖于bar.Rd
,反之亦然Make的依赖关系树构建很奇怪,因为循环依赖关系警告在此解决方案中消失。使用-debug选项,任何地方都没有循环依赖的迹象。
dir/%.Rd: file1 file2 $(filter-out $@, dir/*.Rd) # doesn't appear to work: circular dependency warning
...
dir/%.Rd: file1 file2 $$(filter-out $$@, dir/*.Rd) # same
...
.SECONDEXPANSION:
dir/%.Rd: file1 file2 $$(filter-out $$@, dir/*.Rd) # same
...
RD := $(wildcard *.Rd)
ifneq ($(TARG),)
RD := $(filter-out $(TARG),$(RD))
$(TARG): $(RD)
do something to update $@
endif
rebuild_%:
@$(MAKE) $*.rd TARG=$*.Rd