1 /* Basic dependency engine for GNU Make.
2 Copyright (C) 1988,89,90,91,92,93,94,95,96 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)
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. */
39 extern int try_implicit_rule
PARAMS ((struct file
*file
, unsigned int depth
));
42 /* Incremented when a command is started (under -n, when one would be). */
43 unsigned int commands_started
= 0;
45 static int update_file
PARAMS ((struct file
*file
, unsigned int depth
));
46 static int update_file_1
PARAMS ((struct file
*file
, unsigned int depth
));
47 static int check_dep
PARAMS ((struct file
*file
, unsigned int depth
, time_t this_mtime
, int *must_make_ptr
));
48 static int touch_file
PARAMS ((struct file
*file
));
49 static void remake_file
PARAMS ((struct file
*file
));
50 static time_t name_mtime
PARAMS ((char *name
));
51 static int library_search
PARAMS ((char **lib
, time_t *mtime_ptr
));
53 extern time_t f_mtime
PARAMS ((struct file
*file
, int search
));
56 extern int vms_stat
PARAMS ((char *name
, struct stat
*buf
));
60 /* Remake all the goals in the `struct dep' chain GOALS. Return -1 if nothing
61 was done, 0 if all goals were updated successfully, or 1 if a goal failed.
62 If MAKEFILES is nonzero, these goals are makefiles, so -t, -q, and -n should
63 be disabled for them unless they were also command-line targets, and we
64 should only make one goal at a time and return as soon as one goal whose
65 `changed' member is nonzero is successfully made. */
68 update_goal_chain (goals
, makefiles
)
69 register struct dep
*goals
;
72 int t
= touch_flag
, q
= question_flag
, n
= just_print_flag
;
73 unsigned int j
= job_slots
;
76 #define MTIME(file) (makefiles ? file_mtime_no_search (file) \
79 /* Duplicate the chain so we can remove things from it. */
81 goals
= copy_dep_chain (goals
);
84 /* Clear the `changed' flag of each goal in the chain.
85 We will use the flag below to notice when any commands
86 have actually been run for a target. When no commands
87 have been run, we give an "up to date" diagnostic. */
90 for (g
= goals
; g
!= 0; g
= g
->next
)
95 /* Only run one job at a time. */
98 /* Update all the goals until they are all finished. */
102 register struct dep
*g
, *lastgoal
;
104 /* Start jobs that are waiting for the load to go down. */
106 start_waiting_jobs ();
108 /* Wait for a child to die. */
110 reap_children (1, 0);
116 /* Iterate over all double-colon entries for this file. */
117 struct file
*file
= g
->file
;
118 int stop
, any_not_updated
= 0;
120 for (file
= g
->file
->double_colon
? g
->file
->double_colon
: g
->file
;
124 unsigned int ocommands_started
;
126 time_t mtime
= MTIME (file
);
127 check_renamed (file
);
130 if (file
->cmd_target
)
137 touch_flag
= question_flag
= just_print_flag
= 0;
140 /* Save the old value of `commands_started' so we can compare
141 later. It will be incremented when any commands are
143 ocommands_started
= commands_started
;
145 x
= update_file (file
, makefiles
? 1 : 0);
146 check_renamed (file
);
148 /* Set the goal's `changed' flag if any commands were started
149 by calling update_file above. We check this flag below to
150 decide when to give an "up to date" diagnostic. */
151 g
->changed
+= commands_started
- ocommands_started
;
154 if (x
!= 0 || file
->updated
)
156 /* If STATUS was not already 1, set it to 1 if
157 updating failed, or to 0 if updating succeeded.
158 Leave STATUS as it is if no updating was done. */
162 if (file
->update_status
!= 0)
164 /* Updating failed, or -q triggered.
165 The STATUS value tells our caller which. */
166 status
= file
->update_status
;
167 /* If -q just triggered, stop immediately.
168 It doesn't matter how much more we run,
169 since we already know the answer to return. */
170 stop
= (!keep_going_flag
&& !question_flag
173 else if (MTIME (file
) != mtime
)
175 /* Updating was done. If this is a makefile and
176 just_print_flag or question_flag is set
177 (meaning -n or -q was given and this file was
178 specified as a command-line target), don't
179 change STATUS. If STATUS is changed, we will
180 get re-exec'd, and fall into an infinite loop. */
182 || (!just_print_flag
&& !question_flag
))
184 if (makefiles
&& file
->dontcare
)
185 /* This is a default makefile. Stop remaking. */
191 /* Keep track if any double-colon entry is not finished.
192 When they are all finished, the goal is finished. */
193 any_not_updated
|= !file
->updated
;
199 /* Reset FILE since it is null at the end of the loop. */
202 if (stop
|| !any_not_updated
)
204 /* If we have found nothing whatever to do for the goal,
205 print a message saying nothing needs doing. */
208 /* If the update_status is zero, we updated successfully
209 or not at all. G->changed will have been set above if
210 any commands were actually started for this goal. */
211 && file
->update_status
== 0 && !g
->changed
212 /* Never give a message under -s or -q. */
213 && !silent_flag
&& !question_flag
)
214 message (1, ((file
->phony
|| file
->cmds
== 0)
215 ? "Nothing to be done for `%s'."
216 : "`%s' is up to date."),
219 /* This goal is finished. Remove it from the chain. */
223 lastgoal
->next
= g
->next
;
225 /* Free the storage. */
228 g
= lastgoal
== 0 ? goals
: lastgoal
->next
;
251 /* If FILE is not up to date, execute the commands for it.
252 Return 0 if successful, 1 if unsuccessful;
253 but with some flag settings, just call `exit' if unsuccessful.
255 DEPTH is the depth in recursions of this function.
256 We increment it during the consideration of our dependencies,
257 then decrement it again after finding out whether this file
260 If there are multiple double-colon entries for FILE,
261 each is considered in turn. */
264 update_file (file
, depth
)
268 register int status
= 0;
269 register struct file
*f
;
271 for (f
= file
->double_colon
? file
->double_colon
: file
; f
!= 0; f
= f
->prev
)
273 status
|= update_file_1 (f
, depth
);
276 if (status
!= 0 && !keep_going_flag
)
279 switch (f
->command_state
)
282 /* The file is done being remade. */
286 case cs_deps_running
:
287 /* Don't run the other :: rules for this
288 file until this rule is finished. */
292 assert (f
->command_state
== cs_running
);
300 /* Consider a single `struct file' and update it as appropriate. */
303 update_file_1 (file
, depth
)
307 register time_t this_mtime
;
308 int noexist
, must_make
, deps_changed
;
310 register struct dep
*d
, *lastd
;
313 DEBUGPR ("Considering target file `%s'.\n");
317 if (file
->update_status
> 0)
319 DEBUGPR ("Recently tried and failed to update file `%s'.\n");
320 return file
->update_status
;
323 DEBUGPR ("File `%s' was considered already.\n");
327 switch (file
->command_state
)
330 case cs_deps_running
:
333 DEBUGPR ("Still updating file `%s'.\n");
336 DEBUGPR ("Finished updating file `%s'.\n");
337 return file
->update_status
;
344 /* Notice recursive update of the same file. */
347 /* Looking at the file's modtime beforehand allows the possibility
348 that its name may be changed by a VPATH search, and thus it may
349 not need an implicit rule. If this were not done, the file
350 might get implicit commands that apply to its initial name, only
351 to have that name replaced with another found by VPATH search. */
353 this_mtime
= file_mtime (file
);
354 check_renamed (file
);
355 noexist
= this_mtime
== (time_t) -1;
357 DEBUGPR ("File `%s' does not exist.\n");
361 /* If file was specified as a target with no commands,
362 come up with some default commands. */
364 if (!file
->phony
&& file
->cmds
== 0 && !file
->tried_implicit
)
366 if (try_implicit_rule (file
, depth
))
367 DEBUGPR ("Found an implicit rule for `%s'.\n");
369 DEBUGPR ("No implicit rule found for `%s'.\n");
370 file
->tried_implicit
= 1;
372 if (file
->cmds
== 0 && !file
->is_target
373 && default_file
!= 0 && default_file
->cmds
!= 0)
375 DEBUGPR ("Using default commands for `%s'.\n");
376 file
->cmds
= default_file
->cmds
;
379 /* Update all non-intermediate files we depend on, if necessary,
380 and see whether any of them is more recent than this file. */
388 check_renamed (d
->file
);
390 mtime
= file_mtime (d
->file
);
391 check_renamed (d
->file
);
393 if (d
->file
->updating
)
395 error ("Circular %s <- %s dependency dropped.",
396 file
->name
, d
->file
->name
);
399 file
->deps
= d
->next
;
405 lastd
->next
= d
->next
;
412 d
->file
->parent
= file
;
413 dep_status
|= check_dep (d
->file
, depth
, this_mtime
, &must_make
);
414 check_renamed (d
->file
);
417 register struct file
*f
= d
->file
;
422 running
|= (f
->command_state
== cs_running
423 || f
->command_state
== cs_deps_running
);
429 if (dep_status
!= 0 && !keep_going_flag
)
433 d
->changed
= file_mtime (d
->file
) != mtime
;
439 /* Now we know whether this target needs updating.
440 If it does, update all the intermediate files we depend on. */
444 for (d
= file
->deps
; d
!= 0; d
= d
->next
)
445 if (d
->file
->intermediate
)
447 time_t mtime
= file_mtime (d
->file
);
448 check_renamed (d
->file
);
449 d
->file
->parent
= file
;
450 dep_status
|= update_file (d
->file
, depth
);
451 check_renamed (d
->file
);
454 register struct file
*f
= d
->file
;
459 running
|= (f
->command_state
== cs_running
460 || f
->command_state
== cs_deps_running
);
466 if (dep_status
!= 0 && !keep_going_flag
)
470 d
->changed
= ((file
->phony
&& file
->cmds
!= 0)
471 || file_mtime (d
->file
) != mtime
);
477 DEBUGPR ("Finished dependencies of target file `%s'.\n");
481 set_command_state (file
, cs_deps_running
);
483 DEBUGPR ("The dependencies of `%s' are being made.\n");
487 /* If any dependency failed, give up now. */
491 file
->update_status
= dep_status
;
492 notice_finished_file (file
);
496 DEBUGPR ("Giving up on target file `%s'.\n");
498 if (depth
== 0 && keep_going_flag
499 && !just_print_flag
&& !question_flag
)
500 error ("Target `%s' not remade because of errors.", file
->name
);
505 if (file
->command_state
== cs_deps_running
)
506 /* The commands for some deps were running on the last iteration, but
507 they have finished now. Reset the command_state to not_started to
508 simplify later bookkeeping. It is important that we do this only
509 when the prior state was cs_deps_running, because that prior state
510 was definitely propagated to FILE's also_make's by set_command_state
511 (called above), but in another state an also_make may have
512 independently changed to finished state, and we would confuse that
513 file's bookkeeping (updated, but not_started is bogus state). */
514 set_command_state (file
, cs_not_started
);
516 /* Now record which dependencies are more
517 recent than this file, so we can define $?. */
520 for (d
= file
->deps
; d
!= 0; d
= d
->next
)
522 time_t d_mtime
= file_mtime (d
->file
);
523 check_renamed (d
->file
);
525 #if 1 /* %%% In version 4, remove this code completely to
526 implement not remaking deps if their deps are newer
527 than their parents. */
528 if (d_mtime
== (time_t) -1 && !d
->file
->intermediate
)
529 /* We must remake if this dep does not
530 exist and is not intermediate. */
534 /* Set DEPS_CHANGED if this dep actually changed. */
535 deps_changed
|= d
->changed
;
537 /* Set D->changed if either this dep actually changed,
538 or its dependent, FILE, is older or does not exist. */
539 d
->changed
|= noexist
|| d_mtime
> this_mtime
;
541 if (debug_flag
&& !noexist
)
543 print_spaces (depth
);
544 if (d_mtime
== (time_t) -1)
545 printf ("Dependency `%s' does not exist.\n", dep_name (d
));
547 printf ("Dependency `%s' is %s than dependent `%s'.\n",
548 dep_name (d
), d
->changed
? "newer" : "older", file
->name
);
553 /* Here depth returns to the value it had when we were called. */
556 if (file
->double_colon
&& file
->deps
== 0)
559 DEBUGPR ("Target `%s' is double-colon and has no dependencies.\n");
561 else if (!noexist
&& file
->is_target
&& !deps_changed
&& file
->cmds
== 0)
564 DEBUGPR ("No commands for `%s' and no dependencies actually changed.\n");
569 DEBUGPR ("No need to remake target `%s'.\n");
570 notice_finished_file (file
);
574 DEBUGPR ("Must remake target `%s'.\n");
576 /* Now, take appropriate actions to remake the file. */
579 if (file
->command_state
!= cs_finished
)
581 DEBUGPR ("Commands of `%s' are being run.\n");
585 switch (file
->update_status
)
588 DEBUGPR ("Failed to remake target file `%s'.\n");
591 DEBUGPR ("Successfully remade target file `%s'.\n");
594 DEBUGPR ("Target file `%s' needs remade under -q.\n");
597 assert (file
->update_status
>= 0 && file
->update_status
<= 2);
602 return file
->update_status
;
605 /* Set FILE's `updated' flag and re-check its mtime and the mtime's of all
606 files listed in its `also_make' member. Under -t, this function also
609 On return, FILE->update_status will no longer be -1 if it was. */
612 notice_finished_file (file
)
613 register struct file
*file
;
616 int ran
= file
->command_state
== cs_running
;
618 file
->command_state
= cs_finished
;
622 /* The update status will be:
623 -1 if this target was not remade;
624 0 if 0 or more commands (+ or ${MAKE}) were run and won;
625 1 if some commands were run and lost.
626 We touch the target if it has commands which either were not run
627 or won when they ran (i.e. status is 0). */
628 && file
->update_status
== 0)
630 if (file
->cmds
!= 0 && file
->cmds
->any_recurse
)
632 /* If all the command lines were recursive,
633 we don't want to do the touching. */
635 for (i
= 0; i
< file
->cmds
->ncommand_lines
; ++i
)
636 if (!(file
->cmds
->lines_flags
[i
] & COMMANDS_RECURSE
))
637 goto have_nonrecursing
;
643 file
->update_status
= 0;
645 /* Should set file's modification date and do nothing else. */
646 file
->update_status
= touch_file (file
);
650 if (ran
&& !file
->phony
)
654 if (just_print_flag
|| question_flag
655 || (file
->is_target
&& file
->cmds
== 0))
656 file
->last_mtime
= NEW_MTIME
;
658 file
->last_mtime
= 0;
660 /* Propagate the change of modification time to all the double-colon
661 entries for this file. */
662 for (f
= file
->double_colon
; f
!= 0; f
= f
->next
)
663 f
->last_mtime
= file
->last_mtime
;
666 if (ran
&& file
->update_status
!= -1)
667 /* We actually tried to update FILE, which has
668 updated its also_make's as well (if it worked).
669 If it didn't work, it wouldn't work again for them.
670 So mark them as updated with the same status. */
671 for (d
= file
->also_make
; d
!= 0; d
= d
->next
)
673 d
->file
->command_state
= cs_finished
;
674 d
->file
->updated
= 1;
675 d
->file
->update_status
= file
->update_status
;
677 if (ran
&& !d
->file
->phony
)
678 /* Fetch the new modification time.
679 We do this instead of just invalidating the cached time
680 so that a vpath_search can happen. Otherwise, it would
681 never be done because the target is already updated. */
682 (void) f_mtime (d
->file
, 0);
684 else if (file
->update_status
== -1)
685 /* Nothing was done for FILE, but it needed nothing done.
686 So mark it now as "succeeded". */
687 file
->update_status
= 0;
690 /* Check whether another file (whose mtime is THIS_MTIME)
691 needs updating on account of a dependency which is file FILE.
692 If it does, store 1 in *MUST_MAKE_PTR.
693 In the process, update any non-intermediate files
694 that FILE depends on (including FILE itself).
695 Return nonzero if any updating failed. */
698 check_dep (file
, depth
, this_mtime
, must_make_ptr
)
704 register struct dep
*d
;
710 if (!file
->intermediate
)
711 /* If this is a non-intermediate file, update it and record
712 whether it is newer than THIS_MTIME. */
715 dep_status
= update_file (file
, depth
);
716 check_renamed (file
);
717 mtime
= file_mtime (file
);
718 check_renamed (file
);
719 if (mtime
== (time_t) -1 || mtime
> this_mtime
)
724 /* FILE is an intermediate file. */
727 if (!file
->phony
&& file
->cmds
== 0 && !file
->tried_implicit
730 if (try_implicit_rule (file
, depth
))
731 DEBUGPR ("Found an implicit rule for `%s'.\n");
733 DEBUGPR ("No implicit rule found for `%s'.\n");
734 file
->tried_implicit
= 1;
736 if (file
->cmds
== 0 && !file
->is_target
&& file
->secondary
737 && default_file
!= 0 && default_file
->cmds
!= 0)
739 DEBUGPR ("Using default commands for `%s'.\n");
740 file
->cmds
= default_file
->cmds
;
743 /* If the intermediate file actually exists
744 and is newer, then we should remake from it. */
745 check_renamed (file
);
746 mtime
= file_mtime (file
);
747 check_renamed (file
);
748 if (mtime
> this_mtime
)
750 /* Otherwise, update all non-intermediate files we depend on,
751 if necessary, and see whether any of them is more
752 recent than the file on whose behalf we are checking. */
755 register struct dep
*lastd
;
761 if (d
->file
->updating
)
763 error ("Circular %s <- %s dependency dropped.",
764 file
->name
, d
->file
->name
);
767 file
->deps
= d
->next
;
773 lastd
->next
= d
->next
;
780 d
->file
->parent
= file
;
781 dep_status
|= check_dep (d
->file
, depth
, this_mtime
, must_make_ptr
);
782 check_renamed (d
->file
);
783 if (dep_status
!= 0 && !keep_going_flag
)
786 if (d
->file
->command_state
== cs_running
787 || d
->file
->command_state
== cs_deps_running
)
788 /* Record that some of FILE's dependencies are still being made.
789 This tells the upper levels to wait on processing it until
790 the commands are finished. */
791 set_command_state (file
, cs_deps_running
);
803 /* Touch FILE. Return zero if successful, one if not. */
805 #define TOUCH_ERROR(call) return (perror_with_name (call, file->name), 1)
809 register struct file
*file
;
812 message (0, "touch %s", file
->name
);
815 if (ar_name (file
->name
))
816 return ar_touch (file
->name
);
820 int fd
= open (file
->name
, O_RDWR
| O_CREAT
, 0666);
823 TOUCH_ERROR ("touch: open: ");
833 status
= fstat (fd
, &statbuf
);
835 while (status
< 0 && errno
== EINTR
);
838 TOUCH_ERROR ("touch: fstat: ");
839 /* Rewrite character 0 same as it already is. */
840 if (read (fd
, &buf
, 1) < 0)
841 TOUCH_ERROR ("touch: read: ");
842 if (lseek (fd
, 0L, 0) < 0L)
843 TOUCH_ERROR ("touch: lseek: ");
844 if (write (fd
, &buf
, 1) < 0)
845 TOUCH_ERROR ("touch: write: ");
846 /* If file length was 0, we just
847 changed it, so change it back. */
848 if (statbuf
.st_size
== 0)
851 fd
= open (file
->name
, O_RDWR
| O_TRUNC
, 0666);
853 TOUCH_ERROR ("touch: open: ");
862 /* Having checked and updated the dependencies of FILE,
863 do whatever is appropriate to remake FILE itself.
864 Return the status from executing FILE's commands. */
873 /* Phony target. Pretend it succeeded. */
874 file
->update_status
= 0;
875 else if (file
->is_target
)
876 /* This is a nonexistent target file we cannot make.
877 Pretend it was successfully remade. */
878 file
->update_status
= 0;
881 /* This is a dependency file we cannot remake. Fail. */
882 static const char msg_noparent
[]
883 = "%sNo rule to make target `%s'%s";
884 static const char msg_parent
[]
885 = "%sNo rule to make target `%s', needed by `%s'%s";
886 if (keep_going_flag
|| file
->dontcare
)
890 if (file
->parent
== 0)
891 error (msg_noparent
, "*** ", file
->name
, ".");
893 error (msg_parent
, "*** ",
894 file
->name
, file
->parent
->name
, ".");
896 file
->update_status
= 2;
900 if (file
->parent
== 0)
901 fatal (msg_noparent
, "", file
->name
, "");
903 fatal (msg_parent
, "", file
->name
, file
->parent
->name
, "");
909 chop_commands (file
->cmds
);
911 if (!touch_flag
|| file
->cmds
->any_recurse
)
913 execute_file_commands (file
);
917 /* This tells notice_finished_file it is ok to touch the file. */
918 file
->update_status
= 0;
921 /* This does the touching under -t. */
922 notice_finished_file (file
);
925 /* Return the mtime of a file, given a `struct file'.
926 Caches the time in the struct file to avoid excess stat calls.
928 If the file is not found, and SEARCH is nonzero, VPATH searching and
929 replacement is done. If that fails, a library (-lLIBNAME) is tried and
930 the library's actual name (/lib/libLIBNAME.a, etc.) is substituted into
934 f_mtime (file
, search
)
935 register struct file
*file
;
940 /* File's mtime is not known; must get it from the system. */
943 if (ar_name (file
->name
))
945 /* This file is an archive-member reference. */
947 char *arname
, *memname
;
951 /* Find the archive's name. */
952 ar_parse_name (file
->name
, &arname
, &memname
);
954 /* Find the modification time of the archive itself.
955 Also allow for its name to be changed via VPATH search. */
956 arfile
= lookup_file (arname
);
959 arfile
= enter_file (arname
);
962 mtime
= f_mtime (arfile
, search
);
963 check_renamed (arfile
);
964 if (search
&& strcmp (arfile
->name
, arname
))
966 /* The archive's name has changed.
967 Change the archive-member reference accordingly. */
969 unsigned int arlen
, memlen
;
977 arname
= arfile
->name
;
978 arlen
= strlen (arname
);
979 memlen
= strlen (memname
);
983 file
->name
= (char *) xmalloc (arlen
+ 1 + memlen
+ 2);
984 bcopy (arname
, file
->name
, arlen
);
985 file
->name
[arlen
] = '(';
986 bcopy (memname
, file
->name
+ arlen
+ 1, memlen
);
987 file
->name
[arlen
+ 1 + memlen
] = ')';
988 file
->name
[arlen
+ 1 + memlen
+ 1] = '\0';
995 if (mtime
== (time_t) -1)
996 /* The archive doesn't exist, so it's members don't exist either. */
999 mtime
= ar_member_date (file
->name
);
1004 mtime
= name_mtime (file
->name
);
1006 if (mtime
== (time_t) -1 && search
)
1008 /* If name_mtime failed, search VPATH. */
1009 char *name
= file
->name
;
1010 if (vpath_search (&name
, &mtime
)
1011 /* Last resort, is it a library (-lxxx)? */
1012 || (name
[0] == '-' && name
[1] == 'l'
1013 && library_search (&name
, &mtime
)))
1016 /* vpath_search and library_search store zero in MTIME
1017 if they didn't need to do a stat call for their work. */
1018 file
->last_mtime
= mtime
;
1019 rename_file (file
, name
);
1020 check_renamed (file
);
1021 return file_mtime (file
);
1027 /* Files can have bogus timestamps that nothing newly made will be
1028 "newer" than. Updating their dependents could just result in loops.
1029 So notify the user of the anomaly by treating future files as
1030 unrecoverably absent. */
1033 if (mtime
!= -1 && mtime
> now
&& ! file
->updated
)
1035 /* This file's time appears to be in the future.
1036 Update our concept of the present, and compare again. */
1038 /* Handle vms 64bit to 32bit time hack introduced in vms_stat ... */
1039 static unsigned long vms_now
[2]; /* assumes 32 bit long ! */
1040 sys$
gettim (vms_now
);
1041 now
= ((vms_now
[0]>>24) & 0xff) + ((vms_now
[1]<<8) & 0xffffff00);
1044 extern time_t time ();
1045 if (mtime
> time (&now
))
1048 error ("*** File `%s' has modification time in the future",
1050 file
->update_status
= 2;
1055 /* Store the mtime into all the entries for this file. */
1056 if (file
->double_colon
)
1057 file
= file
->double_colon
;
1060 file
->last_mtime
= mtime
;
1062 } while (file
!= 0);
1068 /* Return the mtime of the file or archive-member reference NAME. */
1072 register char *name
;
1077 if (vms_stat (name
, &st
) < 0)
1079 if (stat (name
, &st
) < 0)
1083 return (time_t) st
.st_mtime
;
1087 /* Search for a library file specified as -lLIBNAME, searching for a
1088 suitable library file in the system library directories and the VPATH
1092 library_search (lib
, mtime_ptr
)
1096 static char *dirs
[] =
1102 #if defined(WIN32) && !defined(LIBDIR)
1104 * This is completely up to the user at product install time. Just define
1109 LIBDIR
, /* Defined by configuration. */
1113 char *libname
= &(*lib
)[2]; /* Name without the `-l'. */
1116 /* Buffer to construct possible names in. */
1117 char *buf
= xmalloc (sizeof (LIBDIR
) + 8 + strlen (libname
) + 4 + 2 + 1);
1120 /* Look first for `libNAME.a' in the current directory. */
1123 sprintf (buf
, "lib%s.a", libname
);
1125 sprintf (buf
, "%s.lib", libname
);
1127 mtime
= name_mtime (buf
);
1128 if (mtime
!= (time_t) -1)
1136 /* Now try VPATH search on that. */
1139 if (vpath_search (&file
, mtime_ptr
))
1146 /* Now try the standard set of directories. */
1148 for (dp
= dirs
; *dp
!= 0; ++dp
)
1151 sprintf (buf
, "%s/lib%s.a", *dp
, libname
);
1153 sprintf (buf
, "%s/%s.lib", *dp
, libname
);
1155 mtime
= name_mtime (buf
);
1156 if (mtime
!= (time_t) -1)