Problem 1098

Summary: Geant4 application main .cc file not recompiled when dependencies change
Product: Geant4 Reporter: gahs
Component: configAssignee: Gabriele Cosmo <Gabriele.Cosmo>
Status: RESOLVED FIXED    
Severity: normal CC: Gunter.Folger
Priority: P5    
Version: 9.2   
Hardware: All   
OS: All   

Description gahs 2010-01-19 21:17:37 CET
We use binmake.gmk in the makefile for our Geant4 application (exactly as is done in the examples).  Recently, I noticed that the executable source was not being recompiled when its dependencies changed.  This has been a problem for our own simulation development, but it can be easily seen in the standard Geant4 examples such as Example01.  

I believe I've understood the problem, but the explanation may only make sense to someone very familiar with the make system.

By dumping the make database ("make -p"), I discovered that there was a full set of dependency rules for target "example01.o", and another rule defined for "/user/gahs/g4workdir/Linux-g++/example01/tmp/exe/example01.o" which only had the example01.cc as a dependency.  (Here $G4WORKDIR=/user/gahs/g4workdir, $G4SYSTEM=Linux-g++.)  Only the rule with the full path is active.  The makefile does not make example01.o in the current directory, so the first rule refers to an inactive target.

I was able to trace the problem to a small error in the use of a "sed" filter used by binmake.gmk.  The dependencies for example01.cc are autogenerated by binmake.gmk, and stored in $G4TMPDIR/$G4SYSTEM/$G4TARGET/tmp/exe/$G4TARGET.d, where G4TARGET=example01 in the example case.  Careful inspection shows that the generated file indeed contains

example01.o:  example01.cc  [other dependencies] 

It should have had the full path /user/gahs/g4workdir/Linux-g++/example01/tmp/exe/example01.o.  There is a sed filter in binmake.gmk that attempts to make this substitution, but it fails to do so.  (By the way, there is an equivalent sed filter in common.gmk which works as intended for object files in the target library.)

I found the sed command actually being executed by binmake.gmk was

  's!example01.o :!/user/gahs/g4workdir/Linux-g++/example01/tmp/exe/example01.o /user/gahs/g4workdir/Linux-g++/example01/tmp/exe/example01.d!'


NOTE THE SPACE between the first ".o" and ":"!  This causes the pattern match to fail, so that the dependency target is left unmodified.  This leads to the observed problem: "make" does not properly recompile the main .cc file of a Geant4 application when it should do so due to a change in an included file.

The critical final step is figuring out where the spurious space comes from.  It is from the definition of the make variable TARGOBJEXT, which has whitespace at the end of the line.  GNU Make includes trailing whitespace in the variable's value (confirmed with make 3.80 and 3.81).

This extra end-of-line space appeared in binmake.gmk in Geant4 release 9.2, and persists in 9.3.  It was not present in 9.1.
Comment 1 Gabriele Cosmo 2010-01-20 10:31:27 CET
Thanks for the precise report. The fix will be included in a future patch!