我有SConscripts,它在SConscript目录中包含的所有目录中递归调用SConscripts。
这不适用于变体构建,因为在评估子SConscripts之前,不会将整个源目录复制到variant目录。
实施例
.
├── 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中删除variant目录的输出
$ 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 :(得分: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')