[jamming] Problem with header file scanning and updates

Matt Armstrong matt at lickey.com
Mon Feb 10 20:38:39 PST 2003


"Peter Klotz" <peter.klotz at aon.at> writes:

>> Is it rebuilt the second time you run Jam?
> Yes.

Then you have a problem with dependencies.

My theory is that the problem is caused by "grist."

I see that you are using grist (FGristFiles) in your UicR rule.  If
you are using SubDir, then FGristFiles will cause each directory in
your project to have different grist added to the targets.

So your UicR rule will create a target something like <a!b!c>base.hpp.

However, Jambase by default does not grist header files found during
the header scan phase.  So Jam will scan derived.cpp and find

    #include "base.hpp"

and create a base.hpp target.

So you end up with <a!b!c>base.hpp and base.hpp -- two Jam targets
that reference the same file.

The first time you run Jam, base.hpp is not modified on disk yet, so
derived.cpp is not out of date (Jam does not realize base.hpp and
<a!b!c>base.hpp are the same file).  The second time, Jam notices that
base.hpp is newer than derived.cpp and recompiles derived.cpp.

This is one place where jam is weak -- I wish there were an elegant
solution to this problem.

You can check if this is happening by running

    jam -d5 | egrep '(base.hpp|derived.cpp)'

You'll see calls to Depends and Includes that set up the dependency
tree.  You'll probably find that the base.hpp included by derived.cpp
has no grist, but the base.hpp generated by your custom rule has
grist.

There are three solutions (probably more):

1) Explicitly set up the dependency in your Jamfile:

    Includes base.hpp : <a!b!c>base.hpp ;

   This second one tricks Jam into thinking base.hpp (the one
   discovered at header scan time) "includes" <a!b!c>base.hpp (the one
   generated by your rule), so any file including base.hpp (namely,
   derived.cpp) will end up depending on <a!b!c>base.hpp.

2) Turn off grist.  Do this by setting the SOURCE_GRIST variable to
   nothing after every SubDir call.

    SubDir TOP foo ;
    SOURCE_GRIST = ;

   This assumes that no two directories in your project will ever have
   files with the same name.

3) Use FGristSourceFiles in your UicR rule.  Add a modified version of
   Jambase' FGristSourceFiles rule to your Jamrules.  The modified
   version will not add grist to .hpp files, just as the stock Jambase
   version does not add grist to .h files.

   This assumes that your project will never have two .hpp files with
   the same name in different directories.


I wish there were an option 4)

4) Modify jam itself such that all targets that are bound to the same
   file on disk automatically have an Includes dependency amongst
   themselves (since anybody depending on one of them will want to
   depend on all of them).

-- 
matt



More information about the jamming mailing list