[Scons-users] Compact notation

Andrew C. Morrow andrew.c.morrow at gmail.com
Sun Dec 11 10:55:12 EST 2016


Over the past few years, I've encountered a few things that seem to lead to
more-verbose-than-needed python code when writing SConscripts, leading to a
less declarative feel. I've recently been thinking about how I would want
to write these things better. Perhaps others have encountered these same
issues and have found solutions?

1) Conditionally including a file or library:

If I have a library that may or may not include a particular file (say,
based on if the target platform is windows), I generally need to pull the
list of sources out, and then conditionally append:

fooSources=[
    'source1.cpp',
    'source2.cpp',
]

fooLibs=[
    'lib1',
    'lib2,
]

if windows:
   fooSources.append('source_windows.cpp')
   fooLibs.append('lib_windows')

env.Library(
    target='foo',
    source=fooSources
    LIBS=fooLibs
)

It would be nicer to write:

env.Library(
    target="foo",
    source=[
        'source1.cpp',
        'source2.cpp',
        'source_windows.cpp' if windows else None,
    ],
    LIBS=[
        'lib1',
        'lib2',
        'lib_windows' if windows else None,
    ]
)

But SCons seems to reject this:

AttributeError: 'NoneType' object has no attribute 'name':

Would it be a reasonable enhancement request that the various built-in
builders filter incoming lists for None? Is there another way to achieve
this? I could obviously attach filter each expression for None at the point
of its declaration, but that seems verbose.

It doesn't come up often, but it would be nice.


2) Inline manipulation of Environment variables.

I can easily override an Env var when declaring a target:

// Happens far away
env.Append(CPPDEFINES="whatever")

env.Library(
    target="foo",
    source=...
    CPPDEFINES=["applies"]
)

This will build with -Dapplies, overriding "whatever" in CPPDEFINES for the
sources in this target. But what if I want to Append or Prepend (Unique),
instead of override? There doesn't seem to be a compact syntax for that. I
need to write:

// Happens far away
env.Append(CPPDEFINES=["whatever"])

env = env.Clone()
env.AppendUnique(CPPDEFINES=["applies"])
env.Library(
    target="foo",
    source=...
)

Now I get both -Dwhatever and -Dapplies for the sources.

But what I'd really like to write is:


// Happens far away
env.Append(CPPDEFINES=["whatever"])

env.Library(
    target="foo",
    source=...
    CPPDEFINES=UniqueAppender(["applies"]),
)

Where UniqueAppender is a mutator that causes the effects of
env.AppendUnique(arg) to be applied to the local Environment for the target.

Is there any existing mechanism to achieve this? If not, is it possible?
Reasonable? Other suggestions for how to do this?

Combining the two techniques:

Old:

fooSources=[
    'source1.cpp',
    'source2.cpp',
]

fooLibs=[
    'lib1',
    'lib2,
]

if windows:
   fooSources.append('source_windows.cpp')
   fooLibs.append('lib_windows')

env = env.Clone()
env.AppendUnique(CPPDEFINES=["applies"])
env.Library(
    target='foo',
    source=fooSources
    LIBS=fooLibs
)

New (and making the 'applies' conditional as well, just for fun):


env.Library(
    target="foo",
    source=[
        'source1.cpp',
        'source2.cpp',
        'source_windows.cpp' if windows else None,
    ],
    CPPDEFINES=UniqueAppender([
        "applies" if windows else None,
    ]),
    LIBS=[
        'lib1',
        'lib2',
        'lib_windows' if windows else None,
    ]
)

I think these two features would go a long way towards making complex
SConscripts more declarative.

Thoughts? Suggestions? Ways I can do this now with SCons that I'm missing?

Thanks,
Andrew
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://pairlist4.pair.net/pipermail/scons-users/attachments/20161211/9f785e9a/attachment.html>


More information about the Scons-users mailing list