Scons:仅当目标已更改时才生成版本文件 [英] Scons: Generating version file only if target has changed

查看:33
本文介绍了Scons:仅当目标已更改时才生成版本文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要从 SCons 脚本生成 version.cc 文件.仅当目标的任何源文件发生更改时才应生成此文件.

假设 SCons 脚本有以下语句

#python 函数在生成 libtest.a 的同一文件夹中生成 version.cc.这将始终生成不同的 version.cc,因为其中包含的版本字符串将具有时间戳生成版本代码()#target 使用 version.cclibtest = env.Library('test', ['a.cc', 'b.cc', 'version.cc'])

第一次运行上述代码时一切正常.但是当我再次运行相同的脚本时,由于生成了新的 version.cc,目标 'test' 将被重建.我的要求是,如果 version.cc 文件已经存在并且任何源(即本例中的 a.cc 和 b.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 的内容,该函数检查自上次构建以来源文件的更改.

解决方案

据我所知,如果任何源文件发生变化,你只想生成 version.cc,如果 version.cc 你只想构建库更改或任何库源文件更改.也就是说,将 version.cc 视为库的源文件之一.

如果是这种情况,您可以考虑 2 组依赖项,它们都将由 SCons 依赖项检查控制.

不太清楚 version.cc 生成由什么组成,但让我们假设 python 函数 GenerateVersionCode() 将完全做到这一点:生成 version.cc,但不会有任何依赖检查相关的逻辑.

这是 SConscript 代码:

def GenerateVersionCode(env, target, source):# 这里填写生成代码# version.cc 检查env.Command(target='version.cc',来源=['a.cc', 'b.cc'],动作=生成版本代码)# 图书馆env.Library(target='test', source=['version.cc', 'a.cc', 'b.cc'])

这不应该是必要的,但可以通过使用 SCons Depends() 函数显式设置从库目标到 version.cc 目标的依赖关系来更进一步.

这是我在构建时得到的输出,我没有使用 GenerateVersionCode() 函数,而是使用了一个简单的 shell 脚本 versionGen.sh,从而将对 Command() 的调用更改为:

env.Command(target='version.cc',来源=['a.cc', 'b.cc'],action='./versionGen.sh')

这是第一个构建:

<代码>>烤饼scons:读取 SConscript 文件...scons:完成读取 SConscript 文件.scons:建立目标......g++ -o a.o -c a.ccg++ -o b.o -c b.cc./versionGen.shg++ -o version.o -c version.ccar rc libtest.a version.o a.o b.o运行libtest.ascons:完成构建目标.

然后,没有改变任何东西,我再次构建,它什么也没做:

<代码>>烤饼scons:读取 SConscript 文件...scons:完成读取 SConscript 文件.scons:建立目标......scons:`.'已是最新.scons:完成构建目标.

然后,我修改了a.cc,再次构建,它生成了一个新版本的version.cc:

<代码>>vi a.cc>烤饼scons:读取 SConscript 文件...scons:完成读取 SConscript 文件.scons:建立目标......g++ -o a.o -c a.cc./versionGen.shg++ -o version.o -c version.ccar rc libtest.a version.o a.o b.o运行libtest.ascons:完成构建目标.

I have a requirement to generate version.cc file from SCons Script. This file should be generated only if any of the source file for a target has changed.

Suppose the SCons script has the following statements

#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'])

First time when I run the above code everything is fine. But when I run the same script again, the target 'test' will be rebuilt because of new version.cc which got generated. My requirement is we should not generate new version of version.cc file if the file is already present and there are no changes in any of the sources (namely a.cc and b.cc in this example)



   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'])

One related question on this site suggested something as follows


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

W.r.to the above suggestion I would want to know the contents of function PythonFunctionToUpdateContents which checks the change in source files since previous build.

解决方案

As I understand it, you only want to generate version.cc if any of the source files change, and you only want to build the library if version.cc changes or if any of the library source files change. That is, consider version.cc as one of the source files for the library.

If this is the case, you could consider 2 sets of dependencies, both of which would be controlled by the SCons dependency checking.

Its not real clear what the version.cc generation consists of, but lets assume that the python function GenerateVersionCode() will do exactly that: generate version.cc, but wont have any dependency checking related logic.

Here is the SConscript code:

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'])

It shouldnt be necessary, but this could be taken one step further by explicitly setting a dependency from the Library target to the version.cc target with the SCons Depends() function.

Here is the output I get when I build, and instead of using the GenerateVersionCode() function, I use a simple shell script versionGen.sh, thus changing the call to Command() to this:

env.Command(target='version.cc',
            source=['a.cc', 'b.cc'],
            action='./versionGen.sh')

Here is the first build:

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

Then, without having changed anything, I build again, and it does nothing:

> scons
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
scons: `.' is up to date.
scons: done building targets.

Then, I modify a.cc, and build again, and it generates a new version of 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.

这篇关于Scons:仅当目标已更改时才生成版本文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