Scons:仅在目标已更改时生成版本文件

时间:2013-06-26 18:02:22

标签: scons

我需要从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的内容,它检查自上一次构建以来源文件的变化。

1 个答案:

答案 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.