user19425295
user19425295

Reputation: 1

SCons build object files in source folders, rather have them in "build" folder

I'm very new to SCons and working on a project, where I am supposed to implement SCons. The directory layout is like this:

Now when I run the SCons, it builds all the *.o files in all the subfoldrs, I'd rather have it build them in the "build" folder.

SConstruct looks like this:

...
...
SConscript('SConscript_Main', variant_dir='build/temp', src_dir='.', duplicate=0, exports='env')

SConscript_Main looks like this:

import ...
directory = str(Dir('#')
obj = []
libraries = []
list = os.listdir(directory)
...
...

def SConscript_files():
    for i in list:
        path = os.path.join(directory, i)
        SConscript_files = glob.glob(os.path.join(path, 'SConscript*'))
        for SConscript_file in SConscript_files:
            if 'SConscript' in SConscript_file:
                objects = SConscript(SConscript_file, exports='env')
                obj.append(objects) 
    return(obj)

objects = []

objects.append(get_SConsript_Modules())
xyz = env.Program(target='T_Name', source = objects, LIBS = libraries)

Sub-SConscripts look like this:

Import('env')

env = env.Clone()

env.Append(CPPPATH = 'subsubfoldr1')

files = [
    'subsubfoldr1\\BOOT_Init.c',
    'subsubfoldr1\\BOOT_Main.c',
    'subsubfoldr1\\BOOT_StartUpTests.c',
    'subsubfoldr1\\main.c'
]

modules = [ env.StaticObject(x) for x in files ]
Return ('modules')

What am I missing? I tried couple of different solutions, but neither worked. For instance, I tried to give all the module specific SConscripts in this line of SConstruct, but the variant_dir gives error:

SConscript(['SConscript_Main', 'subfoldr1/Sconscript1', 'subfoldr2/SConscript2', 'subfoldr3/SConscript3'], variant_dir='build/temp', src_dir='.', duplicate=0, exports='env')

Upvotes: 0

Views: 714

Answers (1)

bdbaddog
bdbaddog

Reputation: 3509

Ok. There's a couple issues with your implementation.

Firstly, you've asked SCons to use a variant_dir of 'build' and source dir of '.'. This is not a good idea because the effectively build is in the source dir.

Secondly, if all your SConscripts populate modules and then Return() them, each subsequent SConscript will overwrite the return value from the previous SConscript. Note you could just append the return values from StaticObjects() to an env variable

for x in files:
  env['MODULES'] += env.StaticObject(x)

Thirdly, the logic in your SConscript_main, should probably just be in your SConstruct. Then each SConscript() call can set the variant_dir to "#/build/"+os.path.dirname(SConscript_file)

Lastly, since you've told the top level SConscript to use a variant_dir='build', when the various SConscripts are run, SCons considers their current directory to be under build, and given that you have duplicate=0, python's own glob() (fairly certain) won't find any files under build/....

Here's a possible re-implementation of SConscript_files() to put in your SConstruct

Sample SConstruct

import os.path

env = Environment()


def SConscript_files(env):
    sconscripts = Glob("*/*/SConscript", strings=True)
    return sconscripts


objs = []
env["MODULES"] = []
x = SConscript_files(env)
for f in x:
    print("File:%s" % f)
    sconscript_dir = os.path.dirname(f)
    SConscript(
        f,
        variant_dir=os.path.join("#/build", sconscript_dir),
        duplicate=False,
        src_dir=sconscript_dir,
        exports="env",
    )


print("MODULES:%s" % [str(o) for o in env["MODULES"]])

Sample b/c/SConscript

Import('env')
print("In b/c/SConscript")
files = ['x.c', 'y.c']

for f in files:
    env['MODULES'] += env.StaticObject(f)

print("MODULES:%s"%[str(o) for o in env['MODULES']])

Output from sample:

% python ~/devel/scons/git/as_scons/scripts/scons.py
scons: Reading SConscript files ...
File:b/c/SConscript
In b/c/SConscript
MODULES:['x.o', 'y.o']
MODULES:['build/b/c/x.o', 'build/b/c/y.o']
scons: done reading SConscript files.
scons: Building targets ...
gcc -o build/b/c/x.o -c b/c/x.c
gcc -o build/b/c/y.o -c b/c/y.c
scons: done building targets.

% tree .
.
├── SConstruct
├── b
│   └── c
│       ├── SConscript
│       ├── x.c
│       └── y.c
└── build
    └── b
        └── c
            ├── x.o
            └── y.o

Hope this helps!

Upvotes: 1

Related Questions