Formerly file.c.~24~
[make.git] / remake.c
blob26a253a3b45362a8d5efddc6731180c0fee7a0b6
1 /* Copyright (C) 1988, 1989, 1990, 1991, 1992, 1993
2 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"
25 #ifdef HAVE_FCNTL_H
26 #include <fcntl.h>
27 #else
28 #include <sys/file.h>
29 #endif
31 extern int try_implicit_rule ();
34 /* Incremented when a command is started (under -n, when one would be). */
35 unsigned int commands_started = 0;
37 static int update_file (), update_file_1 (), check_dep (), touch_file ();
38 static void remake_file ();
39 static time_t name_mtime ();
40 static int library_search ();
41 extern time_t f_mtime ();
43 /* Remake all the goals in the `struct dep' chain GOALS. Return -1 if nothing
44 was done, 0 if all goals were updated successfully, or 1 if a goal failed.
45 If MAKEFILES is nonzero, these goals are makefiles, so -t, -q, and -n should
46 be disabled for them unless they were also command-line targets, and we
47 should only make one goal at a time and return as soon as one goal whose
48 `changed' member is nonzero is successfully made. */
50 int
51 update_goal_chain (goals, makefiles)
52 register struct dep *goals;
53 int makefiles;
55 int t = touch_flag, q = question_flag, n = just_print_flag;
56 unsigned int j = job_slots;
57 int status = -1;
59 #define MTIME(file) (makefiles ? file_mtime_no_search (file) \
60 : file_mtime (file))
62 /* Duplicate the chain so we can remove things from it. */
64 goals = copy_dep_chain (goals);
67 /* Clear the `changed' flag of each goal in the chain.
68 We will use the flag below to notice when any commands
69 have actually been run for a target. When no commands
70 have been run, we give an "up to date" diagnostic. */
72 struct dep *g;
73 for (g = goals; g != 0; g = g->next)
74 g->changed = 0;
77 if (makefiles)
78 /* Only run one job at a time. */
79 job_slots = 1;
81 /* Update all the goals until they are all finished. */
83 while (goals != 0)
85 register struct dep *g, *lastgoal;
87 /* Start jobs that are waiting for the load to go down. */
89 start_waiting_jobs ();
91 /* Wait for a child to die. */
93 reap_children (1, 0);
95 lastgoal = 0;
96 g = goals;
97 while (g != 0)
99 unsigned int ocommands_started;
100 int x;
101 time_t mtime = MTIME (g->file);
102 check_renamed (g->file);
104 if (makefiles)
106 if (g->file->cmd_target)
108 touch_flag = t;
109 question_flag = q;
110 just_print_flag = n;
112 else
113 touch_flag = question_flag = just_print_flag = 0;
116 /* Save the old value of `commands_started' so we can compare later.
117 It will be incremented when any commands are actually run. */
118 ocommands_started = commands_started;
120 x = update_file (g->file, makefiles ? 1 : 0);
121 check_renamed (g->file);
123 /* Set the goal's `changed' flag if any commands were started
124 by calling update_file above. We check this flag below to
125 decide when to give an "up to date" diagnostic. */
126 g->changed += commands_started - ocommands_started;
128 if (x != 0 || g->file->updated)
130 int stop = 0;
132 /* If STATUS was not already 1, set it to 1 if
133 updating failed, or to 0 if updating succeeded.
134 Leave STATUS as it is if no updating was done. */
136 if (status < 1)
138 if (g->file->update_status != 0)
140 /* Updating failed. */
141 status = 1;
142 stop = !keep_going_flag && !makefiles;
144 else if (MTIME (g->file) != mtime)
146 /* Updating was done.
147 If this is a makefile and just_print_flag or
148 question_flag is set (meaning -n or -q was given
149 and this file was specified as a command-line target),
150 don't change STATUS. If STATUS is changed, we will
151 get re-exec'd, and fall into an infinite loop. */
152 if (!makefiles || (!just_print_flag && !question_flag))
153 status = 0;
154 if (makefiles && g->file->dontcare)
155 /* This is a default makefile. Stop remaking. */
156 stop = 1;
160 if (stop || g->file->prev == 0)
162 /* If we have found nothing whatever to do for the goal,
163 print a message saying nothing needs doing. */
165 if (!makefiles
166 /* If the update_status is zero, we updated successfully
167 or not at all. G->changed will have been set above if
168 any commands were actually started for this goal. */
169 && g->file->update_status == 0 && !g->changed
170 /* Never give a message under -s or -q. */
171 && !silent_flag && !question_flag)
173 if (g->file->phony || g->file->cmds == 0)
174 message ("Nothing to be done for `%s'.",
175 g->file->name);
176 else
177 message ("`%s' is up to date.", g->file->name);
178 fflush (stdout);
181 /* This goal is finished. Remove it from the chain. */
182 if (lastgoal == 0)
183 goals = g->next;
184 else
185 lastgoal->next = g->next;
187 /* Free the storage. */
188 free ((char *) g);
190 g = lastgoal == 0 ? goals : lastgoal->next;
192 else if (g->file->updated)
193 /* This instance of the target is done being updated.
194 Go to the next instance (:: rule).
195 update_file cycles through all instances, but under -j,
196 update_file can return while the file is running,
197 then reap_children can change its command state and
198 updated flag, leaving G->file done, but some of its
199 other instances needing work. */
200 g->file = g->file->prev;
202 if (stop)
203 break;
205 else
207 lastgoal = g;
208 g = g->next;
213 if (makefiles)
215 touch_flag = t;
216 question_flag = q;
217 just_print_flag = n;
218 job_slots = j;
221 return status;
224 /* If FILE is not up to date, execute the commands for it.
225 Return 0 if successful, 1 if unsuccessful;
226 but with some flag settings, just call `exit' if unsuccessful.
228 DEPTH is the depth in recursions of this function.
229 We increment it during the consideration of our dependencies,
230 then decrement it again after finding out whether this file
231 is out of date.
233 If there are multiple double-colon entries for FILE,
234 each is considered in turn. */
236 static int
237 update_file (file, depth)
238 struct file *file;
239 unsigned int depth;
241 register int status = 0;
242 register struct file *f;
244 for (f = file; f != 0; f = f->prev)
246 status |= update_file_1 (f, depth);
247 check_renamed (f);
249 if (status != 0 && !keep_going_flag)
250 return status;
252 switch (f->command_state)
254 case cs_finished:
255 /* The file is done being remade. */
256 break;
258 case cs_running:
259 case cs_deps_running:
260 /* Don't run the other :: rules for this
261 file until this rule is finished. */
262 return 0;
264 default:
265 error ("internal error: `%s' command_state == %d in update_file",
266 f->name, (int) f->command_state);
267 abort ();
268 break;
272 return status;
275 /* Consider a single `struct file' and update it as appropriate. */
277 static int
278 update_file_1 (file, depth)
279 struct file *file;
280 unsigned int depth;
282 register time_t this_mtime;
283 int noexist, must_make, deps_changed;
284 int dep_status = 0;
285 register struct dep *d, *lastd;
286 int running = 0;
288 DEBUGPR ("Considering target file `%s'.\n");
290 if (file->updated)
292 if (file->update_status > 0)
294 DEBUGPR ("Recently tried and failed to update file `%s'.\n");
295 return file->update_status;
298 DEBUGPR ("File `%s' was considered already.\n");
299 return 0;
302 switch (file->command_state)
304 case cs_not_started:
305 case cs_deps_running:
306 break;
307 case cs_running:
308 DEBUGPR ("Still updating file `%s'.\n");
309 return 0;
310 case cs_finished:
311 DEBUGPR ("Finished updating file `%s'.\n");
312 return file->update_status;
313 default:
314 abort ();
317 ++depth;
319 /* Notice recursive update of the same file. */
320 file->updating = 1;
322 /* Looking at the file's modtime beforehand allows the possibility
323 that its name may be changed by a VPATH search, and thus it may
324 not need an implicit rule. If this were not done, the file
325 might get implicit commands that apply to its initial name, only
326 to have that name replaced with another found by VPATH search. */
328 this_mtime = file_mtime (file);
329 check_renamed (file);
330 noexist = this_mtime == (time_t) -1;
331 if (noexist)
332 DEBUGPR ("File `%s' does not exist.\n");
334 must_make = noexist;
336 /* If file was specified as a target with no commands,
337 come up with some default commands. */
339 if (!file->phony && file->cmds == 0 && !file->tried_implicit)
341 if (try_implicit_rule (file, depth))
342 DEBUGPR ("Found an implicit rule for `%s'.\n");
343 else
345 DEBUGPR ("No implicit rule found for `%s'.\n");
346 if (!file->is_target
347 && default_file != 0 && default_file->cmds != 0)
349 DEBUGPR ("Using default commands for `%s'.\n");
350 file->cmds = default_file->cmds;
353 file->tried_implicit = 1;
356 /* Update all non-intermediate files we depend on, if necessary,
357 and see whether any of them is more recent than this file. */
359 lastd = 0;
360 d = file->deps;
361 while (d != 0)
363 time_t mtime;
365 check_renamed (d->file);
367 mtime = file_mtime (d->file);
368 check_renamed (d->file);
370 if (d->file->updating)
372 error ("Circular %s <- %s dependency dropped.",
373 file->name, d->file->name);
374 if (lastd == 0)
376 file->deps = d->next;
377 free ((char *) d);
378 d = file->deps;
380 else
382 lastd->next = d->next;
383 free ((char *) d);
384 d = lastd->next;
386 continue;
389 d->file->parent = file;
390 dep_status |= check_dep (d->file, depth, this_mtime, &must_make);
391 check_renamed (d->file);
394 register struct file *f = d->file;
397 running |= (f->command_state == cs_running
398 || f->command_state == cs_deps_running);
399 f = f->prev;
401 while (f != 0);
404 if (dep_status != 0 && !keep_going_flag)
405 break;
407 if (!running)
408 d->changed = file_mtime (d->file) != mtime;
410 lastd = d;
411 d = d->next;
414 /* Now we know whether this target needs updating.
415 If it does, update all the intermediate files we depend on. */
417 if (must_make)
419 for (d = file->deps; d != 0; d = d->next)
420 if (d->file->intermediate)
422 time_t mtime = file_mtime (d->file);
423 check_renamed (d->file);
424 d->file->parent = file;
425 dep_status |= update_file (d->file, depth);
426 check_renamed (d->file);
429 register struct file *f = d->file;
432 running |= (f->command_state == cs_running
433 || f->command_state == cs_deps_running);
434 f = f->prev;
436 while (f != 0);
439 if (dep_status != 0 && !keep_going_flag)
440 break;
442 if (!running)
443 d->changed = ((file->phony && file->cmds != 0)
444 || file_mtime (d->file) != mtime);
448 file->updating = 0;
450 DEBUGPR ("Finished dependencies of target file `%s'.\n");
452 if (running)
454 file->command_state = cs_deps_running;
455 --depth;
456 DEBUGPR ("The dependencies of `%s' are being made.\n");
457 return 0;
460 /* If any dependency failed, give up now. */
462 if (dep_status != 0)
464 file->command_state = cs_finished;
465 file->update_status = dep_status;
466 file->updated = 1;
468 depth--;
470 DEBUGPR ("Giving up on target file `%s'.\n");
472 if (depth == 0 && keep_going_flag
473 && !just_print_flag && !question_flag)
474 error ("Target `%s' not remade because of errors.", file->name);
476 return dep_status;
479 file->command_state = cs_not_started;
481 /* Now record which dependencies are more
482 recent than this file, so we can define $?. */
484 deps_changed = 0;
485 for (d = file->deps; d != 0; d = d->next)
487 time_t d_mtime = file_mtime (d->file);
488 check_renamed (d->file);
490 #if 1 /* %%% In version 4, remove this code completely to
491 implement not remaking deps if their deps are newer
492 than their parents. */
493 if (d_mtime == (time_t) -1 && !d->file->intermediate)
494 /* We must remake if this dep does not
495 exist and is not intermediate. */
496 must_make = 1;
497 #endif
499 /* Set DEPS_CHANGED if this dep actually changed. */
500 deps_changed |= d->changed;
502 /* Set D->changed if either this dep actually changed,
503 or its dependent, FILE, is older or does not exist. */
504 d->changed |= noexist || d_mtime > this_mtime;
506 if (debug_flag && !noexist)
508 print_spaces (depth);
509 if (d_mtime == (time_t) -1)
510 printf ("Dependency `%s' does not exist.\n", dep_name (d));
511 else
512 printf ("Dependency `%s' is %s than dependent `%s'.\n",
513 dep_name (d), d->changed ? "newer" : "older", file->name);
514 fflush (stdout);
518 /* Here depth returns to the value it had when we were called. */
519 depth--;
521 if (file->double_colon && file->deps == 0)
523 must_make = 1;
524 DEBUGPR ("Target `%s' is double-colon and has no dependencies.\n");
526 else if (file->is_target && !deps_changed && file->cmds == 0)
528 must_make = 0;
529 DEBUGPR ("No commands for `%s' and no dependencies actually changed.\n");
532 if (!must_make)
534 DEBUGPR ("No need to remake target `%s'.\n");
535 file->command_state = cs_finished;
536 file->update_status = 0;
537 file->updated = 1;
538 return 0;
541 DEBUGPR ("Must remake target `%s'.\n");
543 /* Now, take appropriate actions to remake the file. */
544 remake_file (file);
546 if (file->command_state != cs_finished)
548 DEBUGPR ("Commands of `%s' are being run.\n");
549 return 0;
552 switch (file->update_status)
554 case 1:
555 DEBUGPR ("Failed to remake target file `%s'.\n");
556 break;
557 case 0:
558 DEBUGPR ("Successfully remade target file `%s'.\n");
559 break;
560 case -1:
561 error ("internal error: `%s' update_status is -1 at cs_finished!",
562 file->name);
563 abort ();
564 default:
565 error ("internal error: `%s' update_status invalid!", file->name);
566 abort ();
569 file->updated = 1;
570 return file->update_status;
573 /* Set FILE's `updated' flag and re-check its mtime and the mtime's of all
574 files listed in its `also_make' member. Under -t, this function also
575 touches FILE. */
577 void
578 notice_finished_file (file)
579 register struct file *file;
581 struct dep *d;
583 file->command_state = cs_finished;
584 file->updated = 1;
586 if (touch_flag
587 /* The update status will be:
588 -1 if no commands were run;
589 0 if some commands (+ or ${MAKE}) were run and won;
590 1 if some commands were run and lost.
591 The only time we don't want to touch the target is if
592 it had some recursive commands, and they lost. */
593 && file->update_status != 1)
595 if (file->cmds != 0 && file->cmds->any_recurse)
597 /* If all the command lines were recursive,
598 we don't want to do the touching. */
599 unsigned int i;
600 for (i = 0; i < file->cmds->ncommand_lines; ++i)
601 if (!(file->cmds->lines_flags[i] & COMMANDS_RECURSE))
602 goto have_nonrecursing;
604 else
606 have_nonrecursing:
607 if (file->phony)
608 file->update_status = 0;
609 else
610 /* Should set file's modification date and do nothing else. */
611 file->update_status = touch_file (file);
615 if (!file->phony)
617 if (just_print_flag || question_flag
618 || (file->is_target && file->cmds == 0))
619 file->last_mtime = time ((time_t *) 0);
620 else
621 file->last_mtime = 0;
624 if (file->update_status != -1)
625 /* We actually tried to update FILE, which has
626 updated its also_make's as well (if it worked).
627 If it didn't work, it wouldn't work again for them.
628 So mark them as updated with the same status. */
629 for (d = file->also_make; d != 0; d = d->next)
631 d->file->command_state = cs_finished;
632 d->file->updated = 1;
633 d->file->update_status = file->update_status;
635 if (!d->file->phony)
636 /* Fetch the new modification time.
637 We do this instead of just invalidating the cached time
638 so that a vpath_search can happen. Otherwise, it would
639 never be done because the target is already updated. */
640 (void) f_mtime (d->file, 0);
644 /* Check whether another file (whose mtime is THIS_MTIME)
645 needs updating on account of a dependency which is file FILE.
646 If it does, store 1 in *MUST_MAKE_PTR.
647 In the process, update any non-intermediate files
648 that FILE depends on (including FILE itself).
649 Return nonzero if any updating failed. */
651 static int
652 check_dep (file, depth, this_mtime, must_make_ptr)
653 struct file *file;
654 unsigned int depth;
655 time_t this_mtime;
656 int *must_make_ptr;
658 register struct dep *d;
659 int dep_status = 0;
661 ++depth;
662 file->updating = 1;
664 if (!file->intermediate)
665 /* If this is a non-intermediate file, update it and record
666 whether it is newer than THIS_MTIME. */
668 time_t mtime;
669 dep_status = update_file (file, depth);
670 check_renamed (file);
671 mtime = file_mtime (file);
672 check_renamed (file);
673 if (mtime == (time_t) -1 || mtime > this_mtime)
674 *must_make_ptr = 1;
676 else
678 /* FILE is an intermediate file.
679 Update all non-intermediate files we depend on, if necessary,
680 and see whether any of them is more recent than the file
681 on whose behalf we are checking. */
682 register struct dep *lastd;
683 lastd = 0;
684 d = file->deps;
685 while (d != 0)
687 if (d->file->updating)
689 error ("Circular %s <- %s dependency dropped.",
690 file->name, d->file->name);
691 if (lastd == 0)
693 file->deps = d->next;
694 free ((char *) d);
695 d = file->deps;
697 else
699 lastd->next = d->next;
700 free ((char *) d);
701 d = lastd->next;
703 continue;
706 d->file->parent = file;
707 dep_status |= check_dep (d->file, depth, this_mtime, must_make_ptr);
708 check_renamed (d->file);
709 if (dep_status != 0 && !keep_going_flag)
710 break;
712 if (d->file->command_state == cs_running
713 || d->file->command_state == cs_deps_running)
714 /* Record that some of FILE's dependencies are still being made.
715 This tells the upper levels to wait on processing it until
716 the commands are finished. */
717 file->command_state = cs_deps_running;
719 lastd = d;
720 d = d->next;
724 file->updating = 0;
725 return dep_status;
728 /* Touch FILE. Return zero if successful, one if not. */
730 #define TOUCH_ERROR(call) return (perror_with_name (call, file->name), 1)
732 static int
733 touch_file (file)
734 register struct file *file;
736 if (!silent_flag)
738 printf ("touch %s\n", file->name);
739 fflush (stdout);
742 #ifndef NO_ARCHIVES
743 if (ar_name (file->name))
744 return ar_touch (file->name);
745 else
746 #endif
748 int fd = open (file->name, O_RDWR | O_CREAT, 0666);
750 if (fd < 0)
751 TOUCH_ERROR ("touch: open: ");
752 else
754 struct stat statbuf;
755 char buf;
757 if (fstat (fd, &statbuf) < 0)
758 TOUCH_ERROR ("touch: fstat: ");
759 /* Rewrite character 0 same as it already is. */
760 if (read (fd, &buf, 1) < 0)
761 TOUCH_ERROR ("touch: read: ");
762 if (lseek (fd, 0L, 0) < 0L)
763 TOUCH_ERROR ("touch: lseek: ");
764 if (write (fd, &buf, 1) < 0)
765 TOUCH_ERROR ("touch: write: ");
766 /* If file length was 0, we just
767 changed it, so change it back. */
768 if (statbuf.st_size == 0)
770 (void) close (fd);
771 fd = open (file->name, O_RDWR | O_TRUNC, 0666);
772 if (fd < 0)
773 TOUCH_ERROR ("touch: open: ");
775 (void) close (fd);
779 return 0;
782 /* Having checked and updated the dependencies of FILE,
783 do whatever is appropriate to remake FILE itself.
784 Return the status from executing FILE's commands. */
786 static void
787 remake_file (file)
788 struct file *file;
790 if (file->cmds == 0)
792 if (file->phony)
793 /* Phony target. Pretend it succeeded. */
794 file->update_status = 0;
795 else if (file->is_target)
796 /* This is a nonexistent target file we cannot make.
797 Pretend it was successfully remade. */
798 file->update_status = 0;
799 else
801 /* This is a dependency file we cannot remake. Fail. */
802 static char noway[] = "No rule to make target";
803 if (keep_going_flag || file->dontcare)
805 if (!file->dontcare)
806 error ("*** %s `%s'.", noway, file->name);
807 file->update_status = 1;
809 else
810 fatal ("%s `%s'", noway, file->name);
813 else
815 chop_commands (file->cmds);
817 if (!touch_flag || file->cmds->any_recurse)
819 execute_file_commands (file);
820 return;
824 /* This does the touching under -t. */
825 notice_finished_file (file);
828 /* Return the mtime of a file, given a `struct file'.
829 Caches the time in the struct file to avoid excess stat calls.
831 If the file is not found, and SEARCH is nonzero, VPATH searching and
832 replacement is done. If that fails, a library (-lLIBNAME) is tried and
833 the library's actual name (/lib/libLIBNAME.a, etc.) is substituted into
834 FILE. */
836 time_t
837 f_mtime (file, search)
838 register struct file *file;
839 int search;
841 time_t mtime;
843 /* File's mtime is not known; must get it from the system. */
845 #ifndef NO_ARCHIVES
846 if (ar_name (file->name))
848 /* This file is an archive-member reference. */
850 char *arname, *memname;
851 struct file *arfile;
852 int arname_used = 0;
854 /* Find the archive's name. */
855 ar_parse_name (file->name, &arname, &memname);
857 /* Find the modification time of the archive itself.
858 Also allow for its name to be changed via VPATH search. */
859 arfile = lookup_file (arname);
860 if (arfile == 0)
862 arfile = enter_file (arname);
863 arname_used = 1;
865 mtime = f_mtime (arfile, search);
866 check_renamed (arfile);
867 if (search && strcmp (arfile->name, arname))
869 /* The archive's name has changed.
870 Change the archive-member reference accordingly. */
872 unsigned int arlen, memlen;
874 if (!arname_used)
876 free (arname);
877 arname_used = 1;
880 arname = arfile->name;
881 arlen = strlen (arname);
882 memlen = strlen (memname);
884 free (file->name);
886 file->name = (char *) xmalloc (arlen + 1 + memlen + 2);
887 bcopy (arname, file->name, arlen);
888 file->name[arlen] = '(';
889 bcopy (memname, file->name + arlen + 1, memlen);
890 file->name[arlen + 1 + memlen] = ')';
891 file->name[arlen + 1 + memlen + 1] = '\0';
894 if (!arname_used)
895 free (arname);
896 free (memname);
898 if (mtime == (time_t) -1)
899 /* The archive doesn't exist, so it's members don't exist either. */
900 return (time_t) -1;
902 mtime = ar_member_date (file->name);
904 else
905 #endif
907 mtime = name_mtime (file->name);
909 if (mtime == (time_t) -1 && search)
911 /* If name_mtime failed, search VPATH. */
912 char *name = file->name;
913 if (vpath_search (&name, &mtime)
914 /* Last resort, is it a library (-lxxx)? */
915 || (name[0] == '-' && name[1] == 'l'
916 && library_search (&name, &mtime)))
918 if (mtime != 0)
919 /* vpath_search and library_search store zero in MTIME
920 if they didn't need to do a stat call for their work. */
921 file->last_mtime = mtime;
922 rename_file (file, name);
923 check_renamed (file);
924 return file_mtime (file);
929 /* Store the mtime into all the entries for this file. */
932 file->last_mtime = mtime;
933 file = file->prev;
934 } while (file != 0);
936 return mtime;
940 /* Return the mtime of the file or archive-member reference NAME. */
942 static time_t
943 name_mtime (name)
944 register char *name;
946 struct stat st;
948 if (stat (name, &st) < 0)
949 return (time_t) -1;
951 return (time_t) st.st_mtime;
955 /* Search for a library file specified as -lLIBNAME, searching for a
956 suitable library file in the system library directories and the VPATH
957 directories. */
959 static int
960 library_search (lib, mtime_ptr)
961 char **lib;
962 time_t *mtime_ptr;
964 static char *dirs[] =
966 "/lib",
967 "/usr/lib",
968 LIBDIR, /* Defined by configuration. */
972 char *libname = &(*lib)[2]; /* Name without the `-l'. */
973 time_t mtime;
975 /* Buffer to construct possible names in. */
976 char *buf = xmalloc (sizeof (LIBDIR) + 8 + strlen (libname) + 4 + 2 + 1);
977 char *file, **dp;
979 /* Look first for `libNAME.a' in the current directory. */
981 sprintf (buf, "lib%s.a", libname);
982 mtime = name_mtime (buf);
983 if (mtime != (time_t) -1)
985 *lib = buf;
986 if (mtime_ptr != 0)
987 *mtime_ptr = mtime;
988 return 1;
991 /* Now try VPATH search on that. */
993 file = buf;
994 if (vpath_search (&file, mtime_ptr))
996 free (buf);
997 *lib = file;
998 return 1;
1001 /* Now try the standard set of directories. */
1003 for (dp = dirs; *dp != 0; ++dp)
1005 sprintf (buf, "%s/lib%s.a", *dp, libname);
1006 mtime = name_mtime (buf);
1007 if (mtime != (time_t) -1)
1009 *lib = buf;
1010 if (mtime_ptr != 0)
1011 *mtime_ptr = mtime;
1012 return 1;
1016 free (buf);
1017 return 0;