【问题标题】:scons error using Glob in SConscript在 SConscript 中使用 Glob 的 scons 错误
【发布时间】:2015-01-05 22:14:27
【问题描述】:

我遇到了一个相当奇怪的错误,涉及在 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 调用时,这会显示上面显示的错误消息。

【问题讨论】:

  • 您没有显示 SConstruct 和 SConscript 的全部内容,因此这不是一个完整的示例。没有看到干净的 MWE,很难给出干净的解决方案。 ;)
  • 我很抱歉,因为我认为通过将其浓缩为错误的工作示例,更容易诊断。我将编辑该帖子,并提供有关我要完成的工作的更多详细信息。
  • 您的源文件夹或顶级文件夹中是否有“build.cc”文件?
  • 没有,没有。顶级文件夹包含 SConstruct、SConscript、Program.cc、src/subroutine.cc 和 include/subroutine.hh。对“build”的引用似乎来自作为 variant_dir 传入的目录。

标签: scons


【解决方案1】:

您的问题是您正在使用 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 连续三次在系统中搜索编译器/工具...只需执行一次,然后 clone() 到不同的环境并使用您的构建特定设置进一步装饰它们。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-09
    • 1970-01-01
    • 2020-12-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多