Managing build order (for automatically generated code) with Boost.Build (bbv2 / bjam)

I use an external tool to create the source code for the application at work. The tool takes a directory tree full of JSON files, and generates C ++ and some other utility files. I was able to set a rule and a goal that will restart the generator when the source has changed, but I'm struggling to determine how to control the build order.

Since I have no easy way to create a list of C ++ / H files that will be created by the code generator (since it is determined by the runtime configuration), I see no alternative but to start the generator and then GLOB all the files in the output directory.

When I install source files (JSON) depending on my executable file, Boost.Build starts the generator when something has changed, however it calculates the dependencies of my executable file before the code generator runs, and therefore does not restore the right things (for example, if there were new files are created or header files are changed, their dependencies are not recompiled), since this check is performed before the code generator is launched and therefore GLOB takes the current (outdated) generated files, and not new ones.

I will get around this by using b2 twice, first with a purpose that generates the code, and again so that the newly generated code is properly GLOBbed and my executable is rebuilt. This works, but I really would like to have a way to specify "start the code generator, if necessary, then GLOB any files in the output directory and determine what needs to be rebuilt." I could not find the right conditions for the search - bbv2 has its own concept of “generators”, which makes it difficult to find exactly what I am looking for, and I did not find a good source of examples.

My rules look something like this, I'm afraid that I can not be more specific. This is for a generator that accepts files like * .foo and * .bar and creates a bunch of CPP files, as well as one .baz file that I use to determine if it is being updated.

type.register FOO : foo ;
type.register BAR : bar ;

type.register BAZ : baz ;

generators.register-composing fileset2baz : FOO BAR : BAZ ;
rule fileset2baz ( target : sources * : properties * )
{
   # I actually have a switch here based on OS type, but it is not germane to this example
   codegen $(target) : $(sources) : $(properties) ;
}
actions codegen
{
    ./run-the-code-generator
}

# take the fileset and a target object, and invoke the generator
rule fileset ( fileset : target )
{
    local FILES = [ path.glob-tree $(fileset) : *.foo *.bar ] ;
    local target_baz = $(fileset:B).baz;
    baz $(target_baz) : $(FILES) ;
    return $(target_baz) ;
}

.... - :

alias cg : [ fileset $(PATH_TO_FILESET) : $(OUTPUT_DIR) ] ;
lib CodeGen : [ GLOB $(OUTPUT_DIR) : *.cpp *.c ] : : : <include>$(OUTPUT_DIR);

CodeGen, , . cg ( ) , $(OUTPUT_DIR).

+4

All Articles