[Scons-users] Maven Ideas with Scons -- File missing on wiki

Javier Llopis javier at correo.com
Mon Mar 14 08:42:32 EDT 2016

No problem in creating a recipe in the wiki, but I don't think it can happen until April.

On Mon, Mar 14, 2016 at 12:34, Bill Deegan  wrote: 


Maybe you can write it up in the wiki?

On Mon, Mar 14, 2016 at 8:20 AM, Javier Llopis  wrote:

The approach I'm thinking of is as follows:  

I have a module on my site-scons directory that contains a function as follows:

def make_environment(target=None, platform=None, debug=None):
    '''Create a Scons Environment() object with reasonable options
    ... detect target, platform and debug or take it from args or take it from ARGUMENTS
    ... and create an environment with the right options

    env["_payload"] = {
            "_platform": platform,
            "_target": target,
            "_debug": debug,
    return env

Then, my SConscripts will add information to the payload with the component name as the key and the information any other module will need to use it. The choice of cloning the environment or not rests on the SConscript itself. For example:

lib = env.StaticLibrary("libraryA", sources)
env["_payload"]["libraryA"] = {
            "lib": lib,
            "includes": include_dir_lst,


 env = SConscript("libraryC/SConscript", exports="env") #build a dependency
 libc = env["_payload"]["libraryC"]["lib"]
libc_includes = env["_payload"]["libraryC"]["lib"] 
 localenv = env.Clone()  # if I am adding includes and compiler switches and whatnot...
localenv.Append(CPPPATH= mydirs + libc_includes)
   libB = localenv.SharedLibrary("libraryB", sources, LIBS=libc)
env["_payload"]["libraryB"] = {
     "lib": libB,
     "includes": mydirs,
Return("env") # Always return the original env, not the cloned one

libA = env["_payload"]["libraryA"]["lib"]
libB = env["_payload"]["libraryB"]["lib"]
libA_dirs = env["_payload"]["libraryA"]["includes"]
libB_dirs = env["_payload"]["libraryB"]["includes"]
prog = env.Program("mainapp", sources, CPPPATH=libA_dirs+libB_dirs, LIBS=[libA, libB])
env["_payload"]["mainapp"] = {
        "prog": prog,
main SConstruct:
 env = make_environment()
env = SConscript("libraryA/SSonscript", exports="env")
env = SConscript("libraryB/SConscript", exports="env")
env = SConscript("mainapp/Sconscript", exports="env")
Install("bin", env["_payload"]["mainapp"]["prog"])
The test project on which I'm testing it builds fine. 'Unloading' the payload gets a bit verbose, but other than that I think the approach is very clean. Any further suggestions or criticism are welcome

On Mon, Mar 14, 2016 at 02:27, Jason Kenny  wrote:
 I would disagree,
 Unless one is making a small component, or something simpler. It is more common that a given component will need to add not just libs, but also defines that they don’t want propagated. Most cases I have seen there are some values that should not be propagated. Depending on how much fine tuning you want to do in the build scripts, it can make a lot of sense to have a general “clone” logic to make sure different modules being build are in a different environment and to reduce risk of bad values from leaking down a depenancy chain by mistake.
 O be fair, I tend to find a Clone in many cases heavy, and would rather have a more first class object like the SCons Override environment that does a copy on write. Most of the time there is only one or two item you want to change. Cloning in there cases is often to heavy for what you need.
 From: Bill Deegan (mailto:bill at baddogconsulting.com)
Sent: Sunday, March 13, 2016 11:23 AM
To: SCons users mailing list (mailto:scons-users at scons.org)
Subject: Re: [Scons-users] Maven Ideas with Scons -- File missing on wiki
On Fri, Mar 11, 2016 at 11:13 AM, Javier Llopis   wrote:
 Hi Bill,

 Yes, at each step of the build, every component knows the bits it needs to compile and add (to a static library) or link (for a shared library). If I have a program P that links to libraries A and B, it will also need A and B's include paths, but it doesn't need nor want anything to do with library C that was needed by A, which had additional compiler options and include paths that P isn't concerned with.

 In the code provided, I see that Jakob Scheck is just attaching a dictionary variable, which he calls 'pom', to the environment and storing in it all sorts of interesting info which he then processes. I think I could go that way, creating an environment on SConstruct, and cloning it on the different SConscripts and returning just the info needed by anyone to use the library, from which the upper level SConstruct or SConscript can build the other modules by attaching to the environment the info they need. All I would need then is a function that builds an environment with the OS, Architecture, etc. for the main SConstruct.
 Rarely is it actually necessary to clone the environment in each and every SConscript.
Unless you are altering it in a way you don't want to propagate.
Usually adding LIBS,etc to the env.Program() is a better choice than env['LIBS']...

 On Fri, Mar 11, 2016 at 14:57, Bill Deegan  wrote:  
On Fri, Mar 11, 2016 at 8:58 AM, Javier Llopis  wrote:
   Thank you so much for the file, Bill.

 Indeed, I have found in my design that the environment itself has most of what I need. When I create a library --and I create a bunch of those- I need to be Return()ing not only the library but also list of include directories, that means either that the project gets a longer and longer list of include paths (which is ugly but not dangerous) or that I need to add a little logic to handle what dependencies are needed by this bit and what dependencies are needed by the other bit. The wiki recipe seems to be doing that in a nice, declarative way. Other than that, I am thinking of either subclassing Environment or creating a class that mostly contains an environment plus a few other bits, or perhaps even nothing at all, as you say, and it's just a matter of always doing things the same way in a consistent manner. I don't yet have a clear idea at this point.
Firstly, there are a number of ways to simplify what you are trying to do.
You don't need to return the libraries and such, just add them to your Environment() and Export() it.
Does each program know the libraries it needs to link against?
Or are you adding each library to the list as you create the library and the program(s) link against all of them?
To ask another way, how do you decide which libraries and/or include paths are needed for each program/library/source file compile?
Subclassing Environment is likely not the best way to go and likely overkill.
Can you explain what "other bits" you would need to add?

 On Fri, Mar 11, 2016 at 13:33, Bill Deegan  wrote:  
On Fri, Mar 11, 2016 at 7:02 AM, Javier Llopis  wrote:

 TL;DR: There is a recipe on the wiki "Maven Ideas with Scons" by Jakob Scheck at  https://bitbucket.org/scons/scons/wiki/MavenIdeasWithSCons (https://bitbucket.org/scons/scons/wiki/MavenIdeasWithSCons) that I have found inspiring. Unfortunately, the sources that come with it in a separate file seem to have been lost, possibly during some of the recent site moves. It would be great if someone could give me a pointer to that file, which I would put back to the wiki.
The file is still there, but the link to it wasn't properly translated in the move.

 Here's the file:
https://bitbucket.org/scons/scons/wiki/MavenIdeasWithSCons/sources.zip (https://bitbucket.org/scons/scons/wiki/MavenIdeasWithSCons/sources.zip)

 I'll get the link updated today.
 The broader issue is I need to cut down the boilerplate I find myself writing all the time. I have sources and dependencies that I need to build for windows or Linux, for x86 or x64, with or without debug symbols, and I need to be keeping track of include directories, libraries, library directories, preprocessor symbols and compiler switches, along with one or two custom builders that I have in use. There is a lot of information being passed back and forth and it becomes messy. I have been reading the wiki and earlier list messages for ideas on how to go about this issue and found some good ones here and there. I may need to implement my own 'boilerplate encapsulator class' and I think it could be something like described in the above article. Looking at the sources would save me some time, but I am open to other suggestions, as I don't think this problem is too uncommon.
I'm not sure what couldn't be handled by adding variables to the Environment().
All the items you mention "include directories, libraries, library directories, preprocessor symbols and compiler switches, along with one or two custom builders that I have in use."  are simple to add to the env['MY_INCLUDE']='#abc/def', and then use later.
Just Export() and Import() the environment between your SConstruct and SConscript(s)
Is there something more complicated that that?
 Scons-users mailing list
Scons-users at scons.org (mailto:Scons-users at scons.org)
https://pairlist4.pair.net/mailman/listinfo/scons-users (https://pairlist4.pair.net/mailman/listinfo/scons-users)
 Scons-users mailing list
Scons-users at scons.org (mailto:Scons-users at scons.org)
https://pairlist4.pair.net/mailman/listinfo/scons-users (https://pairlist4.pair.net/mailman/listinfo/scons-users)
 Scons-users mailing list
Scons-users at scons.org (mailto:Scons-users at scons.org)
https://pairlist4.pair.net/mailman/listinfo/scons-users (https://pairlist4.pair.net/mailman/listinfo/scons-users)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://pairlist4.pair.net/pipermail/scons-users/attachments/20160314/dc684ce3/attachment-0001.html>

More information about the Scons-users mailing list