Some generated files have a lot of dependencies and a lot of
dependents.  For this case it is worth doing a micro optimization to
detect if the generated contents have changed since the last time.

The obvious example is asm-offsets.h.  Most asm-offsets.h have large
dependency trees, arch/i386/asm-offsets.s depends on 160 .h files plus
their config options (our include tree is spaghetti), yet a change to
most of those files has no effect on the generated asm-offsets.h.  IA64
is even worse, with a larger dependency list for asm-offsets.s and more
files affected by a change to asm-offsets.h.

This patch against kbuild 2.5-2.4.13-1 adds update_if_changed().  Take
a look at it before I release it to the world.

Index: 13.11/Documentation/kbuild/kbuild-2.5.txt
--- 13.11/Documentation/kbuild/kbuild-2.5.txt Sun, 28 Oct 2001 21:02:09 +1100 kaos 
(linux-2.4/G/e/50_kbuild-2.5 1.32 644)
+++ 13.12(w)/Documentation/kbuild/kbuild-2.5.txt Mon, 29 Oct 2001 01:47:41 +1100 kaos 
+(linux-2.4/G/e/50_kbuild-2.5 1.33 644)
@@ -564,6 +564,25 @@ MAKEFILE.IN SYNTAX
         base_target(vmlinux) is semi-reserved, it can be specified in a
         makefile but it always refers to the top level vmlinux.
 
+    update_if_changed(target new_target)
+        If the new_target is newer than target and they are not identical
+        then replace the contents of target with the contents of new_target.
+        This command is normally used for text files generated by
+        user_command(), the new_target is generated but only replaces target
+        if anything has changed.  The new_target parameter can be omitted, it
+        defaults to the target name prefixed with 'tmp_' (not '.tmp_').
+
+        Obviously there must be another command that generates new_target.
+        Do not use a new_target name that starts with '.', dot files are
+        special cases in kbuild and will not do what you expect.  The target
+        is automatically marked as nodepend(), the only thing it depends on
+        is the new_target, there is no need for other dependency data.
+
+        update_if_changed() is a micro optimization, resist the temptation to
+        use it in too many places.  Only use it when a significant number of
+        files are affected by a change to the target, so the saving in
+        reduced compilation is worth the less readable code in the makefile.
+
     hostcc(object_list)
         Compile the objects to run on the host system.  It uses HOSTCC, the
         standard include list, HOSTCFLAGS plus any extra flags for the
@@ -1549,10 +1568,11 @@ CONTROLLING KBUILD
 
 TEMPORARY FILES FOR KBUILD
 
-  All the temporary files and directories create by kbuild start with
-  '.tmp_'.  Only the kbuild team needs to know what is in these files, but a
-  brief list might be useful to the general build audience.  This list is
-  roughly in the order they appear in the top level and scripts Makefiles.
+  All the temporary files and directories created by kbuild start with
+  '.tmp_' or 'tmp_'.  Only the kbuild team needs to know what is in these
+  files, but a brief list might be useful to the general build audience.
+  This list is roughly in the order they appear in the top level and scripts
+  Makefiles.
 
   .tmp_include_list
     A shell script which, when executed, returns the external include list,
@@ -1674,6 +1694,11 @@ TEMPORARY FILES FOR KBUILD
     fed back into the lexical analyser for macro expansion.  It uses this
     temporary file for the feedback, the feedback is never more than one
     level.
+
+  tmp_<target>
+    Used with update_if_changed() to decide if a file has changed or not.
+    The default for the second parameter of update_if_changed() is the target
+    prefixed with 'tmp_'.
 
 
 ADDITIONAL TARGETS AND COMMANDS
Index: 13.11/Makefile-2.5
--- 13.11/Makefile-2.5 Mon, 08 Oct 2001 16:39:45 +1000 kaos 
(linux-2.4/E/d/40_Makefile-2 1.32 644)
+++ 13.12(w)/Makefile-2.5 Mon, 29 Oct 2001 01:30:33 +1100 kaos 
+(linux-2.4/E/d/40_Makefile-2 1.32 644)
@@ -346,6 +346,7 @@ clean: $(KBUILD_OBJTREE).tmp_global_make
                              -o -name '.SUMS' \
                              -o -name '.tmp_implicit' \
                              -o -name '.tmp_*_shipped' \
