【问题标题】:Scons Explicit DependencyScons 显式依赖
【发布时间】:2015-05-13 21:53:10
【问题描述】:

我有一个简单的.cpp 文件,它依赖于jsoncpp。作为我构建过程的一部分,我希望 Scons 在尝试编译 app.cpp 之前解压缩 jsoncpp(如果还没有的话)并构建它(如果还没有的话),因为 app.cpp 依赖于一些 .h 文件被压缩在jsoncpp.tar.gz 内。

这是我迄今为止尝试过的:

env = Environment()
env.Program('app', 'app.cpp')
env.Depends('app.cpp', 'jsoncpp')

def build_jsoncpp(target, source, env):
    shutil.rmtree("jsoncpp", ignore_errors=True)
    mytar = tarfile.open(str(source[0]))
    mytar.extractall()
    print("Extracted jsoncpp")

env.Command("jsoncpp", ['jsoncpp.tar.gz'], build_jsoncpp)

但是,Scons 从不打印“Extracted jsoncpp”...它总是尝试编译 app.cpp,然后立即失败。

如果我使用make,我可以简单地执行以下操作:

app: jsoncpp.tar.gz
    # Build app

jsoncpp.tar.gz:
    # Extract and build here

而且订单会得到保证。

【问题讨论】:

    标签: scons


    【解决方案1】:

    您应该查看UnTarBuilder,作为提取 tar 文件并将所有提取的文件正确插入依赖关系树的方法。但是以下内容将得到您的工作。

    如果可能,您希望避免显式依赖。 SCons 的众多乐趣之一就是让它为您处理依赖关系。因此,只需将您所依赖的源文件列为 untar 命令构建器的目标之一。

    为了测试这一点,我创建了一个名为 jsoncpp.tar.gz 的 tar 文件,其中仅包含一个文件 app.cpp,其内容如下。

    #include <iostream>
    int main() {
        std::cout << "Hello World" << std::endl;
        return 0;
    }
    

    并将您的 SConstruct 更新为以下内容。

    import shutil
    import tarfile
    
    env = Environment()
    env.Program('app', 'app.cpp')
    
    def build_jsoncpp(target, source, env):
        shutil.rmtree("jsoncpp", ignore_errors=True)
        mytar = tarfile.open(str(source[0]))
        mytar.extractall()
        print("Extracted jsoncpp")
    
    env.Command(["app.cpp"], ['jsoncpp.tar.gz'], build_jsoncpp)
    

    因为您列出了您所依赖的所需源文件作为命令生成器的目标,所以它将为您处理依赖项。

    当你运行时,你会看到以下内容。

    >> scons --version
    SCons by Steven Knight et al.:
        script: v2.3.4, 2014/09/27 12:51:43, by garyo on lubuntu
        engine: v2.3.4, 2014/09/27 12:51:43, by garyo on lubuntu
        engine path: ['/usr/lib/scons/SCons']
    Copyright (c) 2001 - 2014 The SCons Foundation
    
    >> tree
    .
    ├── jsoncpp.tar.gz
    └── SConstruct
    
    0 directories, 2 files
    
    >> scons
    scons: Reading SConscript files ...
    scons: done reading SConscript files.
    scons: Building targets ...
    build_jsoncpp(["app.cpp"], ["jsoncpp.tar.gz"])
    Extracted jsoncpp
    g++ -o app.o -c app.cpp
    g++ -o app app.o
    scons: done building targets.
    
    >> tree
    .
    ├── app
    ├── app.cpp
    ├── app.o
    ├── jsoncpp.tar.gz
    └── SConstruct
    
    0 directories, 5 files
    
    >> ./app
    Hello World
    

    您的代码不起作用的原因是因为您将 jsoncpp 列为 untar 命令构建器的目标。编译 app.cpp 不会依赖哪个文件,即使您将该操作列为显式依赖项。

    虽然这不能完全回答您的问题,但我希望它为您想要完成的任务提供解决方案。

    【讨论】:

    • 谢谢,这正是我想要的。 Scons 对构建过程的思考方式与 Make 略有不同,所以我很感激这篇文章能够为我澄清一点。
    • “您将 jsoncpp 列为 untar 命令构建器的目标。即使您将该操作列为显式依赖项,它也不是编译 app.cpp 所依赖的文件。”这不正是 Depends 的用途吗?然而,我看到了同样的行为,但令人沮丧的是 scons 文档显然是错误的,并且 Depends 不能像宣传的那样工作
    【解决方案2】:

    如果您将构建器函数的名称与 Command() 方法的参数对齐,这可能会有所帮助。 ;)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多