Whats the equivalent of Makefile's include for SConstruct?

Question:

I’m trying find the best way to replicate Makefile’s include in SConstruct. I have come up with a solution, but its messy, relies of the user passing in specific command-line parameters and surely can’t be the best option.

My file structure is as so:

Working_Dir/
   |-> includes/
   |    |-> filename.mk
   |    |-> filename.py
   |-> Makefile
   |-> main.c
   |-> SConstruct

These are my file’s contents

Makefile

all: main.o
    echo "Version is: $(VERSION)"
    gcc $^ -o main

include includes/filename.mk

filename.mk

VERSION := "1.6.2"

%.o: %.c
    gcc -c -o $@ $<

SConstruct

import filename

env=Environment()
filename.Init(env)

#Create new builder
prog = Builder(action=["gcc $SOURCE -o $TARGET"])

#Add the builder
builder = { "Prog": prog}
env.Append(BUILDERS=builder)

print "Version is: " + env['VERSION']
env.Prog(target = "main", source = "main.o")

filename.py

from SCons.Script import *  # Needed so we can use scons stuff like builders

def Init(env):
    #Make builder
    obj = Builder(action="gcc -c -o $TARGET $SOURCE")

    #Add stuff
    env.Append(BUILDERS= {'Obj': obj})
    env.Append(VERSION= "1.6.2")

(Ignore the fact that SCons has its own Object builder, this is just a simplified example that I made to learn from for a bigger project)

To compile with the makefile I run make and for SCons its scons --site-dir="includes" since my included file isn’t in the standard path. As far as I’m aware the site_dir option is the only way to include your own code/builders in scons as seen here. Also note that SConscript files aren’t what I want, since when you call them they execute their instructions in their own directory rather than just loading variables and builders into the caller.

I want it to the user can just run scons and it works. I have read I can set these settings globally to my bash profile as seen here in section 10.1.1, but I don’t want to do this because I don’t want every SCons project on my system defaulting to use this directory. I also had a look at the SetOption() function, but its limited and doesn’t actually allow you to set this particular parameter at all.

The only solution I can think of is to start off using GetOption('site_dir') and if its not the directory I’m expecting, I invoke a new SCons call with all of the same parameters, but now with the correct site_dir option.

However this feels very ghetto and I feel I’m missing a much better solution. Is there a better solution?

EDIT:

The reason I’m using this “includes” directory instead of the “site_scons” directory is because in my larger project the “includes” directory isn’t in the same directory as the project, its in a completely different directory (The path to that directory is known). filename.py will be used for multiple of my SCons projects that depend on it, but not every SCons project on my machine should use it (ie. It shouldn’t be global).

Asked By: Protofall

||

Answers:

I figured it out on my own. I just loaded the file as a normal python module as seen in the top answer here. I specifically used the Python 2 answer since it seems SCons is configured on my system to use python 2.

Thanks to this I have the ability to load any python file including scons related code from anywhere on my computer, this is exactly what I wanted.

For those curious, here’s the code I needed to add

file_path = "/path/to/my/file/filename.py"

import imp
extra_stuff = imp.load_source('filename', file_path)

env=Environment()
extra_stuff.Init(env)
Answered By: Protofall
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.