Formerly default.c.~31~
[make.git] / remake.c
blob06f26010b37a2f5d0701f8dfc99e9d504eaea67d
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
344 DEBUGPR ("No implicit rule found for `%s'.\n");
345 file->tried_implicit = 1;
347 if (file->cmds == 0 && !file->is_target
348 && default_file != 0 && default_file->cmds != 0)
350 DEBUGPR ("Using default commands for `%s'.\n");
351 file->cmds = default_file->cmds;
354 /* Update all non-intermediate files we depend on, if necessary,
355 and see whether any of them is more recent than this file. */
357 lastd = 0;
358 d = file->deps;
359 while (d != 0)
361 time_t mtime;
363 check_renamed (d->file);
365 mtime = file_mtime (d->file);
366 check_renamed (d->file);
368 if (d->file->updating)
370 error ("Circular %s <- %s dependency dropped.",
371 file->name, d->file->name);
372 if (lastd == 0)
374 file->deps = d->next;
375 free ((char *) d);
376 d = file->deps;
378 else
380 lastd->next = d->next;
381 free ((char *) d);
382 d = lastd->next;
384 continue;
387 d->file->parent = file;
388 dep_status |= check_dep (d->file, depth, this_mtime, &must_make);
389 check_renamed (d->file);
392 register struct file *f = d->file;
395 running |= (f->command_state == cs_running
396 || f->command_state == cs_deps_running);
397 f = f->prev;
399 while (f != 0);
402 if (dep_status != 0 && !keep_going_flag)
403 break;
405 if (!running)
406 d->changed = file_mtime (d->file) != mtime;
408 lastd = d;
409 d = d->next;
412 /* Now we know whether this target needs updating.
413 If it does, update all the intermediate files we depend on. */
415 if (must_make)
417 for (d = file->deps; d != 0; d = d->next)
418 if (d->file->intermediate)
420 time_t mtime = file_mtime (d->file);
421 check_renamed (d->file);
422 d->file->parent = file;
423 dep_status |= update_file (d->file, depth);
424 check_renamed (d->file);
427 register struct file *f = d->file;
430 running |= (f->command_state == cs_running
431 || f->command_state == cs_deps_running);
432 f = f->prev;
434 while (f != 0);
437 if (dep_status != 0 && !keep_going_flag)
438 break;
440 if (!running)
441 d->changed = ((file->phony && file->cmds != 0)
442 || file_mtime (d->file) != mtime);
446 file->updating = 0;
448 DEBUGPR ("Finished dependencies of target file `%s'.\n");
450 if (running)
452 file->command_state = cs_deps_running;
453 --depth;
454 DEBUGPR ("The dependencies of `%s' are being made.\n");
455 return 0;
458 /* If any dependency failed, give up now. */
460 if (dep_status != 0)
462 file->command_state = cs_finished;
463 file->update_status = dep_status;
464 file->updated = 1;
466 depth--;
468 DEBUGPR ("Giving up on target file `%s'.\n");
470 if (depth == 0 && keep_going_flag
471 && !just_print_flag && !question_flag)
472 error ("Target `%s' not remade because of errors.", file->name);
474 return dep_status;
477 file->command_state = cs_not_started;
479 /* Now record which dependencies are more
480 recent than this file, so we can define $?. */
482 deps_changed = 0;
483 for (d = file->deps; d != 0; d = d->next)
485 time_t d_mtime = file_mtime (d->file);
486 check_renamed (d->file);
488 #if 1 /* %%% In version 4, remove this code completely to
489 implement not remaking deps if their deps are newer
490 than their parents. */
491 if (d_mtime == (time_t) -1 && !d->file->intermediate)
492 /* We must remake if this dep does not
493 exist and is not intermediate. */
494 must_make = 1;
495 #endif
497 /* Set DEPS_CHANGED if this dep actually changed. */
498 deps_changed |= d->changed;
500 /* Set D->changed if either this dep actually changed,
501 or its dependent, FILE, is older or does not exist. */
502 d->changed |= noexist || d_mtime > this_mtime;
504 if (debug_flag && !noexist)
506 print_spaces (depth);
507 if (d_mtime == (time_t) -1)
508 printf ("Dependency `%s' does not exist.\n", dep_name (d));
509 else
510 printf ("Dependency `%s' is %s than dependent `%s'.\n",
511 dep_name (d), d->changed ? "newer" : "older", file->name);
512 fflush (stdout);
516 /* Here depth returns to the value it had when we were called. */
517 depth--;
519 if (file->double_colon && file->deps == 0)
521 must_make = 1;
522 DEBUGPR ("Target `%s' is double-colon and has no dependencies.\n");
524 else if (!noexist && file->is_target && !deps_changed && file->cmds == 0)
526 must_make = 0;
527 DEBUGPR ("No commands for `%s' and no dependencies actually changed.\n");
530 if (!must_make)
532 DEBUGPR ("No need to remake target `%s'.\n");
533 file->command_state = cs_finished;
534 file->update_status = 0;
535 file->updated = 1;
536 return 0;
539 DEBUGPR ("Must remake target `%s'.\n");
541 /* Now, take appropriate actions to remake the file. */
542 remake_file (file);
544 if (file->command_state != cs_finished)
546 DEBUGPR ("Commands of `%s' are being run.\n");
547 return 0;
550 switch (file->update_status)
552 case 1:
553 DEBUGPR ("Failed to remake target file `%s'.\n");
554 break;
555 case 0:
556 DEBUGPR ("Successfully remade target file `%s'.\n");
557 break;
558 case -1:
559 error ("internal error: `%s' update_status is -1 at cs_finished!",
560 file->name);
561 abort ();
562 default:
563 error ("internal error: `%s' update_status invalid!", file->name);
564 abort ();
567 file->updated = 1;
568 return file->update_status;
571 /* Set FILE's `updated' flag and re-check its mtime and the mtime's of all
572 files listed in its `also_make' member. Under -t, this function also
573 touches FILE. */
575 void
576 notice_finished_file (file)
577 register struct file *file;
579 struct dep *d;
581 file->command_state = cs_finished;
582 file->updated = 1;
584 if (touch_flag
585 /* The update status will be:
586 -1 if no commands were run;
587 0 if some commands (+ or ${MAKE}) were run and won;
588 1 if some commands were run and lost.
589 The only time we don't want to touch the target is if
590 it had some recursive commands, and they lost. */
591 && file->update_status != 1)
593 if (file->cmds != 0 && file->cmds->any_recurse)
595 /* If all the command lines were recursive,
596 we don't want to do the touching. */
597 unsigned int i;
598 for (i = 0; i < file->cmds->ncommand_lines; ++i)
599 if (!(file->cmds->lines_flags[i] & COMMANDS_RECURSE))
600 goto have_nonrecursing;
602 else
604 have_nonrecursing:
605 if (file->phony)
606 file->update_status = 0;
607 else
608 /* Should set file's modification date and do nothing else. */
609 file->update_status = touch_file (file);
613 if (!file->phony)
615 if (just_print_flag || question_flag
616 || (file->is_target && file->cmds == 0))
617 file->last_mtime = NEW_MTIME;
618 else
619 file->last_mtime = 0;
622 if (file->update_status != -1)
623 /* We actually tried to update FILE, which has
624 updated its also_make's as well (if it worked).
625 If it didn't work, it wouldn't work again for them.
626 So mark them as updated with the same status. */
627 for (d = file->also_make; d != 0; d = d->next)
629 d->file->command_state = cs_finished;
630 d->file->updated = 1;
631 d->file->update_status = file->update_status;
633 if (!d->file->phony)
634 /* Fetch the new modification time.
635 We do this instead of just invalidating the cached time
636 so that a vpath_search can happen. Otherwise, it would
637 never be done because the target is already updated. */
638 (void) f_mtime (d->file, 0);
642 /* Check whether another file (whose mtime is THIS_MTIME)
643 needs updating on account of a dependency which is file FILE.
644 If it does, store 1 in *MUST_MAKE_PTR.
645 In the process, update any non-intermediate files
646 that FILE depends on (including FILE itself).
647 Return nonzero if any updating failed. */
649 static int
650 check_dep (file, depth, this_mtime, must_make_ptr)
651 struct file *file;
652 unsigned int depth;
653 time_t this_mtime;
654 int *must_make_ptr;
656 register struct dep *d;
657 int dep_status = 0;
659 ++depth;
660 file->updating = 1;
662 if (!file->intermediate)
663 /* If this is a non-intermediate file, update it and record
664 whether it is newer than THIS_MTIME. */
666 time_t mtime;
667 dep_status = update_file (file, depth);
668 check_renamed (file);
669 mtime = file_mtime (file);
670 check_renamed (file);
671 if (mtime == (time_t) -1 || mtime > this_mtime)
672 *must_make_ptr = 1;
674 else
676 /* FILE is an intermediate file.
677 Update all non-intermediate files we depend on, if necessary,
678 and see whether any of them is more recent than the file
679 on whose behalf we are checking. */
680 register struct dep *lastd;
681 lastd = 0;
682 d = file->deps;
683 while (d != 0)
685 if (d->file->updating)
687 error ("Circular %s <- %s dependency dropped.",
688 file->name, d->file->name);
689 if (lastd == 0)
691 file->deps = d->next;
692 free ((char *) d);
693 d = file->deps;
695 else
697 lastd->next = d->next;
698 free ((char *) d);
699 d = lastd->next;
701 continue;
704 d->file->parent = file;
705 dep_status |= check_dep (d->file, depth, this_mtime, must_make_ptr);
706 check_renamed (d->file);
707 if (dep_status != 0 && !keep_going_flag)
708 break;
710 if (d->file->command_state == cs_running
711 || d->file->command_state == cs_deps_running)
712 /* Record that some of FILE's dependencies are still being made.
713 This tells the upper levels to wait on processing it until
714 the commands are finished. */
715 file->command_state = cs_deps_running;
717 lastd = d;
718 d = d->next;
722 file->updating = 0;
723 return dep_status;
726 /* Touch FILE. Return zero if successful, one if not. */
728 #define TOUCH_ERROR(call) return (perror_with_name (call, file->name), 1)
730 static int
731 touch_file (file)
732 register struct file *file;
734 if (!silent_flag)
736 printf ("touch %s\n", file->name);
737 fflush (stdout);
740 #ifndef NO_ARCHIVES
741 if (ar_name (file->name))
742 return ar_touch (file->name);
743 else
744 #endif
746 int fd = open (file->name, O_RDWR | O_CREAT, 0666);
748 if (fd < 0)
749 TOUCH_ERROR ("touch: open: ");
750 else
752 struct stat statbuf;
753 char buf;
755 if (fstat (fd, &statbuf) < 0)
756 TOUCH_ERROR ("touch: fstat: ");
757 /* Rewrite character 0 same as it already is. */
758 if (read (fd, &buf, 1) < 0)
759 TOUCH_ERROR ("touch: read: ");
760 if (lseek (fd, 0L, 0) < 0L)
761 TOUCH_ERROR ("touch: lseek: ");
762 if (write (fd, &buf, 1) < 0)
763 TOUCH_ERROR ("touch: write: ");
764 /* If file length was 0, we just
765 changed it, so change it back. */
766 if (statbuf.st_size == 0)
768 (void) close (fd);
769 fd = open (file->name, O_RDWR | O_TRUNC, 0666);
770 if (fd < 0)
771 TOUCH_ERROR ("touch: open: ");
773 (void) close (fd);
777 return 0;
780 /* Having checked and updated the dependencies of FILE,
781 do whatever is appropriate to remake FILE itself.
782 Return the status from executing FILE's commands. */
784 static void
785 remake_file (file)
786 struct file *file;
788 if (file->cmds == 0)
790 if (file->phony)
791 /* Phony target. Pretend it succeeded. */
792 file->update_status = 0;
793 else if (file->is_target)
794 /* This is a nonexistent target file we cannot make.
795 Pretend it was successfully remade. */
796 file->update_status = 0;
797 else
799 /* This is a dependency file we cannot remake. Fail. */
800 static char noway[] = "No rule to make target";
801 if (keep_going_flag || file->dontcare)
803 if (!file->dontcare)
804 error ("*** %s `%s'.", noway, file->name);
805 file->update_status = 1;
807 else
808 fatal ("%s `%s'", noway, file->name);
811 else
813 chop_commands (file->cmds);
815 if (!touch_flag || file->cmds->any_recurse)
817 execute_file_commands (file);
818 return;
822 /* This does the touching under -t. */
823 notice_finished_file (file);
826 /* Return the mtime of a file, given a `struct file'.
827 Caches the time in the struct file to avoid excess stat calls.
829 If the file is not found, and SEARCH is nonzero, VPATH searching and
830 replacement is done. If that fails, a library (-lLIBNAME) is tried and
831 the library's actual name (/lib/libLIBNAME.a, etc.) is substituted into
832 FILE. */
834 time_t
835 f_mtime (file, search)
836 register struct file *file;
837 int search;
839 time_t mtime;
841 /* File's mtime is not known; must get it from the system. */
843 #ifndef NO_ARCHIVES
844 if (ar_name (file->name))
846 /* This file is an archive-member reference. */
848 char *arname, *memname;
849 struct file *arfile;
850 int arname_used = 0;
852 /* Find the archive's name. */
853 ar_parse_name (file->name, &arname, &memname);
855 /* Find the modification time of the archive itself.
856 Also allow for its name to be changed via VPATH search. */
857 arfile = lookup_file (arname);
858 if (arfile == 0)
860 arfile = enter_file (arname);
861 arname_used = 1;
863 mtime = f_mtime (arfile, search);
864 check_renamed (arfile);
865 if (search && strcmp (arfile->name, arname))
867 /* The archive's name has changed.
868 Change the archive-member reference accordingly. */
870 unsigned int arlen, memlen;
872 if (!arname_used)
874 free (arname);
875 arname_used = 1;
878 arname = arfile->name;
879 arlen = strlen (arname);
880 memlen = strlen (memname);
882 free (file->name);
884 file->name = (char *) xmalloc (arlen + 1 + memlen + 2);
885 bcopy (arname, file->name, arlen);
886 file->name[arlen] = '(';
887 bcopy (memname, file->name + arlen + 1, memlen);
888 file->name[arlen + 1 + memlen] = ')';
889 file->name[arlen + 1 + memlen + 1] = '\0';
892 if (!arname_used)
893 free (arname);
894 free (memname);
896 if (mtime == (time_t) -1)
897 /* The archive doesn't exist, so it's members don't exist either. */
898 return (time_t) -1;
900 mtime = ar_member_date (file->name);
902 else
903 #endif
905 mtime = name_mtime (file->name);
907 if (mtime == (time_t) -1 && search)
909 /* If name_mtime failed, search VPATH. */
910 char *name = file->name;
911 if (vpath_search (&name, &mtime)
912 /* Last resort, is it a library (-lxxx)? */
913 || (name[0] == '-' && name[1] == 'l'
914 && library_search (&name, &mtime)))
916 if (mtime != 0)
917 /* vpath_search and library_search store zero in MTIME
918 if they didn't need to do a stat call for their work. */
919 file->last_mtime = mtime;
920 rename_file (file, name);
921 check_renamed (file);
922 return file_mtime (file);
927 /* Store the mtime into all the entries for this file. */
930 file->last_mtime = mtime;
931 file = file->prev;
932 } while (file != 0);
934 return mtime;
938 /* Return the mtime of the file or archive-member reference NAME. */
940 static time_t
941 name_mtime (name)
942 register char *name;
944 struct stat st;
946 if (stat (name, &st) < 0)
947 return (time_t) -1;
949 return (time_t) st.st_mtime;
953 /* Search for a library file specified as -lLIBNAME, searching for a
954 suitable library file in the system library directories and the VPATH
955 directories. */
957 static int
958 library_search (lib, mtime_ptr)
959 char **lib;
960 time_t *mtime_ptr;
962 static char *dirs[] =
964 "/lib",
965 "/usr/lib",
966 LIBDIR, /* Defined by configuration. */
970 char *libname = &(*lib)[2]; /* Name without the `-l'. */
971 time_t mtime;
973 /* Buffer to construct possible names in. */
974 char *buf = xmalloc (sizeof (LIBDIR) + 8 + strlen (libname) + 4 + 2 + 1);
975 char *file, **dp;
977 /* Look first for `libNAME.a' in the current directory. */
979 sprintf (buf, "lib%s.a", libname);
980 mtime = name_mtime (buf);
981 if (mtime != (time_t) -1)
983 *lib = buf;
984 if (mtime_ptr != 0)
985 *mtime_ptr = mtime;
986 return 1;
989 /* Now try VPATH search on that. */
991 file = buf;
992 if (vpath_search (&file, mtime_ptr))
994 free (buf);
995 *lib = file;
996 return 1;
999 /* Now try the standard set of directories. */
1001 for (dp = dirs; *dp != 0; ++dp)
1003 sprintf (buf, "%s/lib%s.a", *dp, libname);
1004 mtime = name_mtime (buf);
1005 if (mtime != (time_t) -1)
1007 *lib = buf;
1008 if (mtime_ptr != 0)
1009 *mtime_ptr = mtime;
1010 return 1;
1014 free (buf);
1015 return 0;