如何使 SCONS 更新构建中使用的文件的内容
更新构建过程中的文件内容的正确 SCONS 方法是什么?
我使用 SCONS 构建了一个相当大的项目。但为了一个简单的问题,假设它看起来像这样:
env.Program("foo", ["foo.c", "version.c"])
在某些构建条件下,有必要使用新信息(实际上是版本信息)更新构建中的 CPP 文件之一的内容。在上面的例子中,我需要修改“version.c”的内容。我认为我可以通过以下示例很好地做到这一点:
env.Command(target="version.c", source=[], action=PythonFunctionToUpdateContents)
env.Program("foo", ["foo.c", "version.c"])
PythonFunctionToUpdateContents 将使用 target[0] 作为文件名,打开它,查找一些特定文本,更改它,将更改写回同一文件。不幸的是,上面的示例不起作用。 SCONS 会在构建目标文件之前自动删除它,因此我的“version.c”文件在更新之前就被删除了。
我尝试在 env.Command() 调用中将目标和源设置为同一文件,但这只会创建一个依赖循环。
我知道我可以通过让 SCONS 生成整个 version.c 文件来解决这个问题,但这并不合适,因为 version.c 包含许多其他代码,这些代码可以作为正常开发的一部分进行更改。
What's the proper SCONS method for updating the contents of a file that is part of build?
I use SCONS to build a fairly large project. But for the sake of a simple question, assume it looks like this:
env.Program("foo", ["foo.c", "version.c"])
Under certain build conditions, it's necessary to update the contents of one of the CPP files in the build with new information - version information actually. In the above example, I would need to modify the contents of "version.c". I thought I could do this rather nicely with the following example:
env.Command(target="version.c", source=[], action=PythonFunctionToUpdateContents)
env.Program("foo", ["foo.c", "version.c"])
The PythonFunctionToUpdateContents would use target[0] as the name of the file, open it, look for some specific text, change it, write the changes back to the same file. Unfortunately, the above sample doesn't work. SCONS automatically deletes a target file before building it, so my "version.c" file got deleted before it could be updated.
I tried setting the target and source to the same file in the env.Command() call, but that just creates a dependency cycle.
I know that I could solve this by having SCONS generate the ENTIRE version.c file, but that's not suitable since version.c contains a lot of other code that can change as part of normal development.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
通常的方法是使用“version.c.in”或“version-in.c”或任何您喜欢的名称。修改它并将其输出到 version.c。您可以将“in”文件添加到版本控制系统中,而 version.c 文件不会在那里。因此,所有这一切的结果如下所示:
这也适用于其他构建系统 - 让输入文件同时成为输出文件通常是一个坏主意。使用中间文件来完成工作要好得多。
The usual way to do this is to have a "version.c.in" or "version-in.c" or whatever you like to call it. Modify that and output it to version.c. You would add the "in" file to your version control system, while the version.c file would not be in there. So the result of all this would look as follows:
This applies to other build systems too - it is generally a bad idea to have an input file also be an output file. Far better to use an intermediate file to get the job done.
这个答案有点晚了,但无论如何:
你应该使用 env.Precious("version.c") 。这可以防止文件在构建之前被删除。
您可能还想使用
env.NoClean("version.c")
,这样它就不会在清理过程中被删除。你也许可以使用env.SideEffect
,但是那个似乎有一些奇怪的事情。邮件列表上告诉我一般不要使用那个。This answer is kinda late to the party, but here it is anyway:
You should use
env.Precious("version.c")
. This prevents the file from being deleted before being built.You probably also want to use
env.NoClean("version.c")
so that it doesn't get deleted during a clean.You COULD useenv.SideEffect
maybe, but that one seems to have a couple weird things about it. I was told on the mailing list to generally not use that one.