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).