在SConscript中使用Glob的scons错误

时间:2015-01-05 22:14:27

标签: scons

我遇到了一个相当奇怪的错误,涉及在SConscript中使用scons函数Glob。我的实际构建脚本更复杂,但我已将其缩小到以下最小的示例。

在基础SConstruct中:

SConscript('SConscript',
           variant_dir='build')

然后,在SConscript中:

Glob('*.cc')

退出,出现错误消息TypeError : Tried to lookup Dir 'build' as a File.已经使用v2.1.0和v2.3.0进行了测试。

我找到了许多解决方法,其中没有一个是完全令人满意的。

  • 如果我将SConscript移动到子目录,则scons运行时没有错误。但是,那将需要将我的整个src树移动到一个子目录,这会感觉很乱。
  • 如果我在运行scons之前创建目录build,则scons运行时没有错误。但是,这需要一个额外的步骤,并且空目录不能很好地与git一起使用。
  • 我可以在调用SConscript之前添加一行Execute(Mkdir('build'))。但是,使用scons -n执行干运行时,这不起作用。
  • 我可以使用duplicate=False调用SConscript,以防止出错。但是,据我了解文档,这可能会导致构建错误,具体取决于包含文件的位置。

我摸索着,并没有真正了解问题的根本原因。这个问题有一个干净的解决方案吗?

编辑:有人要求我添加我的意图的其他详细信息,而不仅仅是导致错误消息的代码。我正在尝试制作一个构建文件,用于同时交叉编译linux可执行文件和Windows可执行文件。

首先,在SConstruct中设置编译环境。

import os

win32 = Environment()
win64 = Environment()
linux = Environment()

#Define the working directory
win32['SYS'] = 'win32'
win64['SYS'] = 'win64'
linux['SYS'] = 'linux'

#Define the compilers
win32.Replace(CXX='i686-w64-mingw32-g++')
win64.Replace(CXX='x86_64-w64-mingw32-g++')

#Define the appropriate file formats
win32.Replace(SHLIBPREFIX='')
win32.Replace(SHLIBSUFFIX='.dll')
win32.Replace(PROGSUFFIX='.exe')
win32.Append(LINKFLAGS='-static')
win64.Replace(SHLIBPREFIX='')
win64.Replace(SHLIBSUFFIX='.dll')
win64.Replace(PROGSUFFIX='.exe')
win64.Append(LINKFLAGS='-static')

for env in [win32,win64,linux]:
    build_dir = os.path.join('build',env['SYS'])
    exe = SConscript('SConscript',
                     variant_dir=build_dir,
                     exports=['env'])

然后,在SConscript中使用实际的构建规则。

Import('env')

env.Append(CPPPATH=['include'])

for main in Glob('*.cc'):
    env.Program([main, Glob('src/*.cc')])

使用scons -n调用时,会显示上面显示的错误消息。

1 个答案:

答案 0 :(得分:2)

您的问题是您正在使用variant_dir来"链接"你的构建文件夹到"。"作为您的源目录。结合默认值" duplicate = 1"选项,这意味着SCons尝试将所有源复制到" build" ...但后者也是源文件夹的一部分。这为各种并发症和循环依赖打开了大门。

干净的解决方案是将所有资源放入他们自己的子目录中,例如: " src",这样您就可以将包含的SConscript引用为

  SConscript('src/SConscript', variant_dir='build')

这将使正确的事情发生。这是首选的设置,即使你不喜欢这个约定,你仍然应该采用它,以免你将来的头痛。

附加提示:您可以(并且应该)使用

节省一些启动时间
win32 = Environment()
win64 = win32.Clone()
linux = win32.Clone()

而不是

win32 = Environment()
win64 = Environment()
linux = Environment()

。在后一种情况下,您强制SCons连续三次在系统中搜索编译器/工具...只需执行一次,然后克隆()到不同的环境并使用特定于构建的设置进一步装饰它们