[Scons-users] Environment.MergeFlags() modifies its arguments - bug or working as intended?

Ionuț Leonte ionut.leonte at gmail.com
Wed May 20 13:24:18 EDT 2020


Hello,

I am debugging a problem where a SCons-based build system needlessly
rebuilds targets
that are already up-to-date. I've tracked the problem down to the fact
that MergeFlags() seems
to be modifying its arguments in-place.

Here is a small example:

    flags = {
        'CFLAGS': ['-pipe', '-pthread', '-g'],
        'CXXFLAGS': ['${CFLAGS}', '-std=c++11'],
        'LINKFLAGS': ['-rdynamic', '-pthread'],
        'CPPDEFINES': ['DEF1=1', 'DEF2=2'],
    }

    print(flags)
    env = Environment()
    env.MergeFlags(flags)
    print(flags)

This prints:

{'CFLAGS': ['-pipe', '-pthread', '-g'], 'CXXFLAGS': ['${CFLAGS}',
'-std=c++11'], 'LINKFLAGS': ['-rdynamic', '-pthread'], 'CPPDEFINES':
['DEF1=1', 'DEF2=2']}
{'CFLAGS': ['-g', '-pthread', '-pipe'], 'CXXFLAGS': ['-std=c++11',
'${CFLAGS}'], 'LINKFLAGS': ['-pthread', '-rdynamic'], 'CPPDEFINES':
['DEF2=2', 'DEF1=1']}

As you can see, MergeFlags() will effectively reverse lists from from
the input dictionary in-place.
This seems to happen for any key from the input dictionary that is not
already present in the environment.
For example, modifying the code above to:

    print(flags)
    env = Environment()
    env['CFLAGS'] = ['-O1']
    env.MergeFlags(flags)
    print(flags)

will print:

{'CFLAGS': ['-pipe', '-pthread', '-g'], 'CXXFLAGS': ['${CFLAGS}',
'-std=c++11'], 'LINKFLAGS': ['-rdynamic', '-pthread'], 'CPPDEFINES':
['DEF1=1', 'DEF2=2']}
{'CFLAGS': ['-pipe', '-pthread', '-g'], 'CXXFLAGS': ['-std=c++11',
'${CFLAGS}'], 'LINKFLAGS': ['-pthread', '-rdynamic'], 'CPPDEFINES':
['DEF2=2', 'DEF1=1']}

The list corresponding to the 'CFLAGS'  key remains unchanged if I
ensure that the environment
contains the key at the time MergeFlags() is called. The other lists
in the input dict are reversed
by the MergeFlags() call.

I have prepared a slightly more involved example here:

https://raw.githubusercontent.com/ileonte/scons-bug-maybe/master/SConstruct

Running SCons repeatedly using this will exhibit the problem I am
debugging: SCons will
sometimes rebuild targets that are up-to-date because the build
command 'changes' because
it is obtained from a `flags` dictionary that is modified in-place by
MergeFlags().

I don't see any reference in the documentation that MergeFlags() is
supposed to behave like this.
Perhaps a bug?

NOTE: I have tested this with multiple versions of SCons (2.3.1,
2.5.1, 3.1.2) with both Python 2.7
and Python 3.8.

Thank you,
Ionuț


More information about the Scons-users mailing list