我需要从SCons Script生成version.cc文件。仅当目标的任何源文件发生更改时,才应生成此文件。
假设SCons脚本具有以下语句
#python function which generates version.cc in the same folder where libtest.a is generated. This will always generate a differnt version.cc because the version string contained inside that will have timestamp
GenerateVersionCode()
#target which uses version.cc
libtest = env.Library('test', ['a.cc', 'b.cc', 'version.cc'])
第一次运行上面的代码时,一切都很好。但是当我再次运行相同的脚本时,由于生成了新的version.cc,目标'test'将被重建。 我的要求是,如果文件已经存在并且任何源中没有任何更改(例如本例中的a.cc和b.cc),我们就不应该生成新版本的.cc文件。
if not version_file_present: GenerateVersionCode() else if no_changes_in_source: GenerateVersionCode() #target which uses version.cc which could be newly generated one or previous one libtest = env.Library('test', ['a.cc', 'b.cc', 'version.cc'])
本网站上的一个相关问题提示如下
env.Command(target="version.c", source="version-in.c", action=PythonFunctionToUpdateContents) env.Program("foo", ["foo.c", "version.c"])
W.r.对上述建议我想知道函数PythonFunctionToUpdateContents的内容,它检查自上一次构建以来源文件的变化。
答案 0 :(得分:5)
据我了解,如果任何源文件发生更改,您只想生成version.cc,并且只想在version.cc更改或任何库源文件发生更改时构建库。也就是说,将version.cc视为库的源文件之一。
如果是这种情况,您可以考虑两组依赖项,这两种依赖项都将由SCons依赖项检查控制。
它不是真正清楚version.cc生成包含的内容,但我们假设python函数GenerateVersionCode()将完全执行此操作:生成version.cc,但不会有任何依赖项检查相关逻辑。
这是SConscript代码:
def GenerateVersionCode(env, target, source):
# fill in generation code here
# The version.cc checking
env.Command(target='version.cc',
source=['a.cc', 'b.cc'],
action=GenerateVersionCode)
# The library
env.Library(target='test', source=['version.cc', 'a.cc', 'b.cc'])
这不一定是必要的,但是可以通过使用SCons Depends()函数显式设置从Library目标到version.cc目标的依赖关系来更进一步。
这是我构建时得到的输出,而不是使用GenerateVersionCode()函数,我使用一个简单的shell脚本versionGen.sh,从而将对Command()的调用更改为:
env.Command(target='version.cc',
source=['a.cc', 'b.cc'],
action='./versionGen.sh')
这是第一个版本:
> scons
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
g++ -o a.o -c a.cc
g++ -o b.o -c b.cc
./versionGen.sh
g++ -o version.o -c version.cc
ar rc libtest.a version.o a.o b.o
ranlib libtest.a
scons: done building targets.
然后,在没有改变任何东西的情况下,我再次构建,它什么也没做:
> scons
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
scons: `.' is up to date.
scons: done building targets.
然后,我修改了一个.cc,然后重新构建,它生成了一个新版本的version.cc:
> vi a.cc
> scons
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
g++ -o a.o -c a.cc
./versionGen.sh
g++ -o version.o -c version.cc
ar rc libtest.a version.o a.o b.o
ranlib libtest.a
scons: done building targets.