[BACK]Return to make.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / make

Diff for /src/usr.bin/make/make.c between version 1.51 and 1.52

version 1.51, 2007/11/18 09:20:25 version 1.52, 2007/11/24 15:41:01
Line 60 
Line 60 
 #include <limits.h>  #include <limits.h>
 #include <stdio.h>  #include <stdio.h>
 #include <signal.h>  #include <signal.h>
   #include <stddef.h>
   #include <string.h>
   #include <ohash.h>
 #include "config.h"  #include "config.h"
 #include "defines.h"  #include "defines.h"
 #include "dir.h"  #include "dir.h"
Line 80 
Line 83 
                                  * MakeOODate. It is added to by                                   * MakeOODate. It is added to by
                                  * Make_Update and subtracted from by                                   * Make_Update and subtracted from by
                                  * MakeStartJobs */                                   * MakeStartJobs */
 static int      numNodes;       /* Number of nodes to be processed. If this  static struct ohash targets;    /* stuff we must build */
                                  * is non-zero when Job_Empty() returns  
                                  * true, there's a cycle in the graph */  
   
 static void MakeAddChild(void *, void *);  static void MakeAddChild(void *, void *);
 static void MakeHandleUse(void *, void *);  static void MakeHandleUse(void *, void *);
Line 91 
Line 92 
 static bool try_to_make_node(GNode *);  static bool try_to_make_node(GNode *);
 static void add_targets_to_make(Lst);  static void add_targets_to_make(Lst);
   
 /*-  static bool has_unmade_predecessor(GNode *);
  *-----------------------------------------------------------------------  static void requeue_successors(GNode *);
  * MakeAddChild  --  
  *      Function used by Make_Run to add a child to the list l.  static bool
  *      It will only add the child if its make field is false.  has_unmade_predecessor(GNode *gn)
  *  
  * Side Effects:  
  *      The given list is extended  
  *-----------------------------------------------------------------------  
  */  
 static void  
 MakeAddChild(void *to_addp, void *lp)  
 {  {
         GNode      *to_add = (GNode *)to_addp;          LstNode ln;
         Lst        l = (Lst)lp;  
   
         if (!to_add->must_make && !(to_add->type & OP_USE))          if (Lst_IsEmpty(&gn->preds))
                 Lst_EnQueue(l, to_add);                  return false;
   
   
           for (ln = Lst_First(&gn->preds); ln != NULL; ln = Lst_Adv(ln)) {
                   GNode   *pgn = (GNode *)Lst_Datum(ln);
   
                   if (pgn->must_make && pgn->built_status == UNKNOWN) {
                           if (DEBUG(MAKE))
                                   printf("predecessor %s not made yet.\n",
                                       pgn->name);
                           return true;
                   }
           }
           return false;
 }  }
   
 static void  static void
 MakeHandleUse(void *pgn, void *cgn)  requeue_successors(GNode *gn)
 {  {
         Make_HandleUse((GNode *)pgn, (GNode *)cgn);          LstNode ln;
           /* Deal with successor nodes. If any is marked for making and has an
            * unmade count of 0, has not been made and isn't in the examination
            * queue, it means we need to place it in the queue as it restrained
            * itself before.       */
           for (ln = Lst_First(&gn->successors); ln != NULL; ln = Lst_Adv(ln)) {
                   GNode   *succ = (GNode *)Lst_Datum(ln);
   
                   if (succ->must_make && succ->unmade == 0
                       && succ->built_status == UNKNOWN)
                           (void)Lst_QueueNew(&toBeMade, succ);
           }
 }  }
   
 /*-  /*-
Line 178 
Line 195 
                 pgn = (GNode *)Lst_Datum(ln);                  pgn = (GNode *)Lst_Datum(ln);
                 if (pgn->must_make) {                  if (pgn->must_make) {
                         pgn->unmade--;                          pgn->unmade--;
                           if (DEBUG(MAKE))
                                   printf("%s--=%d ",
                                       pgn->name, pgn->unmade);
   
                         if ( ! (cgn->type & (OP_EXEC|OP_USE))) {                          if ( ! (cgn->type & (OP_EXEC|OP_USE))) {
                                 if (cgn->built_status == MADE) {                                  if (cgn->built_status == MADE) {
Line 195 
Line 215 
                                  * predecessors will be dealt with in                                   * predecessors will be dealt with in
                                  * MakeStartJobs.                                   * MakeStartJobs.
                                  */                                   */
                                   if (DEBUG(MAKE))
                                           printf("QUEUING ");
                                 Lst_EnQueue(&toBeMade, pgn);                                  Lst_EnQueue(&toBeMade, pgn);
                         } else if (pgn->unmade < 0) {                          } else if (pgn->unmade < 0) {
                                 Error("Graph cycles through %s", pgn->name);                                  Error("Child %s discovered graph cycles through %s", cgn->name, pgn->name);
                         }                          }
                 }                  }
         }          }
         /* Deal with successor nodes. If any is marked for making and has an          if (DEBUG(MAKE))
          * unmade count of 0, has not been made and isn't in the examination                  printf("\n");
          * queue, it means we need to place it in the queue as it restrained          requeue_successors(cgn);
          * itself before.       */  
         for (ln = Lst_First(&cgn->successors); ln != NULL; ln = Lst_Adv(ln)) {  
                 GNode   *succ = (GNode *)Lst_Datum(ln);  
   
                 if (succ->must_make && succ->unmade == 0  
                     && succ->built_status == UNKNOWN)  
                         (void)Lst_QueueNew(&toBeMade, succ);  
         }  
 }  }
   
 static bool  static bool
