Why does SCons VariantDir() not put output in the given directory?

Ben Hoyt picture Ben Hoyt · Jul 2, 2009 · Viewed 9.1k times · Source

I'm thinking about using SCons for a new project. It looks really good, though I'm finding VariantDir quite confusing.

I have a simple project with a handful of C source files in one directory, and I want to build in "normal" and in "profile" mode -- with two different sets of options to gcc. I want the outputs to go in the normal/ and profile/ directories, respectively.

For testing, I've cut back to just a single source file, t.c, which has a main() in it. My SConstruct file is in the same directory, and looks like this:

normal = DefaultEnvironment(tools=['mingw'], CCFLAGS = '-O2')
normal.VariantDir('release', '.', duplicate=0)
normal.Program('t', ['t.c'])

#profile = normal.Clone(CCFLAGS='-O2 -pg', LINKFLAGS = '-pg')
#profile.VariantDir('profile', '.', duplicate=0)
#profile.Program('t', ['t.c'])

When I run scons, I'm expecting it to put t.o and t.exe into release/, but it puts them in the current directory. And I can't run it at all with the 3 profile lines uncommented -- if I do, I get this error:

scons: *** Two environments with different actions were specified for the same target: t.o

Basically, I'm unsure why my VariantDir() calls aren't telling scons to put the output in the specified output directory, release.

(I've read a fair bit in the docs and newsgroups, but nothing that answers this question. The closest I've come is this page, which describes a similar thing, but it involves a separate src/ directory and two separate scons files, and importing/exporting variables between them. That doesn't seem pleasant.)

Answer

David Cournapeau picture David Cournapeau · Jul 2, 2009

Yes, VariantDir is confusing in scons. Although not well advertised, you can put both SConstruct and SConscript in the same directory, using the current directory as the source directory

# SConstruct
SConscript('SConscript', build_dir='build', src='.')

and

# SConscript
Program('main.c')

I have never found a way to avoid using two files while keeping my sanity trying to understand variant dir :)