[Scons-users] Do not add a Tool to an Environment multiple times

Mike Haboustak haboustak at gmail.com
Fri Dec 6 10:44:22 EST 2019


My various build systems make use of several SCons Tools to encapulate
resuable functionality. In general, I try to ensure that a Tool's
generate method is idempotent, using facilities like env.SetDefault(),
so that it can be added to a single environment multiple times without
ill affects. This has helped with tool dependencies, for example when
tools B and C both depend on tool A.

However many of the built-in tools are not idempotent, and I understand
that it can be difficult to achieve idempotency for non-trivial tools.

Here's an example SConstruct that demonstrates the issue by including
the gcc tool twice. The '-Wall -Werror` flags are discarded when gcc
is included a second time.

--- SConstruct
env = Environment(
    tools=[
        'gnulink', 'gcc', 'g++', 'gas', 'ar',
        'lex', 'yacc', 'filesystem'
    ])
env.Append(
    CFLAGS=['-Wall', '-Werror']
)
print('CFLAGS=', env['CFLAGS'])

env.Tool('gcc')
print(','.join(env['TOOLS']))
print('CFLAGS=', env['CFLAGS'])
----

The example uses the gcc tool because it includes the cc tool which
stomps on the CFLAGS construction variable, but there are more reasonable
examples of the problem in real projects/Tools.

Does it make sense for the env.Tool() infrastructure to only add a Tool
to an Environment once?

I'm not sure I've seen a use case where including a Tool multiple times
was intended behavior. I can deal with this within each Tool's
generate() implementation, but it's not very easy to do. For example:

def generate(env):
    if len([t for t in env['TOOLS'] if t=='this_tool']) > 1:
        return

If tools can't generally be made load-once, maybe there's a facility to
make load-once tools easier to write. I'd prefer the Tool define
idempotency for the env.Tool() infrastructure, rather than an option on
env.Tool() itself, e.g. env.Tool('gcc', if_not_exist=True).

Thanks,
Mike


More information about the Scons-users mailing list