Line 219 
Line 233 
 {  {
         if (DEBUG(MAKE))          if (DEBUG(MAKE))
                 printf("Examining %s...", gn->name);                  printf("Examining %s...", gn->name);
         /*  
          * Make sure any and all predecessors that are going to be made,          if (gn->unmade != 0) {
          * have been.                  if (DEBUG(MAKE))
          */                          printf(" Requeuing (%d)\n", gn->unmade);
         if (!Lst_IsEmpty(&gn->preds)) {                  add_targets_to_make(&gn->children);
                 LstNode ln;                  Lst_EnQueue(&toBeMade, gn);
                   return false;
                 for (ln = Lst_First(&gn->preds); ln != NULL; ln = Lst_Adv(ln)){  
                         GNode   *pgn = (GNode *)Lst_Datum(ln);  
   
                         if (pgn->must_make && pgn->built_status == UNKNOWN) {  
                                 if (DEBUG(MAKE))  
                                         printf(  
                                             "predecessor %s not made yet.\n",  
                                             pgn->name);  
                                 /*  
                                  * there's a predecessor as yet unmade, so we  
                                  * just drop this node on the floor. When the  
                                  * node in question has been made, it will  
                                  * notice this node as being ready to make but  
                                  * as yet unmade and will place the node on the  
                                  * queue.  
                                  */  
                                 return false;  
                         }  
                 }  
         }          }
           if (has_been_built(gn)) {
                   if (DEBUG(MAKE))
                           printf(" already made\n");
                           return false;
           }
           if (has_unmade_predecessor(gn)) {
                   if (DEBUG(MAKE))
                           printf(" Dropping for now\n");
                   return false;
           }
   
         numNodes--;          Suff_FindDeps(gn);
           if (gn->unmade != 0) {
                   if (DEBUG(MAKE))
                           printf(" Requeuing (after deps: %d)\n", gn->unmade);
                   add_targets_to_make(&gn->children);
                   return false;
           }
         if (Make_OODate(gn)) {          if (Make_OODate(gn)) {
                 if (DEBUG(MAKE))                  if (DEBUG(MAKE))
                         printf("out-of-date\n");                          printf("out-of-date\n");
Line 354 
Line 365 
 }  }
   
   
 /*  static void
  * Make an initial downward pass over the graph, marking nodes to be  MakeAddChild(void *to_addp, void *lp)
  * made as we go down. We call Suff_FindDeps to find where a node is and  {
  * to get some children for it if it has none and also has no commands.          GNode *gn = (GNode *)to_addp;
  * If the node is a leaf, we stick it on the toBeMade queue to  
  * be looked at in a minute, otherwise we add its children to our queue          if (!gn->must_make && !(gn->type & OP_USE))
  * and go on about our business.                  Lst_EnQueue((Lst)lp, gn);
   }
   
   static void
   MakeHandleUse(void *pgn, void *cgn)
   {
           Make_HandleUse((GNode *)pgn, (GNode *)cgn);
   }
   
   /* Add stuff to the toBeMade queue. we try to sort things so that stuff
    * that can be done directly is done right away.  This won't be perfect,
    * since some dependencies are only discovered later (e.g., SuffFindDeps).
  */   */
 static void  static void
 add_targets_to_make(Lst targs)  add_targets_to_make(Lst todo)
 {  {
         LIST examine;   /* List of targets to examine */  
         GNode *gn;          GNode *gn;
           LIST examine;
           unsigned int slot;
   
         Lst_Clone(&examine, targs, NOCOPY);          Lst_Clone(&examine, todo, NOCOPY);
   
         while ((gn = (GNode *)Lst_DeQueue(&examine)) != NULL) {          while ((gn = (GNode *)Lst_DeQueue(&examine)) != NULL) {
                 if (!gn->must_make) {                  if (gn->must_make)      /* already known */
                         gn->must_make = true;                          continue;
                         numNodes++;                  gn->must_make = true;
   
                         look_harder_for_target(gn);                  slot = ohash_qlookup(&targets, gn->name);
                         /*                  if (!ohash_find(&targets, slot))
                          * Apply any .USE rules before looking for implicit                          ohash_insert(&targets, slot, gn);
                          * dependencies to make sure everything that should have  
                          * commands has commands ...  
                          */  
                         Lst_ForEach(&gn->children, MakeHandleUse, gn);  
                         Suff_FindDeps(gn);  
   
                         if (gn->unmade != 0)  
                                 Lst_ForEach(&gn->children, MakeAddChild,                  look_harder_for_target(gn);
                                     &examine);                  /*
                         else                   * Apply any .USE rules before looking for implicit
                                 Lst_EnQueue(&toBeMade, gn);                   * dependencies to make sure everything that should have
                    * commands has commands ...
                    */
                   Lst_ForEach(&gn->children, MakeHandleUse, gn);
                   expand_all_children(gn);
   
                   if (gn->unmade != 0) {
                           if (DEBUG(MAKE))
                                   printf("%s: not queuing (%d unmade children)\n",
                                       gn->name, gn->unmade);
                           Lst_ForEach(&gn->children, MakeAddChild,
                               &examine);
                   } else {
                           if (DEBUG(MAKE))
                                   printf("%s: queuing\n", gn->name);
                           Lst_EnQueue(&toBeMade, gn);
                 }                  }
         }          }
 }  }
Line 416 
Line 450 
 bool  bool
 Make_Run(Lst targs)             /* the initial list of targets */  Make_Run(Lst targs)             /* the initial list of targets */
 {  {
         int         errors;     /* Number of errors the Job module reports */          int errors;     /* Number of errors the Job module reports */
           GNode *gn;
           unsigned int i;
           bool cycle;
   
         Static_Lst_Init(&toBeMade);          Static_Lst_Init(&toBeMade);
           ohash_init(&targets, 10, &gnode_info);
   
         numNodes = 0;  
   
         add_targets_to_make(targs);          add_targets_to_make(targs);
         if (queryFlag) {          if (queryFlag) {
                 /*                  /*
Line 458 
Line 494 
         }          }
   
         errors = Job_Finish();          errors = Job_Finish();
           cycle = false;
   
           for (gn = ohash_first(&targets, &i); gn != NULL;
               gn = ohash_next(&targets, &i)) {
                   if (has_been_built(gn))
                           continue;
                   cycle = true;
                   errors++;
                   printf("Error: target %s unaccounted for (%s)\n",
                       gn->name, status_to_string(gn));
           }
         /*          /*
          * Print the final status of each target. E.g. if it wasn't made           * Print the final status of each target. E.g. if it wasn't made
          * because some inferior reported an error.           * because some inferior reported an error.
          */           */
         errors = errors == 0 && numNodes != 0;          Lst_ForEach(targs, MakePrintStatus, &cycle);
         Lst_ForEach(targs, MakePrintStatus, &errors);          if (errors)
                   Fatal("Errors while building");
   
         return true;          return true;
 }  }

Legend:
Removed from v.1.51  
changed lines
  Added in v.1.52