2

NOTE This is a follow on from my previous question.

My thinking is I'm misunderstanding one of the more fundamental aspects of how SCons works but here's an illustrative subset of my problem:

I have an SConscript file containing (essentially):

def IncrementBuildNumber(env, target, source):
    #write some #define's to 'target' file using vanilla python code
    return None

someProg = env.Program('SomeProg', source_list)

buildNumber = env.Builder(action = IncrementBuildNumber)
buildNumber_h = buildNumber(env, env.GetBuildPath('BuildNumber.h'), [])
env.Depends(someProg, buildNumber_h)

So basically I'm making a Builder which calls a Python function which writes some C++ code to the target file. This builder is invoked with my BuildNumber.h file that my source code #include's where needed.
The final Depends() call is an attempt to trigger the builder every time SomeProg is rebuilt.

This approach almost works. On first build everything works correctly, BuildNumber.h is generated with the correct build number.
An immediate rebuild correctly deems everything up-to-date and doesn't re-invoke the IncrementBuildNumber builder.
However, the problem is, when I update a .cpp file which indirectly depends on BuildNumber.h. It does a rebuild of the changed source file but I'm guessing deems the Builder's target as up-to-date and decides not to invoke it.

How can I get SCons to 'need' to invoke my builder (or command or whatever it needs to be) whenever the things that depend on it need re-building?

I'm feeling pretty close to a solution but just missing some final piece of knowledge into how SCons works.

I may need to note here that I am using a VARIANT_DIR so I can delete files if needed...
Also I've tried AlwaysBuild() but you guessed it, it always Increments even when someProg is up-to-date.

Community
  • 1
  • 1
Adam Naylor
  • 6,172
  • 10
  • 49
  • 69

1 Answers1

0

Firstly, your last line works out as env.Depends(some_prog, None).

That is probably not what you intended.

As to your other question, if it's not building 'SomeProg' after compiling your cpp file, is it possible that you are using only md5 checks, in which case, is it possible that the contents of the .o file don't actually change even when you change the .h file? Because in that case, SCons won't bother rebuilding the executable.

Also, if you want to change BuildNumber.h as the result of building someProg,, why not put it as a post action again? does the action happen more than once?

Tom Tanner
  • 9,244
  • 3
  • 33
  • 61
  • Thanks tom. Regarding `Depends()`, that makes sense. How do I get my program to depend on the target of my builder? `SomeProg` is always being compiled correctly, the problem is SCons doesn't re-invoke the `IncrementBuildNumber` builder when I change a cpp file which indirectly `#include`s the file it produces (`BuildNumber.h`). I'll look into the post action idea. Thanks Tom. – Adam Naylor Jul 04 '13 at 12:23
  • Regarding your last point. Strictly, `BuildNumber.h` needs to be updated _before_ the build of SomeProg and really only if SomeProg is not up-to-date (and therefore needs to be rebuilt). If I updated it afterwards wouldn't that cause SomeProg to always be out-of-date? – Adam Naylor Jul 04 '13 at 12:57
  • @AdamNaylor, if you need to do something before a target is built, consider using the AddPreAction() Scons function. Here is a related answer: http://stackoverflow.com/a/17329704/1158895 – Brady Jul 04 '13 at 18:57
  • Your results look exactly like I need @Brady thanks for taking the time to take a look. I'll let you know how it goes. – Adam Naylor Jul 04 '13 at 20:35
  • Thanks @Brady that looks like it's working exactly as expected. Looks like the part I was missing was passing the source of my program as the source of the command. I guess SCons needs that to build the appropriate dep. tree. Feel free to jot that down in an answer. – Adam Naylor Jul 04 '13 at 20:45