如何收集GNU make中过时依赖项的列表?

时间:2011-03-05 11:52:45

标签: makefile

我有一些XML源文件需要由Ruby脚本处理,以便在构建主目标之前创建生成的c#文件。脚本的启动成本远远大于处理每个文件的时间,因此通常在make文件中逐个处理它们是非常低效的。我想要做的是将它们全部收集起来并将它们作为列表传递给脚本,该脚本在更新主目标之前执行。

我现在拥有的是:

_generated_/%.xml.cs : %.cs
    #execute ruby script to generate .cs file

out.exe : a.cs b.cs _generated_/e.xml.cs ....
    #compile .cs files

我遇到了使用eval的想法,所以如果处理的文件后缀为.s并且在脚本处理时产生后缀为.t的文件,我的想法就是:

%.xml : _generated_/%.xml.cs        
    $(eval SOURCE_FILES += $<)

然而,除非在eval之后有shell命令(echo会这样做),否则这个规则不会触发 - 我想这是因为make知道简单地调用一个函数不可能生成一个文件。我的另一个想法是将文件列表收集到一个临时文件中。

    .INTERMEDIATE source_list.txt

   %.xml : _generated_/%.xml.cs        
        echo $< >> source_list.txt

虽然这些可能都有效,但我想知道是否有更好的方法来做到这一点。

更新

我最终做的是如下所示 - eval函数上的@前缀让傻瓜相信正在执行shell命令。

_generated_/%.xml.cs : %.cs
        @ $(eval DIRTY_XML += $(<))

out.exe : a.cs b.cs _generated_/e.xml.cs ....
        # Create generated cs files 
        # by running ruby script with DIRTY_XML as input 
        # Compile all .cs files

2 个答案:

答案 0 :(得分:3)

使用名为ruby-marker的空文件来表示已处理完所有xml文件。它的修改时间可以与“x.s”文件的修改时间进行比较。然后使用$?仅选择自上次运行ruby脚本以来已更改的先决条件“x.s”文件。

main-target: ruby-marker
    whatever...

ruby-marker: foo.s bar.s baz.s
    ruby-script $?
    @touch $@

答案 1 :(得分:0)

您可以在$(filter)上使用$? - $?是比目标更新的先决条件列表。