4

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 ?

RzR
  • 3,068
  • 29
  • 26
John Smith
  • 777
  • 2
  • 14
  • 37
  • Additional question: you mention two scripts above, that you use to generate additional source files during the build. Is the list of resulting filenames for these scripts fixed, i.e. you always get the same set of output files (*not* necessarily with the same content!)...or does this list of "targets" depend on the script's input? – dirkbaechle Dec 15 '15 at 12:34
  • I can get different output files, the script calls a tool that has its own configuration files. I don't know exactly what are the files generated. There is also a problem that script 2 depends on files generated by script 1 – John Smith Dec 15 '15 at 12:40
  • Okay, there is an example now for how you tried to add your CMD as a PostAction (you're using the wrong syntax by the way, the method expects a target as argument and not an Environment)...but how do you call your script(s) on the command-line? And how does your try to run it in SCons look like? – dirkbaechle Dec 15 '15 at 14:34
  • My bad it was in fact env.Program.... So, I am able to run my script with SCons using this AddPostAction (it is a dummy python script: python script_path/script.py ) as a post process. My problem is now that AddPreAction is executed as stated in the manual, before linking and after the compilation. I want to execute scripts before compilation. This is my problem now. – John Smith Dec 15 '15 at 14:41
  • Then please update your question and description accordingly. Note that I neither write an answer for myself, nor for you exclusively. I try to answer this for everybody viewing and reading this page, so I want both parts (question and answer) to be as concise as possible. – dirkbaechle Dec 15 '15 at 14:57
  • I've updated the question with all the details required ! – John Smith Dec 15 '15 at 15:58
  • Do you need the preaction to run before a specific file is compiled? or before all files are compiled? – bdbaddog Nov 26 '17 at 05:07

1 Answers1

1

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.

Dan
  • 4,312
  • 16
  • 28
dirkbaechle
  • 3,984
  • 14
  • 17