+                             -o -name 'tmp_*' \
                              -o -size 0 \
                              \) -type f -print | xargs -r rm -f
        $(KBUILD_QUIET)cd $(KBUILD_OBJTREE) && rm -rf $(CLEAN)
Index: 13.11/arch/i386/Makefile.in
--- 13.11/arch/i386/Makefile.in Sat, 06 Oct 2001 15:24:26 +1000 kaos 
(linux-2.4/E/d/43_Makefile.i 1.13 644)
+++ 13.12(w)/arch/i386/Makefile.in Mon, 29 Oct 2001 01:33:41 +1100 kaos 
+(linux-2.4/E/d/43_Makefile.i 1.13 644)
@@ -12,7 +12,7 @@ extra_aflags(vmlinux.lds.i -no-tradition
 # into
 #   symbol = value /* 0xvalue source */
 
-user_command(asm-offsets.h
+user_command(tmp_asm-offsets.h
        ($(objfile asm-offsets.s))
        (set -e;
          (echo "#ifndef __ASM_OFFSETS_H__";
@@ -41,3 +41,5 @@ user_command(asm-offsets.h
        )
        ()
        )
+
+update_if_changed(asm-offsets.h)
Index: 13.11/drivers/scsi/aic7xxx/aicasm/Makefile.in
--- 13.11/drivers/scsi/aic7xxx/aicasm/Makefile.in Wed, 26 Sep 2001 16:51:39 +1000 kaos 
(linux-2.4/I/d/38_Makefile.i 1.11 644)
+++ 13.12(w)/drivers/scsi/aic7xxx/aicasm/Makefile.in Mon, 29 Oct 2001 01:29:33 +1100 
+kaos (linux-2.4/I/d/38_Makefile.i 1.12 644)
@@ -36,17 +36,15 @@ $(objfile aicasm_scan.lex.o): $(objfile 
 # which in turn would rebuild aic7xxx EVERY TIME, EVEN IF NOTHING HAD CHANGED!
 # Life would be so much easier if aic7xxx used shipped files like everyone else.
 
-ifeq ($(KBUILD_WRITABLE),y)
-  user_command(aicdb.h
+user_command(tmp_aicdb.h
        ()
        (set -e;
-         mv -f $@ $@.old 2>/dev/null || /bin/true;
          for inc in db3/db_185.h db2/db_185.h db1/db.h db1/db_185.h db/db.h 
db/db_185.h db.h db_185.h ;
          do
            (echo "#include <$$inc>"; echo "int main(void) { dbopen(\"\", 0, 0, 0, 0); 
return(0); }") |
              $(HOSTCC) -x c -ldb -o $(objfile .tmp_db3_test) - 2>/dev/null &&
              echo "#include <$$inc>" > $@ &&
-             (cmp -s $@ $@.old && mv $@.old $@ || (rm -f $@.old; echo "  Using `cat 
$@` in $@")) &&
+             echo "Using <$$inc> in aicdb.h" &&
              break;
          done;
          rm -f $(objfile .tmp_db3_test);
@@ -57,7 +55,8 @@ ifeq ($(KBUILD_WRITABLE),y)
        )
        ()
        )
-endif
+
+update_if_changed(aicdb.h)
 
 $(objfile aicasm_symbol.o): $(objfile aicdb.h)
 hostccld(aicasm aicasm.o aicasm_gram.tab.o aicasm_scan.lex.o aicasm_symbol.o)
Index: 13.11/scripts/pp_makefile1_parse.l
--- 13.11/scripts/pp_makefile1_parse.l Thu, 04 Oct 2001 16:53:32 +1000 kaos 
(linux-2.4/I/d/31_pp_makefil 1.18 644)
+++ 13.12(w)/scripts/pp_makefile1_parse.l Mon, 29 Oct 2001 01:15:04 +1100 kaos 
+(linux-2.4/I/d/31_pp_makefil 1.19 644)
@@ -171,6 +171,10 @@ TRAIL      [ \t]*"("
                                  pp_state = 1;
                                  return(BASE_TARGET);
                                }
+"update_if_changed"/{TRAIL}    {
+                                 pp_state = 1;
+                                 return(UPDATE_IF_CHANGED);
+                               }
 "hostcc"/{TRAIL}               {
                                  pp_state = 1;
                                  return(HOSTCC);
@@ -548,14 +552,16 @@ void expand_macros(char **is, char **is_
       changed = 0;
       {
        /* Ignore macros in make comments */
-       int paren = 0;
+       int paren = 0, dquote = 0;
        for (comment = *is; *comment; ++comment) {
-         if (*comment == '(') {
+         if (*comment == '(' && !dquote) {
            ++paren;
-         } else if (*comment == ')') {
+         } else if (*comment == ')' && !dquote) {
            --paren;
+         } else if (*comment == '"') {
+           dquote = !dquote;   /* simplistic, may break on some strings */
          } else if (*comment == '#') {
-           if (paren == 0 && (comment == *is || *(comment-1) != '\\')) {
+           if (paren == 0 && dquote == 0 && (comment == *is || *(comment-1) != '\\')) 
+{
              break;
            }
          }
Index: 13.11/scripts/pp_makefile1_parse.y
--- 13.11/scripts/pp_makefile1_parse.y Thu, 04 Oct 2001 16:53:32 +1000 kaos 
(linux-2.4/I/d/35_pp_makefil 1.24 644)
+++ 13.12(w)/scripts/pp_makefile1_parse.y Mon, 29 Oct 2001 01:29:15 +1100 kaos 
+(linux-2.4/I/d/35_pp_makefil 1.25 644)
@@ -313,7 +313,7 @@ void y_new_string(char **is, char **is_e
 %token EXTRA_CFLAGS EXTRA_CFLAGS_ALL
 %token EXTRA_LDFLAGS
 %token OBJLINK OBJLINK_COND
-%token USER_COMMAND NODEPEND CREATE_OBJDIR SIDE_EFFECT SHIPPED BASE_TARGET
+%token USER_COMMAND NODEPEND CREATE_OBJDIR SIDE_EFFECT SHIPPED BASE_TARGET 
+UPDATE_IF_CHANGED
 %token HOSTCC HOSTLD HOSTCCLD
 %token SETUP
 %token IFSEL IFNSEL IFSELMOD IFSELNMOD
@@ -381,6 +381,7 @@ unit
        | side_effect
        | shipped
        | base_target
+       | update_if_changed
        | hostcc
        | hostld
        | hostccld
@@ -816,6 +817,45 @@ base_target
          { y_printf(")"); }
        ;
 
+update_if_changed
+       : UPDATE_IF_CHANGED
+         LPAREN
+         { start_saving_text(); make_target = 0; }
+         local_target
+         optional_any_target
+         RPAREN
+         {
+           char **s, *target1, *target2 = NULL;
+           for (s = saved_text; s && *s; ++s) {
+             if (!isspace(**s)) {
+               target1 = *s;
+               ++s;
+               break;
+             }
+           }
+           for (; s && *s; ++s) {
+             if (!isspace(**s)) {
+               target2 = *s;
+               ++s;
+               break;
+             }
+           }
+           fprintf(yyout, "%s: ", target1+1);
+           if (target2) {
+             fprintf(yyout, " %s\n", target2+1);
+           }
+           else {
+             char *p = strrchr(target1, '/')+1;
+             fprintf(yyout, " %.*stmp_%s\n", p-(target1+1), target1+1, p);
+           }
+           fprintf(yyout, "\t$(KBUILD_QUIET)cmp -s $< $@ || (($(check_writable);) && 
+echo \"Updating $@\" && cp $< $@)\n\n");
+           fprintf(yyout, "# nodepend(%s)\n", target1);
+           do_nodepend(target1);
+           fprintf(yyout, "CLEAN\t+= %s\n", target1+1);
+           free_saved_text(&saved_text);
+         }
+       ;
+
 
 hostcc
        : HOSTCC
@@ -1001,6 +1041,11 @@ local_target
            }
            free($1);
          }
+       ;
+
+optional_any_target
+       : any_target
+       | /* empty */
        ;
 
 any_target_list


_______________________________________________
kbuild-devel mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/kbuild-devel

Reply via email to