SCons:如何明确表达envs之间的依赖关系?

时间:2014-02-22 02:25:58

标签: scons

我有一个由scons构建的项目。 在项目中有多个组件,包括客户端,shell,引擎等......

每个组件使用不同的编译选项,因此它们被拆分为不同的env。 shell和引擎都需要首先构建客户端库。

在环境设置中,shell和引擎都有类似“-lclient -L [installpath] / lib”的东西,SConscriptClient将在[installpath] / lib中构建libclient.a。

所以我希望SConscriptClient在其他所有事情之前运行。

所以在代码中我有类似的东西:

  clientbuild = clientEnv.SConscript ( 'SConscriptClient', variant_dir=clientDir )
  if hasShell:
     shellbuild = shellEnv.SConscript ( 'SConscriptShell', variant_dir=shellDir )
     Depends ( shellbuild, clientbuild )
  if hasEngine:
     enginebuild = engineEnv.SConscript ( 'SConscriptEngine', variant_dir=engineDir )
     Depends ( enginebuild, clientbuild )

然而,似乎scons不够聪明,无法理解客户端/ shell和引擎之间的依赖关系(这意味着Depends调用不会生效)。它仍然尝试在SConscriptClient之前运行SConscriptShell

我能做些什么来设置sconscript之间的依赖吗?

1 个答案:

答案 0 :(得分:2)

您不应该 显式地 使用Depends()设置这些依赖项。如果客户端库是由SCons构建的目标,并且shell和引擎链接该库,那么SCons应该能够 隐式地 来确定依赖关系并首先构建客户端。

基本上,我在这里看到了两个问题:

  1. 为什么SCons没有隐含地找出依赖关系?
  2. 为什么它不能像显式调用Depends()一样工作?
  3. 如果我们计算出数字1,那么我们就不必弄清楚数字2.但是为了完成,我认为数字2不起作用,因为对SConscript()的调用正在返回。在子公司SConscript脚本(SConscriptClient,SConscriptShell和SConscriptEngine)中是否返回了目标?如果没有,我会想象clientbuild变量为None。要返回目标,请使用Return() SCons函数,并将Library()构建器的返回值传递给它。

    至于为什么SCons无法隐式地找出依赖关系,我们需要查看辅助SConscript构建脚本。但我可以想象它,因为你可能“手动”指定客户端库,所以SCons没有看到依赖。

    使用库构建程序以便SCons可以看到依赖项的方法,您需要使用 LIBS 构造变量,如下所示:

    env.Append(LIBS='client')
    env.Append(LIBPATH='path/to/client/lib')
    env.Program(target='shell', source='shell.cc')
    

    请注意,我不使用上面的-l-L标记,SCons将以独立于平台的方式添加这些标记。如果您通过像下面这样指定库来“手动”指定库:' - lclient'然后SCons将看不到依赖项。这是设计的,并且包含路径更有意思:如果你有很多带头文件的包含路径几乎永远不会改变,那么(出于性能原因)你不希望SCons扫描它们改变,从而“手动”指定它们。

    另外一条评论,通常是不同的环境以不同的方式传递给子公司SConscript构建脚本,如下所示:

    clientEnv = Environment()
    # set the clientEnv accordingly
    SConscript ('SConscriptClient', variant_dir=clientDir, exports=['clientEnv'] )
    

    SConscriptClient:

    Import('clientEnv')
    # You may want to clone the clientEnv here, if you want to make 
    # changes that you don't want seen in the rest of the build