我需要从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'])
Run Code Online (Sandbox Code Playgroud)
我第一次运行上面的代码时一切都很好.但是当我再次运行相同的脚本时,由于生成了新的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"])
对于上面的建议,我想知道函数PythonFunctionToUpdateContents的内容,它检查自上一次构建以来源文件的变化.
据我了解,如果任何源文件发生更改,您只想生成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'])
Run Code Online (Sandbox Code Playgroud)
它不一定是必要的,但是通过使用SCons Depends()函数显式设置从Library目标到version.cc目标的依赖关系,可以更进一步.
这是我构建时得到的输出,而不是使用GenerateVersionCode()函数,我使用一个简单的shell脚本versionGen.sh,从而将对Command()的调用更改为:
env.Command(target='version.cc',
source=['a.cc', 'b.cc'],
action='./versionGen.sh')
Run Code Online (Sandbox Code Playgroud)
这是第一个构建:
> 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.
Run Code Online (Sandbox Code Playgroud)
然后,在没有改变任何东西的情况下,我再次构建,它什么也没做:
> scons
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
scons: `.' is up to date.
scons: done building targets.
Run Code Online (Sandbox Code Playgroud)
然后,我修改a.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.
Run Code Online (Sandbox Code Playgroud)