4

我需要从 SCons 脚本生成 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,目标“测试”将被重建。我的要求是,如果文件已经存在并且任何源(即本例中的 a.cc 和 b.cc)都没有更改,我们不应该生成新版本的 version.cc 文件


   如果不是 version_file_present:
        生成版本代码()
    别的
        如果 no_changes_in_source:  
            生成版本代码()


    #target 使用 version.cc 可以是新生成的一个或以前的一个
    libtest = env.Library('test', ['a.cc', 'b.cc', 'version.cc'])

该网站上的一个相关问题建议如下

    env.Command(target="version.c", source="version-in.c",
        动作=PythonFunctionToUpdateContents)
    env.Program("foo", ["foo.c", "version.c"])

对于上述建议,我想知道函数 PythonFunctionToUpdateContents 的内容,该函数检查自上次构建以来源文件的更改。

4

1 回答 1

5

据我了解,您只想在任何源文件更改时生成 version.cc,并且您只想在 version.cc 更改或任何库源文件更改时构建库。也就是说,将 version.cc 视为库的源文件之一。

如果是这种情况,您可以考虑 2 组依赖项,它们都将由 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.

然后,我修改 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.
于 2013-06-26T20:21:12.463 回答