如何在不调用目标的情况下在makefile中使用依赖项?

时间:2010-03-17 13:58:52

标签: makefile

我正在使用makefile将内部文件格式转换为发送给其他同事的XML文件。他们会对XML文件进行更改并将其发回给我们(不要问,这需要这样;))。当这个XML发生变化时,我想用makefile来更新内部文件。

所以我有这些规则:

%.internal: $(DATAFILES)
       # Read changes from XML if any
       # Create internal representation here

%.xml: %.internal
       # Convert to XML here

现在,由于上述工作流程,XML可能会发生变化。但由于没有数据文件发生变化,make会告诉我file.internal是最新的。我希望避免使%.internal目标虚假,并且对%.xml的循环依赖显然不起作用。

我可以强迫make检查XML文件中的更改并重新构建%.internal吗?

3 个答案:

答案 0 :(得分:1)

您希望允许两种不同的操作:从内部文件创建xml文件,并从xml文件创建内部文件。由于Make只知道修改时间,因此它知道哪个目标较旧,但不知道是否应该重新制作。所以把另一个文件作为一个标志放在最后一次采取任何一个动作时记录下来,然后把它作为你的主要目标;如果任一目标比标志更新,它已经被这些动作以外的东西修改,并且make应该重建旧目标(然后触摸标志)。

有几种方法可以实现这一点。在某些版本的Make(例如GNUMake的最新版本)中,您可以编写双冒号规则,以便Make将以不同方式重建目标,具体取决于哪个preq触发它:

%.flag:: %.internal
    # convert $*.internal to $*.xml
    touch $@

%.flag:: %.xml
    # rewrite $*.internal based on $*.xml
    touch $@

不太优雅但更便携的方式是看$?并重建其他文件:

%.flag: %.xml %.internal
ifeq ($?,$*.internal)
    # convert $*.internal to $*.xml
else
    # rewrite $*.internal based on $*.xml
endif
    touch $@

答案 1 :(得分:1)

我认为你可以这样做:

all: .last-converted-xml .last-converted-internal

.last-converted-internal: *.internal
    ./internal-2-xml $?
    touch $@ .last-converted-xml

.last-converted-xml: *.xml
    ./xml-2-internal $?
    touch $@ .last-converted-internal

在比任意标记文件“.last-converted”更新的任何.xml文件上运行“xml-convert”。 $?应该给你一个比标记文件更新的所有依赖项(* .xml)的列表。

当然,必须编写xml-convert程序来获取xml文件列表并处理每个文件。

我不确定你是否确实需要.internal文件,或者这只是尝试让makefile正常工作。因此,您的“xml-convert”程序可以将每个.xml文件转换到位,也可以在需要时生成file.internal。

答案 2 :(得分:-1)

使用make的-W选项让make认为其中一个数据文件已更改:

make -W somedatafile

这将导致make认为somedatafile已被修改而没有实际更改它的修改时间。


是否可以为XML文件使用不同的名称?您从内部格式创建的文件将有一个名称和您的同事发送给您另一个文件?如果他们使用不同的名称,那么就没有循环依赖。

相关问题