如何过滤SCons Glob结果?

Tim*_*ick 3 scons

我有时想要从SCon中的Glob结果中排除某些源文件.通常是因为我想用不同的选项编译该源文件.像这样的东西:

objs = env.Object(Glob('*.cc'))
objs += env.Object('SpeciallyTreatedFile.cc', CXXFLAGS='-O0')
Run Code Online (Sandbox Code Playgroud)

当然,这会给SCons带来问题:

scons: *** Two environments with different actions were specified
       for the same target: SpeciallyTreatedFile.o
Run Code Online (Sandbox Code Playgroud)

我通常使用以下习语解决这个问题:

objs = env.Object([f for f in Glob('*.cc')
  if 'SpeciallyTreatedFile.cc' not in f.path])
Run Code Online (Sandbox Code Playgroud)

但这很丑陋,如果要过滤掉多个文件,那就更加丑陋了.

有更明确的方法吗?

Tim*_*ick 7

我厌倦了[f for f in Glob ...]在几个地方复制表达式,所以我编写了以下帮助器方法并将其添加到构建环境中:

import os.path

def filtered_glob(env, pattern, omit=[],
  ondisk=True, source=False, strings=False):
    return filter(
      lambda f: os.path.basename(f.path) not in omit,
      env.Glob(pattern))

env.AddMethod(filtered_glob, "FilteredGlob");
Run Code Online (Sandbox Code Playgroud)

现在我可以写

objs = env.Object(env.FilteredGlob('*.cc',
  ['SpeciallyTreatedFile.cc', 'SomeFileToIgnore.cc']))
objs += env.Object('SpeciallyTreatedFile.cc', CXXFLAGS='-O0')
Run Code Online (Sandbox Code Playgroud)

使用这种模式很容易编写类似的东西,例如使用正则表达式过滤器作为omit参数而不是简单的文件名列表,但这适用于我当前的需求.