gpt4 book ai didi

SCons:使用分层构建分离调试/发布构建目录

转载 作者:行者123 更新时间:2023-12-05 00:03:03 24 4
gpt4 key购买 nike

我刚开始学习使用 SCons,希望它能解决我的一些问题。我正在创建一个源层次结构来了解 SCons 的基础知识。

让我们从这个文件夹结构开始:

  • test/foo: 包含 main.cpp, main.h
  • test/bar: 包含自己的 main.cpp, main.h
  • test/common:包含 foo 和 bar 使用的 utils.cpp 和 utils.h
  • test/external/moo:一些外部库的源代码,包含产生“Makefile”的“configure”(不使用SCons),所以SCons需要在“configure”之后调用“make”;我怀疑这部分在使用构建目录时可能会很棘手
  • 测试/构建/调试:用于调试的构建目录
  • 测试/构建/发布:发布的构建目录

  • 这是我想要做的:
  • 有两种类型的构建:调试/发布,其中唯一的区别是调试将 -DDEBUG 指定为 g++
  • 使用构建目录,以便在我的源代码树中不创建 .o 文件。让我们将这些构建目录称为“构建/调试”和“构建/发布”
  • 能够在另一个不使用 SCons 的项目上调用 ./configure 和 make,然后将它生成的 libmoo.a 链接到我的项目
  • 构建是否完全并行(8 核的 scons -j9?)
  • 有一些调试/发布无关的方式来指定要链接的库。就像是:
    env.Program(target='foo', source=['foo/main.cpp', '#build/(DEBUG_OR_RELEASE)/lib/libsomething.a'])

  • 执行上述操作的非常基本的 SConstruct/SConscript 文件是什么样的?即使只是指向正确方向的指针也会很棒!

    提前致谢 :-)

    最佳答案

    我为多个平台的构建(而不是调试/发布)执行此操作,但概念是相同的。基本思想是在项目根目录中需要 2 个文件 - 一个 SConstruct 来设置构建目录(或在 scons 中称为“变体目录”),然后是一个描述实际构建步骤的 SConscript。

    在 SConstruct 文件中,您将指定变体目录及其相应的源目录:

    SConscript(dirs='.',
    variant_dir=variant_dir,
    duplicate=False,
    exports="env")

    现在您希望 variant_dir 依赖于一个标志。您可以使用 AddOption 或 Variables 来执行此操作。这是一个完整的顶级 SConstruct 示例:
    # build with `scons --debug-build` for debug.
    AddOption(
    '--debug-build',
    action='store_true',
    help='debug build',
    default=False)

    env = Environment()

    if GetOption('debug_build'):
    env.ParseFlags('-DDEBUG')
    variant_dir = 'build/debug'
    else:
    variant_dir = 'build/release'

    SConscript(dirs='.',
    variant_dir=variant_dir,
    duplicate=False,
    exports="env")

    AddOption 最容易使用,但是如果您使用变量,那么您可以在运行之间缓存结果,而不必每次都拼出“scons --debug-build”。

    所有目录设置和相关的 cruft 都在 SConstruct 中。现在 SConscript 文件非常简单,根本不需要担心构建目录。
    Import('env')

    env.Program(target='foo_prog', source=['foo/main.cpp', 'lib/libmoo.a'])
    # foo_prog since foo already exists as the name of the directory...

    这是我发现的最简单的方法来设置不同的构建目录而不会出现奇怪的错误。它也非常灵活 - 您只需修改顶级脚本中的“env”即可添加不同的平台构建,而无需更改构建的实际内容。

    在您的问题中唯一起作用的是直接从 SCons 编译 autoconf 样式项目的方法。最简单的方法可能是使用几个 Command() 调用,但是 SCons 喜欢了解每个步骤的输入和输出,因此这可能会变得很棘手。此外,您必须依赖具有正确 VPATH 设置的 autoconf 构建 - 如果您尝试在源代码树之外进行编译,某些项目将不起作用。无论如何,编译 autoconf 项目的方法是这样的:
    import os
    Import('env')

    # get the path to the configure script from the "moo" source directory
    conf = env.File('moo/configure').srcnode().abspath

    # Create the "moo" build directory in the build dir
    build_dir = env.Dir('.').path
    moo_dir = os.path.join(build_dir, 'moo')
    Mkdir(moo_dir)

    # run configure from within the moo dir
    env.Command('moo/Makefile', 'moo/Makefile.am',
    conf, chdir=moo_dir)
    # run make in the moo dir
    env.Command('moo/libmoo.a', 'moo/Makefile',
    'make', chdir=moo_dir)

    env.Program(target='foo_prog', source=['foo/main.cpp', 'moo/libmoo.a'])

    当当前工作目录位于构建层次结构中的某个位置时,从源目录运行配置步骤很尴尬。 make 步骤不那么困惑,但仍然需要了解当前的构建目录。由于您将“libmoo.a”指定为 make 步骤的输出,将 libmoo.a 指定为程序的输入,因此所有依赖项都正常工作,因此并行构建工作正常。并行构建只会在您过多地捏造依赖关系时崩溃。

    关于SCons:使用分层构建分离调试/发布构建目录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7216617/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com