2016-10-03 10 views
0

私は、SConscriptディレクトリに含まれるすべてのディレクトリでSConscriptを再帰的に呼び出すSConscriptを持っています。SConscriptを実行する前に重複したバリアントディレクトリ

補助SConscriptを評価する前に、ソースディレクトリ全体がバリアントディレクトリにコピーされないため、これはバリアントビルドでは機能しません。

. 
├── SConstruct 
└── src 
    ├── a 
    │   ├── a.c 
    │   ├── a.h 
    │   ├── SConscript 
    │   ├── x 
    │   │   ├── ax.h 
    │   │   └── SConscript 
    │   └── y 
    │    ├── ay.h 
    │    └── SConscript 
    ├── b 
    │   ├── b.c 
    │   ├── b.h 
    │   ├── SConscript 
    │   ├── x 
    │   │   ├── bx.h 
    │   │   └── SConscript 
    │   └── y 
    │    ├── by.h 
    │    └── SConscript 
    ├── main.c 
    └── SConscript 

SConstruct

env = Environment() 
objects = SConscript('src/SConscript', exports=['env'], variant_dir='build') 
objects = [x for x in env.Flatten(objects) if x is not None] 
program = env.Program(target='prog', source=objects) 

他のすべてのSConscripts

import os 

Import('env') 
env.AppendUnique(CPPPATH=[Dir('.')]) 
objects = SConscript(
    dirs=[name for name in os.listdir('.') 
      if os.path.isdir(os.path.join('.', name))], 
    exports=['env']) 
objects = objects + env.Object(env.Glob('*.c')) 
Return('objects') 

出力

$ scons . --tree=all 
scons: Reading SConscript files ... 
scons: done reading SConscript files. 
scons: Building targets ... 
gcc -o build/main.o -c -Ibuild build/main.c 
build/main.c:1:15: fatal error: a.h: No such file or directory 
compilation terminated. 
scons: *** [build/main.o] Error 1 
+-. 
    +-SConstruct 
    +-build 
    | +-build/SConscript 
    | +-build/main.c 
    | +-build/main.o 
    | +-build/main.c 
    | +-/usr/bin/gcc 
    +-prog 
    | +-build/main.o 
    | | +-build/main.c 
    | | +-/usr/bin/gcc 
    | +-/usr/bin/gcc 
    +-src 
    +-src/SConscript 
    +-src/main.c 
scons: building terminated because of errors. 

ビルド/ SConscriptを呼び出す前にsrc/aとsrc/bディレクトリはビルド/ aとビルド/ bにコピーされません。したがって、build/SConscriptは、それらのディレクトリがまだ存在しないため、補助SConscriptを呼び出さない。バリアントディレクトリがSConstruct

から削除され

出力

