It's often useful to keep any built files completely separate from the source files. Consider if you have a project to build software for a variety of different controller hardware. The boards are able to share a lot of code, so it makes sense to keep them in the same source tree, but certain build options in the source code and header files differ. If you build "Controller A" first, then "Controller B", on the second build everything would have to be rebuilt, because SCons sees that the build instructions differ, and thus the targets that depend on those different instructions are not valid for the current build. Now when you go back and build for "Controller A", things have to be rebuilt from scratch again for the same reason. However, if you can separate the places the output files go, this problem can be avoided. You can even set up to do both builds in one invocation of SCons.
You can enable this separation by creating one or more
variant directory trees
that are used to hold the built objects files, libraries,
and executable programs, etc.
for a specific flavor, or variant, of build.
SCons provides two ways to do this,
one through the SConscript
function that we've already seen,
and the second through a more flexible VariantDir
function.
Historical note: the VariantDir
function
used to be called BuildDir
, a name which was
removed because the SCons functionality
differs from a familiar model of a "build directory"
implemented by other build systems like GNU Autotools.
You might still find references to the old name on
the Internet in postings about SCons, but it no longer works.
The most straightforward way to establish a variant directory tree
relies the fact that the usual way to
set up a build hierarchy is to have an
SConscript file in the source subdirectory.
If you pass a variant_dir
argument to the
SConscript
function call:
SConscript('src/SConscript', variant_dir='build')
SCons will then build all of the files in
the build
subdirectory:
%ls src
SConscript hello.c %scons -Q
cc -o build/hello.o -c build/hello.c cc -o build/hello build/hello.o %ls src
SConscript hello.c %ls build
SConscript hello hello.c hello.o
No files were built in src
, they went to build
.
The build output might show a bit of a surprise:
the object file
build/hello.o
and the executable file
build/hello
were built in the build
subdirectory,
as expected.
But even though our hello.c
file lives in the src
subdirectory,
SCons has actually compiled a
build/hello.c
file
to create the object file,
and that file is now seen in build
.
What's happened is that SCons has duplicated
the hello.c
file from the src
subdirectory
to the build
subdirectory,
and built the program from there (it also duplicated SConscript
).
The next section explains why SCons does this.