我有时想要从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)
但这很丑陋,如果要过滤掉多个文件,那就更加丑陋了.
有更明确的方法吗?
我厌倦了[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参数而不是简单的文件名列表,但这适用于我当前的需求.