boostboost-buildbjamb2

bjam - how to always execute shell script before building a target?


My aim is to build a library which includes version information.

I have a script which will update ./version.cpp only when the version has actually changed. This to prevent unnecessary rebuilds.

I have a lib target which globs *.cpp, which is inclusive of version.cpp.

The problem is that if I run bjam I can see it execute the script, and update version.cpp, but the library is not rebuilt.

Only when I run bjam again does it see that version.cpp has changed, and rebuild the lib

My jam file:

Echo [ SHELL "./write_version.sh" ] ;

lib foo
    : [ glob *.cpp ]
    ;

Output of running bjam (twice):

$ bjam
Updating version.cpp

...found 119 targets...

$ bjam
...found 121 targets...
...updating 3 targets...
gcc.compile.c++ ../foo/bin/gcc-4.8/debug/link-static/version.o
gcc.archive ../foo/bin/gcc-4.8/debug/link-static/libfoo.a
...updated 3 targets...

Question:

How can I get both the script and the library build working together?


Solution

  • The issue is that dependencies are resolved when the Jamfile is loaded

    ie: in the example Jamfile:

    lib foo
        : [ glob *.cpp ]
        ;
    

    the cpp files are globbed and stat'd when the Jamfile is loaded. Any that aren't out of date won't be rebuilt.

    After loading the Jamfile, bjam executes the script which generates the updated version.cpp, which is too late.

    A work around is to execute the shell script in the Jamroot. In this way version.cpp is updated before the Jamfile which uses it is loaded. The file is stat'd, found to be updated, and lib foo rebuilt.

    Jamroot:

    Echo [ SHELL "./write_version.sh" ] ;
    
    build-project foo ;
    

    foo Jamfile:

    lib foo
        : [ glob *.cpp ]
        ;