[jamming] Too small updated action list or do I have to modify jam for this?

Igor Boukanov igor.boukanov at fi.uib.no
Wed Oct 20 10:50:02 PDT 1999


Hello!

To write a set of rules to compile Java sources I had to change jam
sources due to the following:

It is rather difficult to predict all Java '.class' file names so I
decided to avoid an introduction of any dependencies between java
sources and class files and I wrote something 
like

rule JavaMain
{
	DEPENDS $(<) : $(>) ;
	DEPENDS all : $(<) ;
}

actions together updated JavaMain
{
	javac $(>) && touch $(<)
}

with usage:

JavaMain project-name : java-sources ;

JavaMain rule will touch 'project-name' file to change time stamp so it
is >= any of its sources.

I use 'together' and 'updated' modifiers to compile all sources in a
single command and 
only those that are newer. But then I faced well known problem:

Although javac tries to compile not only given sources but also other
files if they depend
in some sense on the given sources, still javac can miss. 

For example, given a.java with single line 

class a { }

and b.java with 

class b extends a { }

the command 'javac a.java' does not compile 'b.java' even if a.java is
newer. Thus I have to tell Jam to compile b.java if anything in a.class
that b.class depends on is changed. To make life easy I translated this
into requirement to tell Jam to issue 

javac a.java b.java

even if only a.java is modified and in the same time simply

javac b.java 

for changes only in b.java

First I added:
DEPENDS b.java : a.java ;

But this does not work because for changes only in a.java jam will
constantly recompile everything because nothing makes b.java newer than
a.java. So instead I added a new rule:

rule JavaDepends 
{
	DEPENDS $(<) : $(>) ;
}

actions JavaDepends 
{
	touch $(<) 
}

to make b.java newer than a.java after 

JavaDepends  a.java b.java

but of cause it has very annoying side effect of changing b.java time
stamp.

So I needed something like JavaDepends that does not modify b.java.
After some attempts to implement this in the jam-2.2 I give up and added
a new built-in rule (see the attached patch for jam-2.2, apply it via
'patch -lp0 < jam-2.2.AsIfUpdated.patch'):

AsIfUpdated targets : sources ;
### If any of targets is stable (no updates) but any of AsIfUpdated
sources requires
### an update or newer, do not skip this target from source lists of
actions with
### "updated" modifier

I can write with it:
JavaMain my-project : a.java b.java ;
AsIfUpdated b.java : a.java ;

which will compile both a.java and b.java for  a-modifications and only
b.java for  b-modifications.

And now the question is:
Do I really need to patch jam for this?

-- 
Igor Boukanov
Company: Well Service Technology AS
Work:  +47 5552 5075  Email: Igor.Boukanov at wst.no
Fax:   +47 5552 5051  Web:   http://www.wst.no/
Mobil: +47 916 28 390
-------------- next part --------------
diff -r -bBdc jam-2.2.orig/compile.c jam-2.2/compile.c
*** jam-2.2.orig/compile.c	Wed Nov 12 10:22:24 1997
--- jam-2.2/compile.c	Wed Oct 20 18:43:24 1999
***************
*** 43,48 ****
--- 43,49 ----
   *  builtin_echo() - ECHO rule
   *  builtin_exit() - EXIT rule
   *  builtin_flags() - NOCARE, NOTFILE, TEMPORARY rule
+  *  builtin_as_if_updated() - ASIFUPDATED rule
   *
   * 02/03/94 (seiwald) - Changed trace output to read "setting" instead of
   *          the awkward sounding "settings".
***************
*** 66,71 ****
--- 67,73 ----
  static void builtin_echo();
  static void builtin_exit();
  static void builtin_flags();
+ static void builtin_as_if_updated();
  
  int glob();
  
***************
*** 121,126 ****
--- 123,133 ----
      bindrule( "Temporary" )->procedure =
      bindrule( "TEMPORARY" )->procedure =
      parse_make( builtin_flags, P0, P0, C0, C0, L0, L0, T_FLAG_TEMP );
+ 
+     bindrule( "ASIFUPDATED" )->procedure =
+     bindrule( "AsIfUpdated" )->procedure =
+     parse_make( builtin_as_if_updated, P0, P0, C0, C0, L0, L0, 0 );
+ 
  }
  
  /*
***************
*** 765,770 ****
--- 772,801 ----
  }
  
  /*
+  *  builtin_as_if_updated() - ASIFUPDATED rule
+  *
+  *  If one of targets is stable but any of ASIFUPDATED sources requires
+  *  update, do not skip this target from source lists of actions with
+  * "updated" modifier
+  */
+ 
+ static void
+ builtin_as_if_updated( parse, args )
+ PARSE   *parse;
+ LOL     *args;
+ {
+     LIST *targets = lol_get( args, 0 );
+     LIST *sources = lol_get( args, 1 );
+     LIST *l;
+ 
+     for( l = targets; l; l = list_next( l ) )
+     {
+         TARGET *t = bindtarget( l->string );
+         t->as_if_update_deps = targetlist( t->as_if_update_deps, sources );
+     }
+ }
+ 
+ /*
   * debug_compile() - printf with indent to show rule expansion.
   */
  
diff -r -bBdc jam-2.2.orig/make1.c jam-2.2/make1.c
*** jam-2.2.orig/make1.c	Wed Nov 12 10:22:36 1997
--- jam-2.2/make1.c	Wed Oct 20 18:43:24 1999
***************
*** 577,583 ****
  	    continue;
  
  	if( ( flags & RULE_NEWSRCS ) && t->fate <= T_FATE_STABLE )
! 	    continue;
  
  	/* Prohibit duplicates for RULE_TOGETHER */
  
--- 577,597 ----
          continue;
  
      if( ( flags & RULE_NEWSRCS ) && t->fate <= T_FATE_STABLE )
!     {
!         /* Skip only if all t->as_if_update_deps are also stable or unknown
!          */
!         int should_skip = 1 ;
!         TARGETS *cursor;
!         for( cursor = t->as_if_update_deps; cursor; cursor = cursor->next )
!         {
!             if( cursor->target->fate > T_FATE_STABLE )
!             {
!                 should_skip = 0;
!                 break;
!             }
!         }
!         if( should_skip ) continue;
!     }
  
      /* Prohibit duplicates for RULE_TOGETHER */
  
diff -r -bBdc jam-2.2.orig/rules.h jam-2.2/rules.h
*** jam-2.2.orig/rules.h	Tue Nov 18 18:32:17 1997
--- jam-2.2/rules.h	Wed Oct 20 18:43:24 1999
***************
*** 157,162 ****
--- 157,170 ----
      int asynccnt;       /* child deps outstanding */
      TARGETS *parents;       /* used by make1() for completion */
      char    *cmds;          /* type-punned command list */
+ 
+     TARGETS *as_if_update_deps; /* If this target is stable but
+                                  * any of as_if_update_deps targets requires
+                                  * update, do not skip this target from
+                                  * source lists of actions with "updated"
+                                  * modifier
+                                  */
+ 
  } ;
  
  RULE    *bindrule();


More information about the jamming mailing list