如何在 GNU make 中收集过期依赖项列表?

Posted

技术标签:

【中文标题】如何在 GNU make 中收集过期依赖项列表?【英文标题】:How can I collect a list of out of date dependencies in GNU make? 【发布时间】:2011-03-05 11:52:45 【问题描述】:

我有一些 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

【问题讨论】:

【参考方案1】:

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

main-target: ruby-marker
    whatever...

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

【讨论】:

【参考方案2】:

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

【讨论】:

我已经编辑了我的问题,以使我正在做的事情更清楚。我试过了,但是如果尝试从 $? 构造过期的 xml 文件列表?在编译 .cs 文件的规则中,然后 make 抱怨它没有如何生成生成的 .cs 文件。使其工作的一种方法是使用另一个规则,其中生成的 .cs 文件依赖于 .xml 文件,并且规则只执行 touch 以创建虚拟生成的 .cs 文件,因此第二个规则可以完成生成所有文件的实际工作在编译它们之前将它们分批。

以上是关于如何在 GNU make 中收集过期依赖项列表?的主要内容,如果未能解决你的问题,请参考以下文章

GNU make:规则专题

GNU makefile 规则和依赖项

如何从 CMake 或 make 输出编译依赖项?

用make生成c源的目标文件时如何生成依赖文件

GNU Make 将空格转换为冒号

在Gradle中过期依赖项时发出警告