7

我使用了 scons 几天,有点困惑。为什么没有用于从给定根目录开始递归构建源代码的内置工具?让我解释一下:我有这样的来源处置:

src
    Core
       folder1
       folder2
           subfolder2_1
    Std
       folder1

..等等。这棵树可能更深。

现在我用这样的结构来建造它:

sources = Glob('./builds/Std/*/*.cpp')
sources = sources + Glob('./builds/Std/*.cpp')
sources = sources + Glob('./builds/Std/*/*/*.cpp')
sources = sources + Glob('./builds/Std/*/*/*/*.cpp')

这看起来并不完美。当然,我可以编写一些 python 代码,但是有更合适的方法吗?

4

4 回答 4

10

正如 Torsten 已经说过的,SCons 中没有“内部”递归 Glob()。你需要自己写一些东西。我的解决方案是:

import fnmatch
import os

matches = []
for root, dirnames, filenames in os.walk('src'):
  for filename in fnmatch.filter(filenames, '*.c'):
    matches.append(Glob(os.path.join(root, filename)[len(root)+1:]))

我想强调你在这里需要 Glob()(不是来自 python 的 glob.glob()),尤其是当你使用 VariantDir() 时。此外,当您使用 VariantDir() 时,不要忘记将绝对路径转换为相对路径(在示例中,我使用 [len(root)+1:] 实现了这一点)。

于 2012-06-15T17:50:08.077 回答
6

当然。您需要编写 python 包装器来遍历目录。你可以在 stackoverflow 上找到很多食谱。这是我的简单函数,它返回当前目录中的子目录列表(并忽略以“。”开头的隐藏目录 - 点)

def getSubdirs(abs_path_dir) :  
    lst = [ name for name in os.listdir(abs_path_dir) if os.path.isdir(os.path.join(abs_path_dir, name)) and name[0] != '.' ]
    lst.sort()
    return lst

例如,我有包含 foo、bar、ice 的 dir 模块。

corePath = 'abs/path/to/modules'
modules = getSubdirs(corePath)
# modules = [bar, foo, ice]
for module in modules :
  sources += Glob(os.path.join(corePath, module, '*.cpp'))

您可以改进 getSubdirs 函数,添加递归并深入到子目录。

于 2012-05-17T08:29:52.160 回答
2

Glob() SCons 函数没有递归的能力。

如果您将 Python 代码更改为使用 list.extend() 函数,效率会更高,如下所示:

sources = Glob('./builds/Std/*/*.cpp')
sources.extend(Glob('./builds/Std/*.cpp'))
sources.extend(Glob('./builds/Std/*/*/*.cpp'))
sources.extend(Glob('./builds/Std/*/*/*/*.cpp'))

与其像您一样尝试递归,而是在每个子目录中都有一个 SConscript 脚本,并在根 SConstruct 中使用 SConscript() 函数调用它们中的每一个,这很常见。这称为SCons 分层构建

于 2012-05-15T11:43:18.230 回答
1

我用这个:

srcdir = './'
sources = [s for s in glob2.glob(srcdir + '**/*.cpp') if "/." not in s]
于 2019-10-23T17:30:43.040 回答