2016-10-03 70 views
0

我有SConscripts遞歸地調用SConscript目錄中包含的所有目錄中的SConscripts。運行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. 

在調用build/SConscript之前,不會將src/a和src/b目錄複製到build/a和build/b。因此,build/SConscript不會調用子SConscripts,因爲這些目錄還不存在。

輸出,其中變異目錄從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指源目錄。


編輯:我想保留目錄列表的動態生成。對目錄名稱進行硬編碼是可行的,但這不是一個可行的解決方案,因爲我擁有的目錄數量巨大且將不斷變化。

+0

是,通過如第一章所描述以下的基本設置。 14「分層構建」和第二章。 15 [UserGuide](http://scons.org/doc/production/HTML/scons-user.html)中的「分離源代碼和構建目錄」。 – dirkbaechle

+0

@dirkbaechle SCons文檔中的示例不考慮使用os.listdir()動態生成子目錄的情況。隨着目錄數量的增加,對所有目錄名稱進行硬編碼並不是一個解決方案。 – user80551

+0

你在做什麼沒有什麼價值?爲什麼不只是讓頂級SConstruct遍歷目錄樹,並找到所有SConscript並調用它們,而不是遞歸。 – bdbaddog

回答

0

根據https://stackoverflow.com/a/29218216/2694385,SConscripts必須參考文件和文件夾,就好像它們已經在變體目錄中一樣,即使它們實際上不是。

源和變體目錄可以保存在環境中,每個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')