$ scons --tree=all 
scons: Reading SConscript files ... 
scons: done reading SConscript files. 
scons: Building targets ... 
gcc -o src/b/b.o -c -Isrc -Isrc/b -Isrc/b/x -Isrc/b/y -Isrc/a -Isrc/a/x -Isrc/a/y src/b/b.c 
gcc -o src/a/a.o -c -Isrc -Isrc/b -Isrc/b/x -Isrc/b/y -Isrc/a -Isrc/a/x -Isrc/a/y src/a/a.c 
gcc -o src/main.o -c -Isrc -Isrc/b -Isrc/b/x -Isrc/b/y -Isrc/a -Isrc/a/x -Isrc/a/y src/main.c 
gcc -o prog src/b/b.o src/a/a.o src/main.o 
+-. 
    +-SConstruct 
    +-prog 
    | +-src/b/b.o 
    | | +-src/b/b.c 
    | | +-src/b/b.h 
    | | +-src/b/x/bx.h 
    | | +-src/b/y/by.h 
    | | +-/usr/bin/gcc 
    | +-src/a/a.o 
    | | +-src/a/a.c 
    | | +-src/a/a.h 
    | | +-src/a/x/ax.h 
    | | +-src/a/y/ay.h 
    | | +-/usr/bin/gcc 
    | +-src/main.o 
    | | +-src/main.c 
    | | +-src/a/a.h 
    | | +-src/b/b.h 
    | | +-/usr/bin/gcc 
    | +-/usr/bin/gcc 
    +-src 
    +-src/SConscript 
    +-src/a 
    | +-src/a/SConscript 
    | +-src/a/a.c 
    | +-src/a/a.h 
    | +-src/a/a.o 
    | | +-src/a/a.c 
    | | +-src/a/a.h 
    | | +-src/a/x/ax.h 
    | | +-src/a/y/ay.h 
    | | +-/usr/bin/gcc 
    | +-src/a/x 
    | | +-src/a/x/SConscript 
    | | +-src/a/x/ax.h 
    | +-src/a/y 
    | +-src/a/y/SConscript 
    | +-src/a/y/ay.h 
    +-src/b 
    | +-src/b/SConscript 
    | +-src/b/b.c 
    | +-src/b/b.h 
    | +-src/b/b.o 
    | | +-src/b/b.c 
    | | +-src/b/b.h 
    | | +-src/b/x/bx.h 
    | | +-src/b/y/by.h 
    | | +-/usr/bin/gcc 
    | +-src/b/x 
    | | +-src/b/x/SConscript 
    | | +-src/b/x/bx.h 
    | +-src/b/y 
    | +-src/b/y/SConscript 
    | +-src/b/y/by.h 
    +-src/main.c 
    +-src/main.o 
     +-src/main.c 
     +-src/a/a.h 
     +-src/b/b.h 
     +-/usr/bin/gcc 
scons: done building targets. 

だから、SConsは子会社SConscriptsを実行する前にソースディレクトリを複製作るための方法、または子会社のSConscriptsは、ソースディレクトリを参照して作成する方法があります。


EDIT:ディレクトリのリストを動的に生成したいと思います。ディレクトリ名のハードコーディングは機能しますが、これは実現可能な解決策ではありません。

+0

はい、あります。 14「階層的ビルド」とチャップ15 [UserGuide](http://scons.org/doc/production/HTML/scons-user.html)の「ソースとビルドディレクトリの分離」 – dirkbaechle

+0

@dirkbaechle SConsのドキュメントの例では、os.listdir()を使用して補助ディレクトリを動的に生成する場合は考慮されていません。すべてのディレクトリ名をハードコードすることは、ディレクトリの数が増えるほど解決策ではありません。 – user80551

+0

あなたがやっていることをする上で、価値はほとんどありません。なぜトップレベルのSConstructにディレクトリツリーを移動させて、すべてのSConスクリプトを見つけて呼び出すのではなく、再帰的に呼び出すのではないでしょうか。 – bdbaddog

答えて

0

https://stackoverflow.com/a/29218216/2694385に基づいて、SConscriptはファイルとフォルダを、実際には存在しないにもかかわらずバリアントディレクトリにあるかのように参照する必要があります。

ソースとバリアントのディレクトリは環境に保存でき、各SConscriptは対応するソースディレクトリへのパスを(バリアントディレクトリの深さに基づいて)見つけることができます。

変更されたファイルは

SConstruct

import os 

env = Environment() 
env['VARIANT_DIR'] = Dir("build") 
env['SOURCE_DIR'] = Dir("src") 
objects = SConscript(os.path.join(env['SOURCE_DIR'].path, 'SConscript'), 
        exports=['env'], 
        variant_dir=env['VARIANT_DIR']) 
objects = [x for x in env.Flatten(objects) if x is not None] 
program = env.Program(target='prog', source=objects) 

やつで説明したように、基本的な設定を以下の全てのSConscripts

import os 

Import('env') 
env.AppendUnique(CPPPATH=[Dir('.')]) 

dir_depth_from_variant = env['VARIANT_DIR'].rel_path(Dir('.')) 
corresponding_src_dir = os.path.join(Dir('.').rel_path(env['SOURCE_DIR']), 
            dir_depth_from_variant) 
dirs = [name for name in os.listdir(corresponding_src_dir) 
     if os.path.isdir(os.path.join(corresponding_src_dir, name))] 
objects = SConscript(
    dirs=dirs, 
    exports=['env']) 
objects = objects + env.Object(env.Glob('*.c')) 
Return('objects') 
関連する問題