如何收集 GNU make 中过时依赖项的列表?
我有一些 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
I have some XML source files which need to be processed by a Ruby script to create generated c# files before my main target can be built. The start-up cost of script is much greater than the time to process each file so it's quite inefficient to process them one by one as is usually done in make files. What I want to do is collect them all together and pass them as a list to script which execute just before updating the main target.
What I have now is something like:
_generated_/%.xml.cs : %.cs
#execute ruby script to generate .cs file
out.exe : a.cs b.cs _generated_/e.xml.cs ....
#compile .cs files
I came across the idea of using eval for this so if the files which are processed have a suffix of .s and yield a file with a suffix of .t when processed by the script my idea was to do this:
%.xml : _generated_/%.xml.cs
$(eval SOURCE_FILES += lt;)
However this rule won't trigger unless there is shell command after the eval (echo will do) - I guess it's because make knows that simply calling a function can't possibly produce a file. Another idea I had was to collect the list of files into a temporary file instead.
.INTERMEDIATE source_list.txt
%.xml : _generated_/%.xml.cs
echo lt; >> source_list.txt
While these will probably both work, I am wondering if there is a better way to do this.
Update:
What I ended up doing is was something like the following - the @ prefix on eval function fools make into believing that a shell command is being executed.
_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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
使用名为
ruby-marker
的空文件来指示所有 xml 文件均已处理。其修改时间可以与“xs”文件的修改时间进行比较。然后使用$?
仅选择自上次运行 ruby 脚本以来已更改的先决条件“xs”文件。Use an empty file called, say,
ruby-marker
, to indicate that all of the xml files have been processed. Its modification time can be compared to those of the "x.s" files. Then use$?
to select only the prerequisite "x.s" files that have changed since the last run of the ruby script.您可以在
$?
上使用$(filter)
-$?
是比目标更新的先决条件列表。You could use a
$(filter)
on$?
-$?
is the list of prerequisites that are newer than target.