mk.c 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. /*
  2. * This file is part of the UCB release of Plan 9. It is subject to the license
  3. * terms in the LICENSE file found in the top-level directory of this
  4. * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
  5. * part of the UCB release of Plan 9, including this file, may be copied,
  6. * modified, propagated, or distributed except according to the terms contained
  7. * in the LICENSE file.
  8. */
  9. #include "mk.h"
  10. int runerrs;
  11. void
  12. mk(char *target)
  13. {
  14. Node *node;
  15. int did = 0;
  16. nproc(); /* it can be updated dynamically */
  17. nrep(); /* it can be updated dynamically */
  18. runerrs = 0;
  19. node = graph(target);
  20. if(DEBUG(D_GRAPH)){
  21. dumpn("new target\n", node);
  22. Bflush(&bout);
  23. }
  24. clrmade(node);
  25. while(node->flags&NOTMADE){
  26. if(work(node, (Node *)0, (Arc *)0))
  27. did = 1; /* found something to do */
  28. else {
  29. if(waitup(1, (int *)0) > 0){
  30. if(node->flags&(NOTMADE|BEINGMADE)){
  31. assert(/*must be run errors*/ runerrs);
  32. break; /* nothing more waiting */
  33. }
  34. }
  35. }
  36. }
  37. if(node->flags&BEINGMADE)
  38. waitup(-1, (int *)0);
  39. while(jobs)
  40. waitup(-2, (int *)0);
  41. assert(/*target didnt get done*/ runerrs || (node->flags&MADE));
  42. if(did == 0)
  43. Bprint(&bout, "mk: '%s' is up to date\n", node->name);
  44. }
  45. void
  46. clrmade(Node *n)
  47. {
  48. Arc *a;
  49. n->flags &= ~(CANPRETEND|PRETENDING);
  50. if(strchr(n->name, '(') ==0 || n->time)
  51. n->flags |= CANPRETEND;
  52. MADESET(n, NOTMADE);
  53. for(a = n->prereqs; a; a = a->next)
  54. if(a->n)
  55. clrmade(a->n);
  56. }
  57. static void
  58. unpretend(Node *n)
  59. {
  60. MADESET(n, NOTMADE);
  61. n->flags &= ~(CANPRETEND|PRETENDING);
  62. n->time = 0;
  63. }
  64. int
  65. work(Node *node, Node *p, Arc *parc)
  66. {
  67. Arc *a, *ra;
  68. int weoutofdate;
  69. int ready;
  70. int did = 0;
  71. char cwd[256];
  72. /*print("work(%s) flags=0x%x time=%lud\n", node->name, node->flags, node->time);/**/
  73. if(node->flags&BEINGMADE)
  74. return(did);
  75. if((node->flags&MADE) && (node->flags&PRETENDING) && p && outofdate(p, parc, 0)){
  76. if(explain)
  77. fprint(1, "unpretending %s(%lud) because %s is out of date(%lud)\n",
  78. node->name, node->time, p->name, p->time);
  79. unpretend(node);
  80. }
  81. /*
  82. have a look if we are pretending in case
  83. someone has been unpretended out from underneath us
  84. */
  85. if(node->flags&MADE){
  86. if(node->flags&PRETENDING){
  87. node->time = 0;
  88. }else
  89. return(did);
  90. }
  91. /* consider no prerequisite case */
  92. if(node->prereqs == 0){
  93. if(node->time == 0){
  94. if(getwd(cwd, sizeof cwd))
  95. fprint(2, "mk: don't know how to make '%s' in directory %s\n", node->name, cwd);
  96. else
  97. fprint(2, "mk: don't know how to make '%s'\n", node->name);
  98. if(kflag){
  99. node->flags |= BEINGMADE;
  100. runerrs++;
  101. } else
  102. Exit();
  103. } else
  104. MADESET(node, MADE);
  105. return(did);
  106. }
  107. /*
  108. now see if we are out of date or what
  109. */
  110. ready = 1;
  111. weoutofdate = aflag;
  112. ra = 0;
  113. for(a = node->prereqs; a; a = a->next)
  114. if(a->n){
  115. did = work(a->n, node, a) || did;
  116. if(a->n->flags&(NOTMADE|BEINGMADE))
  117. ready = 0;
  118. if(outofdate(node, a, 0)){
  119. weoutofdate = 1;
  120. if((ra == 0) || (ra->n == 0)
  121. || (ra->n->time < a->n->time))
  122. ra = a;
  123. }
  124. } else {
  125. if(node->time == 0){
  126. if(ra == 0)
  127. ra = a;
  128. weoutofdate = 1;
  129. }
  130. }
  131. if(ready == 0) /* can't do anything now */
  132. return(did);
  133. if(weoutofdate == 0){
  134. MADESET(node, MADE);
  135. return(did);
  136. }
  137. /*
  138. can we pretend to be made?
  139. */
  140. if((iflag == 0) && (node->time == 0) && (node->flags&(PRETENDING|CANPRETEND))
  141. && p && ra->n && !outofdate(p, ra, 0)){
  142. node->flags &= ~CANPRETEND;
  143. MADESET(node, MADE);
  144. if(explain && ((node->flags&PRETENDING) == 0))
  145. fprint(1, "pretending %s has time %lud\n", node->name, node->time);
  146. node->flags |= PRETENDING;
  147. return(did);
  148. }
  149. /*
  150. node is out of date and we REALLY do have to do something.
  151. quickly rescan for pretenders
  152. */
  153. for(a = node->prereqs; a; a = a->next)
  154. if(a->n && (a->n->flags&PRETENDING)){
  155. if(explain)
  156. Bprint(&bout, "unpretending %s because of %s because of %s\n",
  157. a->n->name, node->name, ra->n? ra->n->name : "rule with no prerequisites");
  158. unpretend(a->n);
  159. did = work(a->n, node, a) || did;
  160. ready = 0;
  161. }
  162. if(ready == 0) /* try later unless nothing has happened for -k's sake */
  163. return(did || work(node, p, parc));
  164. did = dorecipe(node) || did;
  165. return(did);
  166. }
  167. void
  168. update(int fake, Node *node)
  169. {
  170. Arc *a;
  171. MADESET(node, fake? BEINGMADE : MADE);
  172. if(((node->flags&VIRTUAL) == 0) && (access(node->name, 0) == 0)){
  173. node->time = timeof(node->name, 1);
  174. node->flags &= ~(CANPRETEND|PRETENDING);
  175. for(a = node->prereqs; a; a = a->next)
  176. if(a->prog)
  177. outofdate(node, a, 1);
  178. } else {
  179. node->time = 1;
  180. for(a = node->prereqs; a; a = a->next)
  181. if(a->n && outofdate(node, a, 1))
  182. node->time = a->n->time;
  183. }
  184. /* print("----node %s time=%lud flags=0x%x\n", node->name, node->time, node->flags);/**/
  185. }
  186. static
  187. pcmp(char *prog, char *p, char *q)
  188. {
  189. char buf[3*NAMEBLOCK];
  190. int pid;
  191. Bflush(&bout);
  192. snprint(buf, sizeof buf, "%s '%s' '%s'\n", prog, p, q);
  193. pid = pipecmd(buf, 0, 0);
  194. while(waitup(-3, &pid) >= 0)
  195. ;
  196. return(pid? 2:1);
  197. }
  198. int
  199. outofdate(Node *node, Arc *arc, int eval)
  200. {
  201. char buf[3*NAMEBLOCK], *str;
  202. Symtab *sym;
  203. int ret;
  204. str = 0;
  205. if(arc->prog){
  206. snprint(buf, sizeof buf, "%s%c%s", node->name, 0377,
  207. arc->n->name);
  208. sym = symlook(buf, S_OUTOFDATE, 0);
  209. if(sym == 0 || eval){
  210. if(sym == 0)
  211. str = strdup(buf);
  212. ret = pcmp(arc->prog, node->name, arc->n->name);
  213. if(sym)
  214. sym->u.value = ret;
  215. else
  216. symlook(str, S_OUTOFDATE, (void *)ret);
  217. } else
  218. ret = sym->u.value;
  219. return(ret-1);
  220. } else if(strchr(arc->n->name, '(') && arc->n->time == 0) /* missing archive member */
  221. return 1;
  222. else
  223. /*
  224. * Treat equal times as out-of-date.
  225. * It's a race, and the safer option is to do
  226. * extra building rather than not enough.
  227. */
  228. return node->time <= arc->n->time;
  229. }