]> git.ipfire.org Git - thirdparty/make.git/commitdiff
(update_goal_chain): Do inner loop on double-colon entries.
authorRoland McGrath <roland@redhat.com>
Tue, 5 Apr 1994 10:37:12 +0000 (10:37 +0000)
committerRoland McGrath <roland@redhat.com>
Tue, 5 Apr 1994 10:37:12 +0000 (10:37 +0000)
(update_file): Use FILE->double_colon pointer to find all entries.
(f_mtime): Likewise.
(notice_finished_file): Propagate mtime change to all entries.

remake.c

index 41d1c98b25e4540478c757e850f99aed9387ffc9..479045e2390be629867a34ab677bac4b49e0bb6d 100644 (file)
--- a/remake.c
+++ b/remake.c
@@ -1,5 +1,5 @@
 /* Basic dependency engine for GNU Make.
-Copyright (C) 1988, 1989, 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
+Copyright (C) 1988, 89, 90, 91, 92, 93, 94 Free Software Foundation, Inc.
 This file is part of GNU Make.
 
 GNU Make is free software; you can redistribute it and/or modify
@@ -96,108 +96,115 @@ update_goal_chain (goals, makefiles)
       g = goals;
       while (g != 0)
        {
-         unsigned int ocommands_started;
-         int x;
-         time_t mtime = MTIME (g->file);
-         check_renamed (g->file);
-
-         if (makefiles)
+         /* Iterate over all double-colon entries for this file.  */
+         struct file *file = g->file;
+         int stop, any_not_updated = 0;
+         for (file = g->file->double_colon ? g->file->double_colon : g->file;
+              file != NULL;
+              file = file->prev)
            {
-             if (g->file->cmd_target)
+             unsigned int ocommands_started;
+             int x;
+             time_t mtime = MTIME (file);
+             check_renamed (file);
+
+             if (makefiles)
                {
-                 touch_flag = t;
-                 question_flag = q;
-                 just_print_flag = n;
+                 if (file->cmd_target)
+                   {
+                     touch_flag = t;
+                     question_flag = q;
+                     just_print_flag = n;
+                   }
+                 else
+                   touch_flag = question_flag = just_print_flag = 0;
                }
-             else
-               touch_flag = question_flag = just_print_flag = 0;
-           }
 
-         /* Save the old value of `commands_started' so we can compare later.
-            It will be incremented when any commands are actually run.  */
-         ocommands_started = commands_started;
+             /* Save the old value of `commands_started' so we can compare
+                later.  It will be incremented when any commands are
+                actually run.  */
+             ocommands_started = commands_started;
 
