[Scons-users] Let directory depend on file? (auto generated sources)

Stijn De Ruyck Stijn.DeRuyck at onsemi.com
Tue Dec 2 11:01:36 EST 2014

Sorry, I can't get this to work.

I have a dumbed down example below:

def FilteredRecursiveGlob(directory, pattern, strings=False, omit=[]):
        matches = []
        for root, dirnames, filenames in os.walk(directory):
                matches.extend(Glob(os.path.join(root, pattern),strings=True))
        filteredMatches = [file for file in matches if os.path.basename(file) not in omit]
        return filteredMatches

def modify_targets(target, source, env):
        generatedFiles = FilteredRecursiveGlob('.','*.c',strings=True,omit=["hello.c"])
        print generatedFiles
        return target, source

env = Environment()
sources = ['hello.c']

bld = Builder(
        action = 'echo `date` >> $TARGET; cp tmp.c.in source1.c; cp tmp2.c.in source2.c;', #example, filenames are "what could come out of mst.odl", in reality not known in advance.
        emitter = modify_targets)
env.Append(BUILDERS = {'Foo' : bld})
generatedFiles = env.Foo('dummy.txt', 'mst.odl')


Problem is of course that after a clean, source1.c and source2.c are not discovered during the modify_targets emitter and not compiled... Only on the second scons invocation they are seen and added to the sources and built.
Also, modifying mst.odl triggers the builder and recreates all files, but the source1.c/2.c files aren't recompiled...

So I don't know where to go from here...

From: Scons-users [mailto:scons-users-bounces at scons.org] On Behalf Of Dirk Bächle
Sent: Thursday, November 27, 2014 4:17 PM
To: SCons users mailing list
Subject: Re: [Scons-users] Let directory depend on file? (auto generated sources)

On 27.11.2014 12:04, Stijn De Ruyck wrote:
Thanks Dirk. As it looks now, I probably won't get around to writing a custom Builder+Emitter. I'll give that a try.

You may want to have a look at


as a starting point...

By the way, I just realized, would my original test ever have worked? (even if you ignore the Dir target)

autogen = env.Command(Dir('autogen'), 'etc/mst.odl', 'tools/build/installModel.sh with some args')
sources.extend(Glob('autogen/*', strings=True))
env.Program(some-exe, sources)

If SCons first parses the SConstruct file, it will be filling up the sources list with the Glob results, while the Command builder is only executed AFTER the parsing phase, correct?
So the Command, triggering installModel, may generate more or less sources, or with different names, than the "old" batch that was still in autogen/. So SCons would be using an outdated sources list anyway, correct?

Yes, you'd always be one step behind...and have to invoke SCons a second time, just to be sure that all dependencies got updated.

If I'm wrong, then maybe your earlier suggestion "You have to specify one of the resulting files "autogen/x.cc" as target instead, " may also work after all, even if I use a dummy file:

autogen = env.Command('autogen/dummy_file.txt', 'etc/mst.odl', 'tools/build/installModel.sh with some args')
sources.extend(Glob('autogen/*', strings=True))
env.Program(some-exe, sources)

Scons will try to rebuild dummy_file.txt by running installModel only if mst.odl has changed and in the process, all the other autogen files get created and rebuilt as well.

SCons rebuilds "dummy_file.txt" whenever it's not up-to-date, this includes the case where the output file doesn't exist. So your installModel.sh would always get called.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://pairlist4.pair.net/pipermail/scons-users/attachments/20141202/e16bd248/attachment.html>

More information about the Scons-users mailing list