[Scons-users] extending build environments (the OO-way)

Julius Ziegler ziegler at atlatec.de
Fri Sep 22 05:49:27 EDT 2017


Hi Bill,

On 09/21/2017 06:52 PM, Bill Deegan wrote:
> Like most things attached to an Environment()..
>
> Likely what you want to do is add another Action to the builder?
>
> Or you can replace it with a Psuedo builder which does stuff and then
> calls the builder.
>
> It really depends when you want the "stuff" to be run, when the
> SConscript is processed, or when the DAG is walked and targets are built..

I think it does not matter in my case. The problem that I am trying to 
solve at the moment is this:

We have shipped out some source code to a customer. It builds with 
scons. The customer has, of course, only ever heard of cmake. The 
project is rather complicated and builds ca. 30 separate libraries and a 
dozen or so executables, so I really do not want to port this to cmake 
(I do not like cmake very much). To make the customer happy, I have made 
a cmake file for him that just calls scons as a custom build step, to 
build one target that depends on every single source file. This is 
already quite ok, since the customer mostly needs the cmake file because 
the IDE that he is using (CLion, something I have never heard of till 
last week) uses cmake as its native project file format. With the simple 
proxy-cmake file I provided he can already browse the source code with 
CLion, use code completion etc..

I now would like to make him even happier by providing a separate target 
(in the cmake file) for every sensible target that is in the scons file. 
Sensible targets are shared libraries and executables. If the customer 
has executable targets in the cmake file, he can e.g. use these as entry 
points, to start them in the CLion debugger.

I want to script this pseudo conversion to cmake, and the first step 
would be to get this list of "real" targets, i.e. everything that is 
build by a "Program" or "SharedLibrary" builder. It would probably be 
sufficient to just print a message for every such target, and I could 
then grep them out of the std output. If I can collect them in a global 
list directly in SCons, even better. What I do not want is to have to 
touch every place in every SConscript where Program and SharedLibrary 
builders are used. Hence my naive attempt at modifying what these 
builders do. Probably attaching an extra Action to them would be the 
right way.

Julius



> -Bill
>
>
> On Thu, Sep 21, 2017 at 11:57 AM, Julius Ziegler <ziegler at atlatec.de
> <mailto:ziegler at atlatec.de>> wrote:
>
>     Thanks for your reply, Gary.
>
>     Phew, its more complicated than I was hoping.
>
>     You have cleared up my main misunderstanding, that was that
>     "Program" is a member function, while it actually is an object that
>     has the __call__ function overloaded (am I right)?
>
>     After reading your message I was trying a bit to monkey patch the
>     Program builder, like this:
>
>     def print_message( self, *args, **kwargs ):
>         print "MESSAGE"
>         self.old_call( *args, **kwargs )
>
>     env.Program.old_call = env.Program.__call__
>     env.Program.__call__ = print_message
>
>     Does that make sense?
>
>     I found out that this can not work directly, according to [1]
>
>     Maybe someone else has a better idea?
>
>     [1]
>     https://stackoverflow.com/questions/38541015/how-to-monkey-patch-a-call-method
>     <https://stackoverflow.com/questions/38541015/how-to-monkey-patch-a-call-method>
>
>
>
>
>     On 09/21/2017 05:09 PM, Gary Granger wrote:
>
>         Here's something about the current solution to this we use, but
>         I don't
>         know if it would be considered a "best practice".  You're right
>         that the
>         methods on the Environment class which are builders are not
>         treated like
>         regular methods.  So to "wrap" a builder method, you can wrap
>         the actual
>         builder instance and replace that instance with your own,
>         something like
>         this:
>
>         from SCons.Builder import BuilderBase
>         from SCons.Builder import _null
>
>         class MyProgramBuilder(BuilderBase):
>             def __init__(self, builder):
>                 BuilderBase.__init__(self,
>                                      action=builder.action,
>                                      emitter=builder.emitter,
>                                      prefix=builder.prefix,
>                                      suffix=builder.suffix,
>                                      src_suffix=builder.src_suffix,
>                                      src_builder=builder.src_builder)
>
>             def __call__(self, env, target=None, source=None,
>         chdir=_null, **kw):
>                 ret = BuilderBase.__call__(self, env, target, source,
>         chdir, **kw)
>                 print("Registered program %s" % (str(source[0]))
>                 return ret
>
>         ...
>
>         env['BUILDERS']['Program'] =
>         MyProgramBuilder(env['BUILDERS']['Program'])
>
>         It could be a little fragile because the wrapper passes all the
>         parameters up to BuilderBase, and the parameters needed by a Program
>         builder instance could change.  Anyway, maybe that helps, or maybe
>         someone knows a better way.
>
>         Gary
>
>         On 09/19/2017 03:20 AM, Julius Ziegler wrote:
>
>             Dear all,
>
>             I am trying to extend what an environment does by inheritance.
>
>             Here is an example of what I try to achive. Expected result
>             is that
>             whenever I schedule build of a "Program" with a  MyEnv, a
>             message gets
>             printed to stdout:
>
>             class MyEnv( Environment ):
>               def Program( self, *args, **kwargs ):
>                 print "REGISTERED PROGRAM TARGET", args[0]
>                 super().Program( *args, **kwargs )
>
>             ...but this code seems to do nothing. It looks like the original
>             Environment overloads the class attribute access or
>             something like
>             this. I am not a hardcore python programmer and it is really
>             hard for
>             me to figure out what is going on.
>
>             Is there a best practice to achieve something similar?
>
>             Thanks!
>             Julius
>
>
>
>     --
>     Dr.-Ing. Julius Ziegler
>
>     Phone:  +49 151 722 026 63 <tel:%2B49%20151%20722%20026%2063>
>     E-Mail: ziegler at atlatec.de <mailto:ziegler at atlatec.de>
>     Web:    www.atlatec.de <http://www.atlatec.de>
>
>     Atlatec GmbH
>     Haid- und Neu-Strasse 7
>     D-76131 Karlsruhe
>
>     Sitz der Gesellschaft: Karlsruhe | Registergericht Mannheim
>     Handelsregisternummer: HRB 718673 | USt-IdNr. DE293003755
>     Geschäftsführer: Dr. Henning Lategahn
>
>     _______________________________________________
>     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
> https://pairlist4.pair.net/mailman/listinfo/scons-users
>

-- 
Dr.-Ing. Julius Ziegler

Phone:  +49 151 722 026 63
E-Mail: ziegler at atlatec.de
Web:    www.atlatec.de

Atlatec GmbH
Haid- und Neu-Strasse 7
D-76131 Karlsruhe

Sitz der Gesellschaft: Karlsruhe | Registergericht Mannheim
Handelsregisternummer: HRB 718673 | USt-IdNr. DE293003755
Geschäftsführer: Dr. Henning Lategahn


More information about the Scons-users mailing list