-         x = update_file (g->file, makefiles ? 1 : 0);
-         check_renamed (g->file);
-
-         /* Set the goal's `changed' flag if any commands were started
-            by calling update_file above.  We check this flag below to
-            decide when to give an "up to date" diagnostic.  */
-         g->changed += commands_started - ocommands_started;
-
-         if (x != 0 || g->file->updated)
-           {
-             int stop = 0;
-
-             /* If STATUS was not already 1, set it to 1 if
-                updating failed, or to 0 if updating succeeded.
-                Leave STATUS as it is if no updating was done.  */
+             x = update_file (file, makefiles ? 1 : 0);
+             check_renamed (file);
 
-             if (status < 1)
+             /* Set the goal's `changed' flag if any commands were started
+                by calling update_file above.  We check this flag below to
+                decide when to give an "up to date" diagnostic.  */
+             g->changed += commands_started - ocommands_started;
+           
+             stop = 0;
+             if (x != 0 || file->updated)
                {
-                 if (g->file->update_status != 0)
-                   {
-                     /* Updating failed.  */
-                     status = 1;
-                     stop = !keep_going_flag && !makefiles;
-                   }
-                 else if (MTIME (g->file) != mtime)
+                 /* If STATUS was not already 1, set it to 1 if
+                    updating failed, or to 0 if updating succeeded.
+                    Leave STATUS as it is if no updating was done.  */
+
+                 if (status < 1)
                    {
-                     /* Updating was done.
-                        If this is a makefile and just_print_flag or
-                        question_flag is set (meaning -n or -q was given
-                        and this file was specified as a command-line target),
-                        don't change STATUS.  If STATUS is changed, we will
-                        get re-exec'd, and fall into an infinite loop.  */
-                     if (!makefiles || (!just_print_flag && !question_flag))
-                       status = 0;
-                     if (makefiles && g->file->dontcare)
-                       /* This is a default makefile.  Stop remaking.  */
-                       stop = 1;
+                     if (file->update_status != 0)
+                       {
+                         /* Updating failed.  */
+                         status = 1;
+                         stop = !keep_going_flag && !makefiles;
+                       }
+                     else if (MTIME (file) != mtime)
+                       {
+                         /* Updating was done.  If this is a makefile and
+                            just_print_flag or question_flag is set
+                            (meaning -n or -q was given and this file was
+                            specified as a command-line target), don't
+                            change STATUS.  If STATUS is changed, we will
+                            get re-exec'd, and fall into an infinite loop.  */
+                         if (!makefiles
+                             || (!just_print_flag && !question_flag))
+                           status = 0;
+                         if (makefiles && file->dontcare)
+                           /* This is a default makefile.  Stop remaking.  */
+                           stop = 1;
+                       }
                    }
                }
 
-             if (stop || g->file->prev == 0)
-               {
-                 /* If we have found nothing whatever to do for the goal,
-                    print a message saying nothing needs doing.  */
-
-                 if (!makefiles
-                     /* If the update_status is zero, we updated successfully
-                        or not at all.  G->changed will have been set above if
-                        any commands were actually started for this goal.  */
-                     && g->file->update_status == 0 && !g->changed
-                     /* Never give a message under -s or -q.  */
-                     && !silent_flag && !question_flag)
-                   {
-                     if (g->file->phony || g->file->cmds == 0)
-                       message ("Nothing to be done for `%s'.",
-                                g->file->name);
-                     else
-                       message ("`%s' is up to date.", g->file->name);
-                     fflush (stdout);
-                   }
+             /* Keep track if any double-colon entry is not finished.
+                 When they are all finished, the goal is finished.  */
+             any_not_updated |= !file->updated;
+
+             if (stop)
+               break;
+           }
 
-                 /* This goal is finished.  Remove it from the chain.  */
-                 if (lastgoal == 0)
-                   goals = g->next;
+         if (stop || !any_not_updated)
+           {
+             /* If we have found nothing whatever to do for the goal,
+                print a message saying nothing needs doing.  */
+
+             if (!makefiles
+                 /* If the update_status is zero, we updated successfully
+                    or not at all.  G->changed will have been set above if
+                    any commands were actually started for this goal.  */
+                 && file->update_status == 0 && !g->changed
+                 /* Never give a message under -s or -q.  */
+                 && !silent_flag && !question_flag)
+               {
+                 if (file->phony || file->cmds == 0)
+                   message ("Nothing to be done for `%s'.",
+                            file->name);
                  else
-                   lastgoal->next = g->next;
+                   message ("`%s' is up to date.", file->name);
+                 fflush (stdout);
+               }
 
-                 /* Free the storage.  */
-                 free ((char *) g);
+             /* This goal is finished.  Remove it from the chain.  */
+             if (lastgoal == 0)
+               goals = g->next;
+             else
+               lastgoal->next = g->next;
 
-                 g = lastgoal == 0 ? goals : lastgoal->next;
-               }
-             else if (g->file->updated)
-               /* This instance of the target is done being updated.
-                  Go to the next instance (:: rule).
-                  update_file cycles through all instances, but under -j,
-                  update_file can return while the file is running,
-                  then reap_children can change its command state and
-                  updated flag, leaving G->file done, but some of its
-                  other instances needing work.  */
-               g->file = g->file->prev;
+             /* Free the storage.  */
+             free ((char *) g);
+
+             g = lastgoal == 0 ? goals : lastgoal->next;
 
              if (stop)
                break;
@@ -241,7 +248,7 @@ update_file (file, depth)
   register int status = 0;
   register struct file *f;
 
-  for (f = file; f != 0; f = f->prev)
+  for (f = file->double_colon ? file->double_colon : file; f != 0; f = f->prev)
     {
       status |= update_file_1 (f, depth);
       check_renamed (f);
@@ -390,6 +397,8 @@ update_file_1 (file, depth)
 
       {
        register struct file *f = d->file;
+       if (f->double_colon)
+         f = f->double_colon;
        do
          {
            running |= (f->command_state == cs_running
@@ -425,6 +434,8 @@ update_file_1 (file, depth)
 
            {
              register struct file *f = d->file;
+             if (f->double_colon)
+               f = f->double_colon;
              do
                {
                  running |= (f->command_state == cs_running
@@ -612,11 +623,18 @@ notice_finished_file (file)
 
   if (!file->phony)
     {
+      struct file *f;
+
       if (just_print_flag || question_flag
          || (file->is_target && file->cmds == 0))
        file->last_mtime = NEW_MTIME;
       else
        file->last_mtime = 0;
+
+      /* Propagate the change of modification time to all the double-colon
+        entries for this file.  */
+      for (f = file->double_colon; f != 0; f = f->next)
+       f->last_mtime = file->last_mtime;
     }
 
   if (file->update_status != -1)
@@ -925,6 +943,8 @@ f_mtime (file, search)
     }
 
   /* Store the mtime into all the entries for this file.  */
+  if (file->double_colon)
+    file = file->double_colon;
   do
     {
       file->last_mtime = mtime;