我正面临一个奇怪的 SCons 问题,尽管看起来我并没有试图实现任何奇怪的事情。情况是这样的(不幸的是,我们使用了许多专有的 SCons 包装器,所以我不能分享代码,至少因为它无论如何都不清楚):
令人惊讶的是,这是我很长一段时间都无法实现的事情,因为我无法保持 SCons 逻辑的一致性。
最简单的一致方法是将生成的文件列表作为库的源。从依赖关系的角度来看,这看起来工作正常; SCons 识别生成的文件何时更新,从而重新编译它们并重新链接库。问题是SCons把生成文件的结果对象放到了生成文件所在的父目录下。因此,它们不是使生成的二进制文件损坏的每个变体目标文件。
然而,我找不到任何方法来构建生成文件的目标文件的单独副本。如果我将生成的文件复制到父 SConscript 中的变体目录 (Command(,,(Copy))),SCons 可以在文件再次生成之前复制这些文件。如果我尝试在附属的 SConscript 中填充生成的文件,库构建器无法识别这些源文件的更新,也不会重新编译它们。
我尝试了很多不同的选项和显式依赖关系,但是文件之间的依赖关系构建链在不同的构建场景中看起来并不确定。我真的很感激任何新的想法。这不是 SCons 具有什么功能的问题,而是如何将功能绑定在一起以达到目标的问题。到现在为止,我还没有找到办法,但我简直不敢相信我的情况太特殊了。
我假设你的变体 dir SConscript 看起来像这样
Import(['env','list_of_generated_files'])
env.SharedLibary('magically_delicious',list_of_generated_files)
假设是这样,这就是 SCons 在幕后所做的事情。
SharedLibary 唯一有效的源文件是目标文件、共享库和静态库(我相当确定)。并且绝对 C/C++ 源文件不是有效的源文件。但是 SCons 知道如何将 C/C++ 文件构建到目标文件中。
在引擎盖下 SCons 做这样的事情:
list_of_objects=[env.SharedObject(s) for s in list_of_generated_files]
由于生成的文件在父目录中,默认情况下(换句话说,当没有指定明确的目标时),SCons 将始终在指定的源文件旁边构建目标文件。
因此在变体目录中生成你的库,在父目录中生成对象。
那么我们如何解决这个问题呢? 我们基本上重现了 SCons 在幕后所做的事情,但这次我们指定了目标。
Import(['env','list_of_generated_files'])
list_of_objects = [env.SharedObject('./${SOURCE.filebase}$SHOBJSUFFIX',s) for s in list_of_generated_files]
env.SharedLibary('magically_delicious',list_of_objects)
请注意,您可以在目标文件规范中使用 subst() 的字符串。
这里有一堆这样的例子
$TARGET => sub/dir/file.x
${TARGET.base} => sub/dir/file
${TARGET.dir} => sub/dir
${TARGET.file} => file.x
${TARGET.filebase} => file
${TARGET.suffix} => .x
${TARGET.abspath} => /top/dir/sub/dir/file.x
${TARGET.relpath} => sub/dir/file.x
$TARGET => ../dir2/file.x
${TARGET.abspath} => /top/dir2/file.x
${TARGET.relpath} => ../dir2/file.x
您可以在联机帮助页中阅读更多相关信息 试试上面的方法,让我们知道这是否适合您