如何在Python的Glob()
环境中进行递归VariantDir()
?
问题的答案< Use a Glob() to find files recursively in Python?>不起作用,因为您需要使用Glob()
来获取知道VariantDir()
环境的文件列表。
所以你需要这样的东西:
import fnmatch
import os
matches = []
for root, dirnames, filenames in os.walk('src'):
for filename in fnmatch.filter(filenames, '*.c'):
matches.append(os.path.join(root, filename))
matches = Glob(matches)
这会有用吗?
答案 0 :(得分:2)
我相信只有在您的源目录为'.'
时才能使用已接受的答案。
以下是一个工作示例,其中源目录为src
,变体目录为build
。
.
├── include
│ └── sum.h
├── SConstruct
└── src
├── dir
│ └── sum.cpp
└── main.cpp
sum.h
#ifndef _SUM_H_
#define _SUM_H_
double sum(const double x, const double y);
#endif
的main.cpp
#include <iostream>
#include <sum.h>
using namespace std;
int main() {
cout << "Sum of 1 and 2 = " << sum(1., 2.) << endl;
return 0;
}
sum.cpp
#include <sum.h>
double sum(const double x, const double y) {
return x + y;
}
SConstruct
import os
def variantglob(env, pattern, ondisk=True, source=True, strings=False,
recursive=False):
matches = []
for root, dirs, filenames in os.walk(env['SOURCE_DIR']):
cwd = Dir(os.path.join(env['VARIANT_DIR'],
os.path.relpath(root, env['SOURCE_DIR'])))
matches.extend(cwd.glob(pattern, ondisk, source, strings))
return matches
# Create Build Environment
env = Environment()
# Customize Environment
env.Replace(VARIANT_DIR='build',
SOURCE_DIR='src')
env.Append(CPPPATH=['include'])
# Setup Variant Directory
VariantDir(variant_dir=env['VARIANT_DIR'],
src_dir=env['SOURCE_DIR'], duplicate=0)
# Build the executable
exe = env.Program(os.path.join(env['VARIANT_DIR'], 'example'),
variantglob(env, '*.cpp', recursive=True))
# Install the executable
Install('bin', exe)
只需在顶级目录中执行scons
即可。这将创建一个build
目录并删除所有临时目录(变体目录),然后将构建结果安装到bin文件夹中。
执行bin/example
以查看是否有效。
这个例子在linux上测试过。
使用variant目录构建时,您必须指定源路径,就好像它已经位于variant目录中一样,但这些目录可能不存在 yet 。这个glob函数遍历源树,构造将位于变体目录中的路径,然后对这些路径进行全局化。
答案 1 :(得分:1)
您的方法可以通过以下方式进行微调:
import fnmatch
import os
def RecursiveGlob(pathname)
matches = []
for root, dirnames, filenames in os.walk(pathname):
for filename in fnmatch.filter(filenames, '*.c'):
matches.append(File(os.path.join(root, filename)))
return matches
请注意,我将其转换为File(),因为如果“strings”参数为false,SCons Glob()函数将返回Nodes。
为了能够处理VariantDir等并更好地将功能与现有的SCons Glob()功能集成,您实际上可以对现有的Glob()函数进行调用,如下所示:
# Notice the signature is similar to the SCons Glob() signature,
# look at scons-2.1.0/engine/SCons/Node/FS.py line 1403
def RecursiveGlob(pattern, ondisk=True, source=True, strings=False):
matches = []
# Instead of using os.getcwd() consider passing-in a path
for root, dirnames, filenames in os.walk(os.getcwd()):
cwd = Dir(root)
# Glob() returns a list, so using extend() instead of append()
# The cwd param isnt documented, (look at the code) but its
# how you tell SCons what directory to look in.
matches.extend(Glob(pattern, ondisk, source, strings, cwd))
return matches
您可以更进一步,并执行以下操作:
def MyGlob(pattern, ondisk=True, source=True, strings=False, recursive=False):
if not recursive:
return Glob(pattern, ondisk, source, strings)
matches = []
# Instead of using os.getcwd() consider passing-in a path
for root, dirnames, filenames in os.walk(os.getcwd()):
cwd = Dir(root)
# Glob() returns a list, so using extend() instead of append()
# The cwd param isnt documented, (look at the code) but its
# how you tell SCons what directory to look in.
matches.extend(Glob(pattern, ondisk, source, strings, cwd))
return matches