更新作为构建一部分的文件内容的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生成ENTIRE version.c文件来解决这个问题,但这不合适,因为version.c包含许多其他代码,这些代码可以作为正常开发的一部分进行更改。
答案 0 :(得分:5)
执行此操作的常用方法是使用“version.c.in”或“version-in.c”或任何您喜欢的方法。修改它并将其输出到version.c。您可以将“in”文件添加到版本控制系统,而version.c文件不会在那里。所以这一切的结果如下:
env.Command(target="version.c", source="version-in.c",
action=PythonFunctionToUpdateContents)
env.Program("foo", ["foo.c", "version.c"])
这也适用于其他构建系统 - 将输入文件也作为输出文件通常是个坏主意。最好使用中间文件来完成工作。
答案 1 :(得分:5)
这个答案对派对来说有点晚了,但无论如何它都在这里:
您应该使用env.Precious("version.c")
。这可以防止在构建文件之前删除该文件。
您可能还想使用env.NoClean("version.c")
,以便在清理过程中不会删除它。
你可能会使用 env.SideEffect
,但那个似乎有一些奇怪的事情。我被告知在邮件列表上通常不会使用那个。