I have SConscripts which recursively call SConscripts in all directories contained in the SConscript directory.
This does not work with variant builds as the entire source directory is not copied to the variant directory before evaluating the subsidiary SConscripts.
Example
.
├── 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)
All other 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')
Output
$ 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.
The src/a and src/b directories are not copied to build/a and build/b before calling build/SConscript. Hence, build/SConscript does not call the subsidiary SConscripts as those directories don't exist yet.
Output where the variant directory is removed from 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.
So is there a way to make SCons duplicate the source directory BEFORE running subsidiary SConscripts, or a way to make the subsidiary SConscripts refer to the source directory.
EDIT: I want to keep the dynamic generation of the list of directories. Hardcoding the directory names works, but that isn't a feasible solution as the number of directories that I have is huge and will keep changing.