Scons 如何强制SCON输出(exe、obj、lib和dll)到特定的生成目录?

Scons 如何强制SCON输出(exe、obj、lib和dll)到特定的生成目录?,scons,Scons,我一直在尝试让SCON将exe、obj、lib和dll文件输出到特定的构建目录 我的文件结构如下所示: /projectdir /build /bin /obj /source /subdirs /.. SConstruct env.VariantDir('build', 'source', duplicate = 0) env.Program('Hierarchy', source = ['source/sconstest.cpp', 'sourc

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

我的文件结构如下所示:

/projectdir
  /build
    /bin
    /obj
  /source
    /subdirs
    /..
  SConstruct
env.VariantDir('build', 'source', duplicate = 0)
env.Program('Hierarchy', source = ['source/sconstest.cpp', 'source/utils/IntUtil.cpp'])
基本上,我现在得到的是我的源目录被obj文件污染了。我宁愿把一切都放在一个地方

SConstruct文件如下所示:

/projectdir
  /build
    /bin
    /obj
  /source
    /subdirs
    /..
  SConstruct
env.VariantDir('build', 'source', duplicate = 0)
env.Program('Hierarchy', source = ['source/sconstest.cpp', 'source/utils/IntUtil.cpp'])
通知SCON将生成的文件放在单独的目录中。在旧版本的scons中,此函数名为
BuildDir


您可能还需要阅读避免复制源目录的相关内容(在《用户指南》和wiki中都有介绍)。

我发现的最简单的方法是使用两个文件,一个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'])

仅使用一个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以避免混淆(没有太大成功)。

我使用了一种类似richq的答案的两文件方法,但尽管最终的构建产品(lib、程序)将进入正确的变体目录,但目标文件仍将进入源目录

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

我的第二个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/下结束,程序在我的variant dir下结束。当我将其更改为以下内容时,对象文件也转到variant dir:

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

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

是的,这就是我所尝试的: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'])
谢谢,这很管用。尽管只有一个文件更干净。我想我只能接受它了!中间文件出现在源目录中的原因是因为您从那里请求它们。如果您从variant dir或relative dir请求它们,那么SCons将在variant目录中填充源文件nt,然后在那里生成输出。(当然,如果你要求variant dir不复制,那么它不会在那里复制源,而是在variant dir中生成输出文件)啊哈,这更有意义。谢谢你的提示!