Search code examples
scons

How to get File objects that will be compiled after a rebuild in SCons?


I have to process some log files generated during compilation.

Because some compilers append the errors to logs created in previous builds, I have to delete the error log files that were generated in a previous build if that files will be compiled again.

I need a list of File objects that are compiled during a rebuild. Currently the builders return all the files to be compiled.

Is this possible to achieve this with SCons ?


Solution

  • You are approaching the problem from an angle that will lead you into the "rabbit hole" of SCons' internals very fast.

    The main point here is: SCons doesn't know about your log files, so you have to teach it. In some way, you have to mark (or tag) those build steps as being special such that SCons knows: "Aha, when I execute this Action to create foo.o from foo.cpp...there is also a foo.log afterwards and I need to know about it."

    This is what the methods SideEffect() and Clean() are there for (see UserGuide and MAN page). The former is especially designed for the situation where several build steps write to an extra (log) file, but they all use the same file name. So the single build steps need to run in a sequence, even if SCons is called with the "-j" option. You haven't given any further info about whether this is currently the case for you, but I assume it's not...so SideEffect isn't needed at all to solve your problem:

    ./runme.sh
    ==========
    #!/bin/sh
    
    cp $1 $2
    echo "Hi there" >> out.log
    
    ./SConstruct
    ============
    env = Environment()
    t = env.Command('out.txt', 'in.txt', './runme.sh $SOURCE $TARGET')
    env.Clean(t, 'out.log')
    

    By adding the Clean() specification, SCons knows that it has to remove the file out.log too when the actual target out.txt gets cleaned. If doing this for each compile command proves to be too cumbersome, you can write a small Python wrapper method for it, or even write your own "pseudo-Builder". You can find more infos and guidelines about the latter in our ToolsForFools Guide. And yes, you have to explicitly call "scons -c" for the cleanup of the log files and all the targets...SCons won't automatically remove the log files on each rebuild, because it can't know that this is what you want. You (or some other user) might want to concatenate the log output from several builds, so how would SCons know?

    Elaborating a bit more on the question you actually asked, all that SCons knows is that there is a target and a source file. If the source file has changed (not up-to-date) or the target doesn't exist yet, it knows a list of Actions that it can execute to build the target. This can be a single string, or a Python function, or a list of a mix of those. But there is no semantic analysis going on, where SCons tries to find out what those single Actions mean. Trying to "guess" that, because the executable "gcc" is involved it must be a compilation step, is a too simple approach. What if someone uses an arbitrarily named link to his compiler? What about cross-compiling, spanning an enormous tree of different compiler names for all the different purposes? What about performance analysis and memory check tools like Insure++, where you have to call "insure gcc" instead? Finally, how would you define "compiling", when only being able to look at a command-line that I give you? ;)