wiki:Programming/Python/SconsRemoveExtraBuildOutputFiles

Version 1 (modified by Vijay Varadan, 8 years ago) (diff)

--

HOWTO: SCons - Remove Extra Build Output Files

Jan 03 2016

SCons Logo

I spent the end of 2015 and the first couple of days of 2016 porting build environment scripts to Powershell and fixing up SCons based build scripts to work with Visual Studio 2015. When doing debug builds, incremental link (.ILK) and program database (.PDB) files are generated. These are considered extra files, since they're not the actual targets (like .OBJ, .EXE, .LIB or .DLL) being built.

The recommended way to remove these files is to mark them as side effects and call the Clean() method on the environment object passing these as parameters. So, looking at this forum post, I did just that. The change to my SConscript looked something like this:

if variant == 'debug':
    myenv.SideEffect('myproject.ilk', prog)
    myenv.Clean('myproject.ilk', prog)
    ...
    ...

And lo and behold, it didn't work. Unfortunately, SCons documentation is bit bare and scattered about with information split unevenly and non-intuitively in the user guide, man page, API (object model) docs and the wiki. The wiki, after repeatedly being hacked and abused was recently moved to BitBucket, but doesn't seem to be searchable [aaaarrrrgggghhhh!]. This is even more true for information about SideEffect() and its use in conjunction with Clean(). I tried the typical sort of debugging via print statements to ensure that I wasn't munging up any values and nothing seemed amiss.

I ended up finding a clue in the wiki page for the `SideEffect()` function - note that this page is not linked to from the main wiki page and neither is its parent. With search functionality missing for the wiki, I only found that page via a DuckDuckGo search because I was explicitly searching for documentation on the SideEffect() function. On that wiki page, I noticed the function signature which clearly showed that the order of parameters to the SideEffect() function is the reverse of that of Clean(). To be fair, the user guide does have examples and a listing with the correct parameter order - but it's not obvious or pointed out explicitly.

In my not-so-humble opinion, it is incredibly daft and very poor design to reverse parameter order in API functions. Moreover, in this case, there doesn't even seem to be a good reason to do so. It results in increased user errors, just like with me and the original forum poster who posted the initial answer.

I swapped the order of params and voilà! It worked.

if variant == 'debug':
    myenv.SideEffect(<span style="color: #ff0000;">'myproject.ilk'</span>, <span style="color: #0000ff;">prog</span>)
    myenv.Clean(<span style="color: #0000ff;">prog</span>, <span style="color: #ff0000;">'myproject.ilk'</span>)
    ...
    ...

To ensure that I didn't run into this problem elsewhere, I added a function in my SConstruct that would take care of this, with an appropriate comment.

function AddSideEffectForClean(env, side_effect, target):
    # NOTE: the order of params to SideEffect() is the reverse of Clean()
    env.SideEffect(side_effect, target)
    env.Clean(target, side_effect)

...
...
...

global_env.AddMethod(AddSideEffectForClean, "AddSideEffectForClean")

...
...
...

In my various SConscript files, I invoke it as follows:

if variant == 'debug':
    myenv.AddSideEffectForClean('myproject.ilk', target)
    myenv.AddSideEffectForClean('myproject.pdb', target)
    ...
    ...

I wasted a couple of hours on this, but it's sorted now. Hope this helps someone else looking to clean out extraneous build output files when using SCons.