Scons 显式依赖

Scons Explicit Dependency

我有一个简单的 .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

并且保证顺序。

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

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

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

为了测试这一点,我创建了一个名为 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)

因为您将依赖的所需源文件列为命令生成器的 target,它会为您处理依赖项。

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

>> 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 命令生成器的 target。这不是编译 app.cpp 将依赖的文件,即使您将该操作列为显式依赖项也是如此。

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