Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to force Scons output (exe, obj, lib & dll) to specific build directory?

Tags:

scons

I've been trying to get scons to output exe, obj, lib and dll files to a specific build directory.

My file structure looks like this:

/projectdir
  /build
    /bin
    /obj
  /source
    /subdirs
    /..
  SConstruct

Basically, what I get now is my source directory is getting polluted with obj files. I'd rather have it all in one place.

The SConstruct file looks like this:

env.VariantDir('build', 'source', duplicate = 0)
env.Program('Hierarchy', source = ['source/sconstest.cpp', 'source/utils/IntUtil.cpp'])
like image 652
Waldo Bronchart Avatar asked Sep 15 '10 17:09

Waldo Bronchart


4 Answers

It's not that tough to get VariantDir working using only one SConstruct file (for a small project), but it's very confusing as the configuration is different for the one-file and two-file use case.

Only SConstruct:

env = Environment()
env.VariantDir('build', 'src', duplicate=0)
files = Glob('build\*.c')
env.Program("build\program", files)

Notice how the source files are located in .\src but .\build is specified as the location. The output has to be also "prefixed" with .\build otherwise the compiled program will reside in the directory of the SConstruct file.

When you execute the script SCons will compile the *.c files from .\src and put the resulting objects to .\build.

No wonder they renamed BuildDir to VariantDir to try to avoid the confusion (without much success).

like image 95
AMilassin Avatar answered Nov 07 '22 03:11

AMilassin


The easiest way I've found is to use 2 files, a SConstruct file and a separate SConscript.

In the SConstruct you simply call the other file and specify the directory for the build output:

# content SConstruct
SConscript('main.scons', variant_dir='build', duplicate=0)

Then in 'main.scons' you do the meat of your build. You can forget about variant directories in this file.

# content of main.scons
env = Environment()
env.Program('Hierarchy',
            source = ['source/sconstest.cpp', 'source/utils/IntUtil.cpp'])
like image 20
richq Avatar answered Nov 07 '22 04:11

richq


The VariantDir (also described in the user guide) tells scons to put generated files in a separate directory. In older versions of scons this function was named BuildDir.

You may also want to read up on avoiding duplicating the source directory (described both in the user guide and on the wiki).

like image 3
Dave Bacher Avatar answered Nov 07 '22 04:11

Dave Bacher


I was using a two-file method like richq's answer, but although the final build products (libs, programs) were going into the right variant directory, the object files were still going to the source directory.

The solution turned out to be to glob the source files by relative path instead of absolute. I have no idea why.

My second scons file originally looked like this. Note globbing by absolute path - when I first wrote this I didn't realize paths would automatically be relative to the scons file.

import os, inspect
env = Environment()
packageDir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
src = Glob(os.path.join(packageDir, "src/*/*.c*"), strings=True, source=True)
env.Program('Foo', source = src)

And that resulted in *.obj ending up under src/ and the program under my variant dir. When I changed it to the following, the object files also went to the variant dir:

env = Environment()
src = Glob("src/*/*.c*", strings=True, source=True) 
env.Program('Foo', source = src)

Using absolute paths is probably a noob mistake - I'm relatively new to both scons and Python - but I thought I'd share it in case anyone else has the same frustrating problem.

like image 1
Soleil Avatar answered Nov 07 '22 04:11

Soleil