【问题标题】:How to force Scons output (exe, obj, lib & dll) to specific build directory?如何强制 Scons 输出(exe、obj、lib 和 dll)到特定的构建目录?
【发布时间】:2010-09-15 17:28:02
【问题描述】:

我一直在尝试让 scons 将 exe、obj、lib 和 dll 文件输出到特定的构建目录。

我的文件结构如下:

/projectdir
  /build
    /bin
    /obj
  /source
    /subdirs
    /..
  SConstruct

基本上,我现在得到的是我的源目录被 obj 文件污染了。我宁愿把所有东西都放在一个地方。

SConstruct 文件如下所示:

env.VariantDir('build', 'source', duplicate = 0)
env.Program('Hierarchy', source = ['source/sconstest.cpp', 'source/utils/IntUtil.cpp'])

【问题讨论】:

    标签: scons


    【解决方案1】:

    我发现最简单的方法是使用 2 个文件,一个 SConstruct 文件和一个单独的 SConscript。

    在 SConstruct 中,您只需调用另一个文件并指定构建输出的目录:

    # content SConstruct
    SConscript('main.scons', variant_dir='build', duplicate=0)
    

    然后在 'main.scons' 中进行构建。您可以忘记此文件中的变体目录。

    # content of main.scons
    env = Environment()
    env.Program('Hierarchy',
                source = ['source/sconstest.cpp', 'source/utils/IntUtil.cpp'])
    

    【讨论】:

    • 谢谢,成功了。虽然只有一个文件更干净。我想我只能忍受它!
    【解决方案2】:

    仅使用一个 SConstruct 文件(对于小型项目)让 VariantDir 工作并不难,但非常令人困惑,因为一文件和两文件用例的配置不同.

    仅 SConstruct:

    env = Environment()
    env.VariantDir('build', 'src', duplicate=0)
    files = Glob('build\*.c')
    env.Program("build\program", files)
    

    请注意源文件如何位于.\src,但.\build 被指定为位置。输出也必须以.\build 为“前缀”,否则编译后的程序将驻留在 SConstruct 文件的目录中。

    当您执行脚本时,SCons 将从.\src 编译*.c 文件并将生成的对象放入.\build。

    难怪他们将 BuildDir 重命名为 VariantDir 以试图避免混淆(没有太大的成功)。

    【讨论】:

      【解决方案3】:

      VariantDir(也在user guide 中描述)告诉 scons 将生成的文件放在单独的目录中。在旧版本的 scons 中,这个函数被命名为BuildDir。

      您可能还想了解避免复制源目录(在用户指南和 wiki 中都有描述)。

      【讨论】:

      • 是的,这就是我尝试过的: env.VariantDir('build', 'source', duplicate = 0) env.Program('Hierarchy', source = ['source/sconstest.cpp', 'source/utils/IntUtil.cpp']) 这完全没有效果:(
      • 要编译的文件不应在源文件中,而应在构建文件夹中:env.Program('Hierarchy', source = ['build/sconstest.cpp', 'build/utils/IntUtil.cpp'])
      【解决方案4】:

      我使用的是像richq 的答案这样的双文件方法,但是虽然最终的构建产品(库、程序)进入了正确的变体目录,但目标文件仍然进入了源目录。

      解决方案原来是通过相对路径而不是绝对路径来全局化源文件。我不知道为什么。

      我的第二个 scons 文件最初看起来像这样。注意通过绝对路径进行通配 - 当我第一次写这篇文章时,我没有意识到路径会自动相对于 scons 文件。

      import os, inspect
      env = Environment()
      packageDir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
      src = Glob(os.path.join(packageDir, "src/*/*.c*"), strings=True, source=True)
      env.Program('Foo', source = src)
      

      这导致 *.obj 最终在 src/ 下,程序在我的变体目录下。当我将其更改为以下内容时,目标文件也转到了变体目录:

      env = Environment()
      src = Glob("src/*/*.c*", strings=True, source=True) 
      env.Program('Foo', source = src)
      

      使用绝对路径可能是一个新手错误——我对 scons 和 Python 都比较陌生——但我想我会分享它以防其他人遇到同样令人沮丧的问题。

      【讨论】:

      • 您的中间文件最终出现在源目录中的原因是您从那里请求它们。如果您从变体目录或相对目录中请求它们,则 SCons 将填充变体中的源,然后也在那里生成输出。 (当然,如果您要求变体目录不要复制,那么它不会在那里复制源代码,而是会在变体目录中生成输出文件)
      • 啊哈,这更有意义。谢谢你的线索!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多