如何强制Scons将输出(exe、obj、lib和dll)到特定的构建目录?

12

我一直在尝试让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'])
4个回答

10

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

谢谢,那个方法可行。虽然只有一个文件更加简洁,但我想我只能接受它! - Waldo Bronchart

9

仅使用一个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时,它将编译*.c文件从.\src并将生成的对象放入.\build
难怪他们将BuildDir重命名为VariantDir以尝试避免混淆(但没有太大成功)。

4

VariantDir(也在用户指南中有描述)告诉scons将生成的文件放置在单独的目录中。在早期版本的scons中,此功能称为BuildDir

您可能还想了解如何避免重复使用源目录(在用户指南和wiki上都有描述)。


1
是的,这就是我尝试过的:env.VariantDir('build', 'source', duplicate=0) env.Program('Hierarchy', source=['source/sconstest.cpp', 'source/utils/IntUtil.cpp'])可是这完全没有任何效果 :( - Waldo Bronchart
编译的文件不应该在源代码目录中,而是在构建目录中:env.Program('Hierarchy', source = ['build/sconstest.cpp', 'build/utils/IntUtil.cpp']) - Phong

1
我曾经使用过像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将在变体中填充源文件,然后也会在那里生成输出。当然,如果你要求变体目录不复制,则它不会将源文件复制到那里,但会在变体目录中生成输出文件。 - bdbaddog
啊哈,这样就有点意思了。谢谢你的提示! - Soleil

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接