(main): Move checks .IGNORE, .SILENT, .POSIX to snap_deps.
[make.git] / remake.c
blobe619b44d90ac0ecc9ebbfc246c03869980468c57
1 /* Basic dependency engine for GNU Make.
2 Copyright (C) 1988, 89, 90, 91, 92, 93, 94 Free Software Foundation, Inc.
3 This file is part of GNU Make.
5 GNU Make is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2, or (at your option)
8 any later version.
10 GNU Make is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with GNU Make; see the file COPYING. If not, write to
17 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
19 #include "make.h"
20 #include "commands.h"
21 #include "job.h"
22 #include "dep.h"
23 #include "file.h"
24 #include <assert.h>
26 #ifdef HAVE_FCNTL_H
27 #include <fcntl.h>
28 #else
29 #include <sys/file.h>
30 #endif
32 extern int try_implicit_rule ();
35 /* Incremented when a command is started (under -n, when one would be). */
36 unsigned int commands_started = 0;
38 static int update_file (), update_file_1 (), check_dep (), touch_file ();
39 static void remake_file ();
40 static time_t name_mtime ();
41 static int library_search ();
42 extern time_t f_mtime ();
44 /* Remake all the goals in the `struct dep' chain GOALS. Return -1 if nothing
45 was done, 0 if all goals were updated successfully, or 1 if a goal failed.
46 If MAKEFILES is nonzero, these goals are makefiles, so -t, -q, and -n should
47 be disabled for them unless they were also command-line targets, and we
48 should only make one goal at a time and return as soon as one goal whose
49 `changed' member is nonzero is successfully made. */
51 int
52 update_goal_chain (goals, makefiles)
53 register struct dep *goals;
54 int makefiles;
56 int t = touch_flag, q = question_flag, n = just_print_flag;
57 unsigned int j = job_slots;
58 int status = -1;
60 #define MTIME(file) (makefiles ? file_mtime_no_search (file) \
61 : file_mtime (file))
63 /* Duplicate the chain so we can remove things from it. */
65 goals = copy_dep_chain (goals);
68 /* Clear the `changed' flag of each goal in the chain.
69 We will use the flag below to notice when any commands
70 have actually been run for a target. When no commands
71 have been run, we give an "up to date" diagnostic. */
73 struct dep *g;
74 for (g = goals; g != 0; g = g->next)
75 g->changed = 0;
78 if (makefiles)
79 /* Only run one job at a time. */
80 job_slots = 1;
82 /* Update all the goals until they are all finished. */
84 while (goals != 0)
86 register struct dep *g, *lastgoal;
88 /* Start jobs that are waiting for the load to go down. */
90 start_waiting_jobs ();
92 /* Wait for a child to die. */
94 reap_children (1, 0);
96 lastgoal = 0;
97 g = goals;
98 while (g != 0)
100 /* Iterate over all double-colon entries for this file. */
101 struct file *file = g->file;
102 int stop, any_not_updated = 0;
103 for (file = g->file->double_colon ? g->file->double_colon : g->file;
104 file != NULL;
105 file = file->prev)
107 unsigned int ocommands_started;
108 int x;
109 time_t mtime = MTIME (file);
110 check_renamed (file);
112 if (makefiles)
114 if (file->cmd_target)
116 touch_flag = t;
117 question_flag = q;
118 just_print_flag = n;
120 else
121 touch_flag = question_flag = just_print_flag = 0;
124 /* Save the old value of `commands_started' so we can compare
125 later. It will be incremented when any commands are
126 actually run. */
127 ocommands_started = commands_started;
129 x = update_file (file, makefiles ? 1 : 0);
130 check_renamed (file);
132 /* Set the goal's `changed' flag if any commands were started
133 by calling update_file above. We check this flag below to
134 decide when to give an "up to date" diagnostic. */
135 g->changed += commands_started - ocommands_started;
137 stop = 0;
138 if (x != 0 || file->updated)
140 /* If STATUS was not already 1, set it to 1 if
141 updating failed, or to 0 if updating succeeded.
142 Leave STATUS as it is if no updating was done. */
144 if (status < 1)
146 if (file->update_status != 0)
148 /* Updating failed, or -q triggered.
149 The STATUS value tells our caller which. */
150 status = file->update_status;
151 /* If -q just triggered, stop immediately.
152 It doesn't matter how much more we run,
153 since we already know the answer to return. */
154 stop = (!keep_going_flag && !question_flag
155 && !makefiles);
157 else if (MTIME (file) != mtime)
159 /* Updating was done. If this is a makefile and
160 just_print_flag or question_flag is set
161 (meaning -n or -q was given and this file was
162 specified as a command-line target), don't
163 change STATUS. If STATUS is changed, we will
164 get re-exec'd, and fall into an infinite loop. */
165 if (!makefiles
166 || (!just_print_flag && !question_flag))
167 status = 0;
168 if (makefiles && file->dontcare)
169 /* This is a default makefile. Stop remaking. */
170 stop = 1;
175 /* Keep track if any double-colon entry is not finished.
176 When they are all finished, the goal is finished. */
177 any_not_updated |= !file->updated;
179 if (stop)
180 break;
183 /* Reset FILE since it is null at the end of the loop. */
184 file = g->file;
186 if (stop || !any_not_updated)
188 /* If we have found nothing whatever to do for the goal,
189 print a message saying nothing needs doing. */
191 if (!makefiles
192 /* If the update_status is zero, we updated successfully
193 or not at all. G->changed will have been set above if
194 any commands were actually started for this goal. */
195 && file->update_status == 0 && !g->changed
196 /* Never give a message under -s or -q. */
197 && !silent_flag && !question_flag)
199 if (file->phony || file->cmds == 0)
200 message ("Nothing to be done for `%s'.",
201 file->name);
202 else
203 message ("`%s' is up to date.", file->name);
204 fflush (stdout);
207 /* This goal is finished. Remove it from the chain. */
208 if (lastgoal == 0)
209 goals = g->next;
210 else
211 lastgoal->next = g->next;
213 /* Free the storage. */
214 free ((char *) g);
216 g = lastgoal == 0 ? goals : lastgoal->next;
218 if (stop)
219 break;
221 else
223 lastgoal = g;
224 g = g->next;
229 if (makefiles)
231 touch_flag = t;
232 question_flag = q;
233 just_print_flag = n;
234 job_slots = j;
237 return status;
240 /* If FILE is not up to date, execute the commands for it.
241 Return 0 if successful, 1 if unsuccessful;
242 but with some flag settings, just call `exit' if unsuccessful.
244 DEPTH is the depth in recursions of this function.
245 We increment it during the consideration of our dependencies,
246 then decrement it again after finding out whether this file
247 is out of date.
249 If there are multiple double-colon entries for FILE,
250 each is considered in turn. */
252 static int
253 update_file (file, depth)
254 struct file *file;
255 unsigned int depth;
257 register int status = 0;
258 register struct file *f;
260 for (f = file->double_colon ? file->double_colon : file; f != 0; f = f->prev)
262 status |= update_file_1 (f, depth);
263 check_renamed (f);
265 if (status != 0 && !keep_going_flag)
266 return status;
268 switch (f->command_state)
270 case cs_finished:
271 /* The file is done being remade. */
272 break;
274 case cs_running:
275 case cs_deps_running:
276 /* Don't run the other :: rules for this
277 file until this rule is finished. */
278 return 0;
280 default:
281 assert (f->command_state == cs_running);
282 break;
286 return status;
289 /* Consider a single `struct file' and update it as appropriate. */
291 static int
292 update_file_1 (file, depth)
293 struct file *file;
294 unsigned int depth;
296 register time_t this_mtime;
297 int noexist, must_make, deps_changed;
298 int dep_status = 0;
299 register struct dep *d, *lastd;
300 int running = 0;
302 DEBUGPR ("Considering target file `%s'.\n");
304 if (file->updated)
306 if (file->update_status > 0)
308 DEBUGPR ("Recently tried and failed to update file `%s'.\n");
309 return file->update_status;
312 DEBUGPR ("File `%s' was considered already.\n");
313 return 0;
316 switch (file->command_state)
318 case cs_not_started:
319 case cs_deps_running:
320 break;
321 case cs_running:
322 DEBUGPR ("Still updating file `%s'.\n");
323 return 0;
324 case cs_finished:
325 DEBUGPR ("Finished updating file `%s'.\n");
326 return file->update_status;
327 default:
328 abort ();
331 ++depth;
333 /* Notice recursive update of the same file. */
334 file->updating = 1;
336 /* Looking at the file's modtime beforehand allows the possibility
337 that its name may be changed by a VPATH search, and thus it may
338 not need an implicit rule. If this were not done, the file
339 might get implicit commands that apply to its initial name, only
340 to have that name replaced with another found by VPATH search. */
342 this_mtime = file_mtime (file);
343 check_renamed (file);
344 noexist = this_mtime == (time_t) -1;
345 if (noexist)
346 DEBUGPR ("File `%s' does not exist.\n");
348 must_make = noexist;
350 /* If file was specified as a target with no commands,
351 come up with some default commands. */
353 if (!file->phony && file->cmds == 0 && !file->tried_implicit)
355 if (try_implicit_rule (file, depth))
356 DEBUGPR ("Found an implicit rule for `%s'.\n");
357 else
358 DEBUGPR ("No implicit rule found for `%s'.\n");
359 file->tried_implicit = 1;
361 if (file->cmds == 0 && !file->is_target
362 && default_file != 0 && default_file->cmds != 0)
364 DEBUGPR ("Using default commands for `%s'.\n");
365 file->cmds = default_file->cmds;
368 /* Update all non-intermediate files we depend on, if necessary,
369 and see whether any of them is more recent than this file. */
371 lastd = 0;
372 d = file->deps;
373 while (d != 0)
375 time_t mtime;
377 check_renamed (d->file);
379 mtime = file_mtime (d->file);
380 check_renamed (d->file);
382 if (d->file->updating)
384 error ("Circular %s <- %s dependency dropped.",
385 file->name, d->file->name);
386 if (lastd == 0)
388 file->deps = d->next;
389 free ((char *) d);
390 d = file->deps;
392 else
394 lastd->next = d->next;
395 free ((char *) d);
396 d = lastd->next;
398 continue;
401 d->file->parent = file;
402 dep_status |= check_dep (d->file, depth, this_mtime, &must_make);
403 check_renamed (d->file);
406 register struct file *f = d->file;
407 if (f->double_colon)
408 f = f->double_colon;
411 running |= (f->command_state == cs_running
412 || f->command_state == cs_deps_running);
413 f = f->prev;
415 while (f != 0);
418 if (dep_status != 0 && !keep_going_flag)
419 break;
421 if (!running)
422 d->changed = file_mtime (d->file) != mtime;
424 lastd = d;
425 d = d->next;
428 /* Now we know whether this target needs updating.
429 If it does, update all the intermediate files we depend on. */
431 if (must_make)
433 for (d = file->deps; d != 0; d = d->next)
434 if (d->file->intermediate)
436 time_t mtime = file_mtime (d->file);
437 check_renamed (d->file);
438 d->file->parent = file;
439 dep_status |= update_file (d->file, depth);
440 check_renamed (d->file);
443 register struct file *f = d->file;
444 if (f->double_colon)
445 f = f->double_colon;
448 running |= (f->command_state == cs_running
449 || f->command_state == cs_deps_running);
450 f = f->prev;
452 while (f != 0);
455 if (dep_status != 0 && !keep_going_flag)
456 break;
458 if (!running)
459 d->changed = ((file->phony && file->cmds != 0)
460 || file_mtime (d->file) != mtime);
464 file->updating = 0;
466 DEBUGPR ("Finished dependencies of target file `%s'.\n");
468 if (running)
470 set_command_state (file, cs_deps_running);
471 --depth;
472 DEBUGPR ("The dependencies of `%s' are being made.\n");
473 return 0;
476 /* If any dependency failed, give up now. */
478 if (dep_status != 0)
480 file->update_status = dep_status;
481 notice_finished_file (file);
483 depth--;
485 DEBUGPR ("Giving up on target file `%s'.\n");
487 if (depth == 0 && keep_going_flag
488 && !just_print_flag && !question_flag)
489 error ("Target `%s' not remade because of errors.", file->name);
491 return dep_status;
494 set_command_state (file, cs_not_started);
496 /* Now record which dependencies are more
497 recent than this file, so we can define $?. */
499 deps_changed = 0;
500 for (d = file->deps; d != 0; d = d->next)
502 time_t d_mtime = file_mtime (d->file);
503 check_renamed (d->file);
505 #if 1 /* %%% In version 4, remove this code completely to
506 implement not remaking deps if their deps are newer
507 than their parents. */
508 if (d_mtime == (time_t) -1 && !d->file->intermediate)
509 /* We must remake if this dep does not
510 exist and is not intermediate. */
511 must_make = 1;
512 #endif
514 /* Set DEPS_CHANGED if this dep actually changed. */
515 deps_changed |= d->changed;
517 /* Set D->changed if either this dep actually changed,
518 or its dependent, FILE, is older or does not exist. */
519 d->changed |= noexist || d_mtime > this_mtime;
521 if (debug_flag && !noexist)
523 print_spaces (depth);
524 if (d_mtime == (time_t) -1)
525 printf ("Dependency `%s' does not exist.\n", dep_name (d));
526 else
527 printf ("Dependency `%s' is %s than dependent `%s'.\n",
528 dep_name (d), d->changed ? "newer" : "older", file->name);
529 fflush (stdout);
533 /* Here depth returns to the value it had when we were called. */
534 depth--;
536 if (file->double_colon && file->deps == 0)
538 must_make = 1;
539 DEBUGPR ("Target `%s' is double-colon and has no dependencies.\n");
541 else if (!noexist && file->is_target && !deps_changed && file->cmds == 0)
543 must_make = 0;
544 DEBUGPR ("No commands for `%s' and no dependencies actually changed.\n");
547 if (!must_make)
549 DEBUGPR ("No need to remake target `%s'.\n");
550 file->update_status = 0;
551 notice_finished_file (file);
552 return 0;
555 DEBUGPR ("Must remake target `%s'.\n");
557 /* Now, take appropriate actions to remake the file. */
558 remake_file (file);
560 if (file->command_state != cs_finished)
562 DEBUGPR ("Commands of `%s' are being run.\n");
563 return 0;
566 switch (file->update_status)
568 case 1:
569 DEBUGPR ("Failed to remake target file `%s'.\n");
570 break;
571 case 0:
572 DEBUGPR ("Successfully remade target file `%s'.\n");
573 break;
574 default:
575 assert (file->update_status == 0 || file->update_status == 1);
576 break;
579 file->updated = 1;
580 return file->update_status;
583 /* Set FILE's `updated' flag and re-check its mtime and the mtime's of all
584 files listed in its `also_make' member. Under -t, this function also
585 touches FILE. */
587 void
588 notice_finished_file (file)
589 register struct file *file;
591 struct dep *d;
592 int ran = file->command_state == cs_running;
594 file->command_state = cs_finished;
595 file->updated = 1;
597 if (touch_flag
598 /* The update status will be:
599 -1 if no commands were run;
600 0 if some commands (+ or ${MAKE}) were run and won;
601 1 if some commands were run and lost.
602 The only time we don't want to touch the target is if
603 it had some recursive commands, and they lost. */
604 && file->update_status != 1)
606 if (file->cmds != 0 && file->cmds->any_recurse)
608 /* If all the command lines were recursive,
609 we don't want to do the touching. */
610 unsigned int i;
611 for (i = 0; i < file->cmds->ncommand_lines; ++i)
612 if (!(file->cmds->lines_flags[i] & COMMANDS_RECURSE))
613 goto have_nonrecursing;
615 else
617 have_nonrecursing:
618 if (file->phony)
619 file->update_status = 0;
620 else
621 /* Should set file's modification date and do nothing else. */
622 file->update_status = touch_file (file);
626 if (ran && !file->phony)
628 struct file *f;
630 if (just_print_flag || question_flag
631 || (file->is_target && file->cmds == 0))
632 file->last_mtime = NEW_MTIME;
633 else
634 file->last_mtime = 0;
636 /* Propagate the change of modification time to all the double-colon
637 entries for this file. */
638 for (f = file->double_colon; f != 0; f = f->next)
639 f->last_mtime = file->last_mtime;
642 if (file->update_status != -1)
643 /* We actually tried to update FILE, which has
644 updated its also_make's as well (if it worked).
645 If it didn't work, it wouldn't work again for them.
646 So mark them as updated with the same status. */
647 for (d = file->also_make; d != 0; d = d->next)
649 d->file->command_state = cs_finished;
650 d->file->updated = 1;
651 d->file->update_status = file->update_status;
653 if (ran && !d->file->phony)
654 /* Fetch the new modification time.
655 We do this instead of just invalidating the cached time
656 so that a vpath_search can happen. Otherwise, it would
657 never be done because the target is already updated. */
658 (void) f_mtime (d->file, 0);
662 /* Check whether another file (whose mtime is THIS_MTIME)
663 needs updating on account of a dependency which is file FILE.
664 If it does, store 1 in *MUST_MAKE_PTR.
665 In the process, update any non-intermediate files
666 that FILE depends on (including FILE itself).
667 Return nonzero if any updating failed. */
669 static int
670 check_dep (file, depth, this_mtime, must_make_ptr)
671 struct file *file;
672 unsigned int depth;
673 time_t this_mtime;
674 int *must_make_ptr;
676 register struct dep *d;
677 int dep_status = 0;
679 ++depth;
680 file->updating = 1;
682 if (!file->intermediate)
683 /* If this is a non-intermediate file, update it and record
684 whether it is newer than THIS_MTIME. */
686 time_t mtime;
687 dep_status = update_file (file, depth);
688 check_renamed (file);
689 mtime = file_mtime (file);
690 check_renamed (file);
691 if (mtime == (time_t) -1 || mtime > this_mtime)
692 *must_make_ptr = 1;
694 else
696 /* FILE is an intermediate file.
697 Update all non-intermediate files we depend on, if necessary,
698 and see whether any of them is more recent than the file
699 on whose behalf we are checking. */
700 register struct dep *lastd;
701 lastd = 0;
702 d = file->deps;
703 while (d != 0)
705 if (d->file->updating)
707 error ("Circular %s <- %s dependency dropped.",
708 file->name, d->file->name);
709 if (lastd == 0)
711 file->deps = d->next;
712 free ((char *) d);
713 d = file->deps;
715 else
717 lastd->next = d->next;
718 free ((char *) d);
719 d = lastd->next;
721 continue;
724 d->file->parent = file;
725 dep_status |= check_dep (d->file, depth, this_mtime, must_make_ptr);
726 check_renamed (d->file);
727 if (dep_status != 0 && !keep_going_flag)
728 break;
730 if (d->file->command_state == cs_running
731 || d->file->command_state == cs_deps_running)
732 /* Record that some of FILE's dependencies are still being made.
733 This tells the upper levels to wait on processing it until
734 the commands are finished. */
735 set_command_state (file, cs_deps_running);
737 lastd = d;
738 d = d->next;
742 file->updating = 0;
743 return dep_status;
746 /* Touch FILE. Return zero if successful, one if not. */
748 #define TOUCH_ERROR(call) return (perror_with_name (call, file->name), 1)
750 static int
751 touch_file (file)
752 register struct file *file;
754 if (!silent_flag)
756 printf ("touch %s\n", file->name);
757 fflush (stdout);
760 #ifndef NO_ARCHIVES
761 if (ar_name (file->name))
762 return ar_touch (file->name);
763 else
764 #endif
766 int fd = open (file->name, O_RDWR | O_CREAT, 0666);
768 if (fd < 0)
769 TOUCH_ERROR ("touch: open: ");
770 else
772 struct stat statbuf;
773 char buf;
774 int status;
776 #ifdef EINTR
778 #endif
779 status = fstat (fd, &statbuf);
780 #ifdef EINTR
781 while (status < 0 && errno == EINTR);
782 #endif
783 if (status < 0)
784 TOUCH_ERROR ("touch: fstat: ");
785 /* Rewrite character 0 same as it already is. */
786 if (read (fd, &buf, 1) < 0)
787 TOUCH_ERROR ("touch: read: ");
788 if (lseek (fd, 0L, 0) < 0L)
789 TOUCH_ERROR ("touch: lseek: ");
790 if (write (fd, &buf, 1) < 0)
791 TOUCH_ERROR ("touch: write: ");
792 /* If file length was 0, we just
793 changed it, so change it back. */
794 if (statbuf.st_size == 0)
796 (void) close (fd);
797 fd = open (file->name, O_RDWR | O_TRUNC, 0666);
798 if (fd < 0)
799 TOUCH_ERROR ("touch: open: ");
801 (void) close (fd);
805 return 0;
808 /* Having checked and updated the dependencies of FILE,
809 do whatever is appropriate to remake FILE itself.
810 Return the status from executing FILE's commands. */
812 static void
813 remake_file (file)
814 struct file *file;
816 if (file->cmds == 0)
818 if (file->phony)
819 /* Phony target. Pretend it succeeded. */
820 file->update_status = 0;
821 else if (file->is_target)
822 /* This is a nonexistent target file we cannot make.
823 Pretend it was successfully remade. */
824 file->update_status = 0;
825 else
827 /* This is a dependency file we cannot remake. Fail. */
828 static char noway[] = "No rule to make target";
829 if (keep_going_flag || file->dontcare)
831 if (!file->dontcare)
832 error ("*** %s `%s'.", noway, file->name);
833 file->update_status = 1;
835 else
836 fatal ("%s `%s'", noway, file->name);
839 else
841 chop_commands (file->cmds);
843 if (!touch_flag || file->cmds->any_recurse)
845 execute_file_commands (file);
846 return;
850 /* This does the touching under -t. */
851 notice_finished_file (file);
854 /* Return the mtime of a file, given a `struct file'.
855 Caches the time in the struct file to avoid excess stat calls.
857 If the file is not found, and SEARCH is nonzero, VPATH searching and
858 replacement is done. If that fails, a library (-lLIBNAME) is tried and
859 the library's actual name (/lib/libLIBNAME.a, etc.) is substituted into
860 FILE. */
862 time_t
863 f_mtime (file, search)
864 register struct file *file;
865 int search;
867 time_t mtime;
869 /* File's mtime is not known; must get it from the system. */
871 #ifndef NO_ARCHIVES
872 if (ar_name (file->name))
874 /* This file is an archive-member reference. */
876 char *arname, *memname;
877 struct file *arfile;
878 int arname_used = 0;
880 /* Find the archive's name. */
881 ar_parse_name (file->name, &arname, &memname);
883 /* Find the modification time of the archive itself.
884 Also allow for its name to be changed via VPATH search. */
885 arfile = lookup_file (arname);
886 if (arfile == 0)
888 arfile = enter_file (arname);
889 arname_used = 1;
891 mtime = f_mtime (arfile, search);
892 check_renamed (arfile);
893 if (search && strcmp (arfile->name, arname))
895 /* The archive's name has changed.
896 Change the archive-member reference accordingly. */
898 unsigned int arlen, memlen;
900 if (!arname_used)
902 free (arname);
903 arname_used = 1;
906 arname = arfile->name;
907 arlen = strlen (arname);
908 memlen = strlen (memname);
910 free (file->name);
912 file->name = (char *) xmalloc (arlen + 1 + memlen + 2);
913 bcopy (arname, file->name, arlen);
914 file->name[arlen] = '(';
915 bcopy (memname, file->name + arlen + 1, memlen);
916 file->name[arlen + 1 + memlen] = ')';
917 file->name[arlen + 1 + memlen + 1] = '\0';
920 if (!arname_used)
921 free (arname);
922 free (memname);
924 if (mtime == (time_t) -1)
925 /* The archive doesn't exist, so it's members don't exist either. */
926 return (time_t) -1;
928 mtime = ar_member_date (file->name);
930 else
931 #endif
933 mtime = name_mtime (file->name);
935 if (mtime == (time_t) -1 && search)
937 /* If name_mtime failed, search VPATH. */
938 char *name = file->name;
939 if (vpath_search (&name, &mtime)
940 /* Last resort, is it a library (-lxxx)? */
941 || (name[0] == '-' && name[1] == 'l'
942 && library_search (&name, &mtime)))
944 if (mtime != 0)
945 /* vpath_search and library_search store zero in MTIME
946 if they didn't need to do a stat call for their work. */
947 file->last_mtime = mtime;
948 rename_file (file, name);
949 check_renamed (file);
950 return file_mtime (file);
955 /* Store the mtime into all the entries for this file. */
956 if (file->double_colon)
957 file = file->double_colon;
960 file->last_mtime = mtime;
961 file = file->prev;
962 } while (file != 0);
964 return mtime;
968 /* Return the mtime of the file or archive-member reference NAME. */
970 static time_t
971 name_mtime (name)
972 register char *name;
974 struct stat st;
976 if (safe_stat (name, &st) < 0)
977 return (time_t) -1;
979 return (time_t) st.st_mtime;
983 /* Search for a library file specified as -lLIBNAME, searching for a
984 suitable library file in the system library directories and the VPATH
985 directories. */
987 static int
988 library_search (lib, mtime_ptr)
989 char **lib;
990 time_t *mtime_ptr;
992 static char *dirs[] =
994 "/lib",
995 "/usr/lib",
996 LIBDIR, /* Defined by configuration. */
1000 char *libname = &(*lib)[2]; /* Name without the `-l'. */
1001 time_t mtime;
1003 /* Buffer to construct possible names in. */
1004 char *buf = xmalloc (sizeof (LIBDIR) + 8 + strlen (libname) + 4 + 2 + 1);
1005 char *file, **dp;
1007 /* Look first for `libNAME.a' in the current directory. */
1009 sprintf (buf, "lib%s.a", libname);
1010 mtime = name_mtime (buf);
1011 if (mtime != (time_t) -1)
1013 *lib = buf;
1014 if (mtime_ptr != 0)
1015 *mtime_ptr = mtime;
1016 return 1;
1019 /* Now try VPATH search on that. */
1021 file = buf;
1022 if (vpath_search (&file, mtime_ptr))
1024 free (buf);
1025 *lib = file;
1026 return 1;
1029 /* Now try the standard set of directories. */
1031 for (dp = dirs; *dp != 0; ++dp)
1033 sprintf (buf, "%s/lib%s.a", *dp, libname);
1034 mtime = name_mtime (buf);
1035 if (mtime != (time_t) -1)
1037 *lib = buf;
1038 if (mtime_ptr != 0)
1039 *mtime_ptr = mtime;
1040 return 1;
1044 free (buf);
1045 return 0;