4

Pythonの環境でどのように再帰的にすることができGlob()ますか?VariantDir()

質問からの答え< Pythonで再帰的にファイルを見つけるためにGlob()を使用しますか?>環境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)

これは機能しますか?

4

2 に答える 2

4

受け入れられた答えは、ソースディレクトリがである場合にのみ機能すると思います'.'

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でテストされました。

なぜそれが機能するのか

バリアントディレクトリを使用してビルドする場合は、ソースへのパスを、それがすでにバリアントディレクトリにあるかのように指定する必要がありますが、それらのディレクトリはまだ存在していない可能性があります。このglob関数は、ソースツリーをウォークして、バリアントディレクトリにあるパスを作成し、それらのパスに対してグロブします

于 2015-03-23T18:57:49.733 に答える
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

「strings」パラメーターがfalseの場合、SCons Glob()関数はノードを返すため、これをFile()に変換したことに注意してください。

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
于 2012-06-18T14:48:37.453 に答える