How to add pre and post-process actions to SCons build?

Question:

I’m trying to add pre and post-process actions when building a project with SCons.

The SConstruct and SConscript files are at the top of the project.

Pre-process actions:
Generating code(by calling different tools):
-> without knowing the exact files that will be generated after this pre-process (additional pre-process for deciding which files were generated can be created in order to feed SCons with them)

-> running external scripts(python, pearl scripts), executed before compilation

Post-process actions:

->running external tools, running external scripts that should be executed after linking

What I tried until now:

For pre-process:

  • To use os.system from python in order to run a cmd. ( works fine but I’m looking for a “SCons solution” )
  • To use AddPreAction(target, action) function from SCons. Unfortunately this function is executed after compiling the project as the SCons user manual states: "The specified pre_action would be executed before scons calls the link command that actually generates
    the executable program binary foo, not before compiling the foo.c file into an object file."

For post-process:

  • To use AddPostAction(target, action) and this works fine, fortunately.

I’m looking for solutions that will make SCons somehow aware of this pre and post processes.

My question is the following:

What is the best approach, for the requirements stated above, using SCons ? Is there a way to execute pre-process actions before compilation using SCons built-in functions ?

Asked By: John Smith

||

Answers:

You don’t give very much detail about what you’ve tried to get your pre-processing part working. In general, you should try to create real Builders for the Code generation part…this will make the detection and handling of dependencies easier for SCons (and for you as the user 😉 ). You may want to check out our Wiki at https://github.com/SCons/scons/wiki/ToolsForFools , where we explain in large detail how to write new Builders.

If you need to run additional scripts on every build, you should be able to trigger these fine with the os.system() or an appropriate subprocess call right at the start of your top-level SConstruct for example. But what I get from your latest edit, and I’ll refer mainly to the first of the questions you asked, is that you’re trying to model some sort of "staged" build process. You think you need a "preprocess" stage, where you can hook into and create all the additional headers and sources you might need, by calling your scripts. My guess is, that you’re trying to rewrite something like an original make/autotools setup and would like to reuse parts wherever possible, which isn’t a bad idea of course. But SCons isn’t stage-driven, it’s dependency-driven…so your current approach is a bad fit and might lead to problems sooner or later.

The best thing you can do, is to forget Pre- and PostActions and get your dependencies straight. In addition to writing your own Builder(s) to replace your scripts, you’d have to implement a proper Emitter for each of these Builders. This Emitter (check the Tools guide mentioned above) would have to parse your input file that goes into the script, and return the list of filenames that will be generated when the script gets actually run. Like this, SCons will then know a priori which files get generated once the build script is run, and can use these names for resolving dependencies already (even if the actual files don’t exist yet).

For the post-processing part: this is usually handled by using the standard Python atexit handler. See e.g. How do I run some code after every build in scons? for an example.

Answered By: dirkbaechle
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.