我将一个项目的不同版本保存在不同的目录中。 (这个
不幸的是,我必须意识到,当从不同目录中的相同源构建目标文件时,SCons 2.3.3将结果存储在缓存中的不同位置。 (我假设该位置等于构建签名。)为每个目录重新编译相同的源。那么为什么SCons确定不同的构建签名,尽管
gcc -E ...
)即使生成的目标文件也相同!
对于一个简单的例子(来自SCons文档的helloworld
)重用缓存有效。虽然在我正在开展的大型项目中,但事实并非如此。也许“SCons构建环境”会影响构建签名,即使它对编译命令没有任何影响吗?
除了--cache-debug=-
之外,是否有任何可以帮助的调试选项? SCons的哪种方法决定了构建签名?
文件夹看起来像这样:
<basedir1>/
SConstruct
src/something.cpp …
include/header.hpp …
<basedir2>/
SConstruct
src/something.cpp …
include/header.hpp …
/SharedCache/
0/ 1/ 2/ … F/
我在 basedir1 和 basedir2 中检查项目,并在两者中调用scons --build-cache-dir=/SharedCache
。 (编辑:--build-cache-dir
是一个自定义选项,在此项目的SConstruct
文件中实现。它映射到env.CacheDir('/SharedCache')
。
EDIT2:在我意识到这个问题之前,我做了一些测试来评估使用--cache-implicit
或SCons 2.4.0的效果。
答案 0 :(得分:1)
这是文件src/engine/SCons/Node/FS.py
中方法def get_cachedir_bsig(self):
"""
Return the signature for a cached file, including
its children.
It adds the path of the cached file to the cache signature,
because multiple targets built by the same action will all
have the same build signature, and we have to differentiate
them somehow.
"""
try:
return self.cachesig
except AttributeError:
pass
# Collect signatures for all children
children = self.children()
sigs = [n.get_cachedir_csig() for n in children]
# Append this node's signature...
sigs.append(self.get_contents_sig())
# ...and it's path
sigs.append(self.get_internal_path())
# Merge this all into a single signature
result = self.cachesig = SCons.Util.MD5collect(sigs)
return result
的代码:
get_cachedir_csig()
它显示了缓存文件的路径如何包含在“缓存构建签名”中,这解释了您看到的行为。为了完整起见,这里还有来自同一FS.py
文件的def get_cachedir_csig(self):
"""
Fetch a Node's content signature for purposes of computing
another Node's cachesig.
This is a wrapper around the normal get_csig() method that handles
the somewhat obscure case of using CacheDir with the -n option.
Any files that don't exist would normally be "built" by fetching
them from the cache, but the normal get_csig() method will try
to open up the local file, which doesn't exist because the -n
option meant we didn't actually pull the file from cachedir.
But since the file *does* actually exist in the cachedir, we
can use its contents for the csig.
"""
try:
return self.cachedir_csig
except AttributeError:
pass
cachedir, cachefile = self.get_build_env().get_CacheDir().cachepath(self)
if not self.exists() and cachefile and os.path.exists(cachefile):
self.cachedir_csig = SCons.Util.MD5filesignature(cachefile, \
SCons.Node.FS.File.md5_chunksize * 1024)
else:
self.cachedir_csig = self.get_csig()
return self.cachedir_csig
方法的代码:
RunAndRenderTask
将子节点的缓存路径散列到最终构建签名中。
编辑:然后使用上面计算的“缓存构建签名”来构建“缓存路径”。像这样,所有文件/目标都可以映射到一个唯一的“缓存路径”,通过它可以引用它们并在缓存中找到(=从中检索)。正如上面的注释所解释的那样,每个文件的相对路径(从SConstruct的顶级文件夹开始)是这个“缓存路径”的一部分。因此,如果您在不同的目录中具有相同的源/目标(foo.c-&gt; foo.obj),它们将具有不同的“缓存路径”并且彼此独立构建。
如果您真的想在不同项目之间共享源代码,请注意CacheDir功能如何更多地用于在不同开发人员之间共享相同的源,您可能需要查看Repository()方法。它让你将另一个源树挂载(融入)到你当前的项目......