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

Bill Deegan bill at baddogconsulting.com
Thu Sep 21 12:52:17 EDT 2017


Program is just a builder:

see: src/engine/SCons/Tools/__init__.py:

def createProgBuilder(env):
    """This is a utility function that creates the Program
    Builder in an Environment if it is not there already.

    If it is already there, we return the existing one.
    """

    try:
        program = env['BUILDERS']['Program']
    except KeyError:
        import SCons.Defaults
        program = SCons.Builder.Builder(action = SCons.Defaults.LinkAction,
                                        emitter = '$PROGEMITTER',
                                        prefix = '$PROGPREFIX',
                                        suffix = '$PROGSUFFIX',
                                        src_suffix = '$OBJSUFFIX',
                                        src_builder = 'Object',
                                        target_scanner = ProgramScanner)
        env['BUILDERS']['Program'] = program

    return program


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

-Bill


On Thu, Sep 21, 2017 at 11:57 AM, Julius Ziegler <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
>
>
>
>
> 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
> 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
>
> _______________________________________________
> Scons-users mailing list
> Scons-users at scons.org
> https://pairlist4.pair.net/mailman/listinfo/scons-users
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://pairlist4.pair.net/pipermail/scons-users/attachments/20170921/7c2bd547/attachment-0001.html>


More information about the Scons-users mailing list