1 /* Basic dependency engine for GNU Make.
2 Copyright (C) 1988,89,90,91,92,93,94,95,96,97 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. */
43 extern int try_implicit_rule
PARAMS ((struct file
*file
, unsigned int depth
));
46 /* Incremented when a command is started (under -n, when one would be). */
47 unsigned int commands_started
= 0;
49 static int update_file
PARAMS ((struct file
*file
, unsigned int depth
));
50 static int update_file_1
PARAMS ((struct file
*file
, unsigned int depth
));
51 static int check_dep
PARAMS ((struct file
*file
, unsigned int depth
, time_t this_mtime
, int *must_make_ptr
));
52 static int touch_file
PARAMS ((struct file
*file
));
53 static void remake_file
PARAMS ((struct file
*file
));
54 static time_t name_mtime
PARAMS ((char *name
));
55 static int library_search
PARAMS ((char **lib
, time_t *mtime_ptr
));
57 extern time_t f_mtime
PARAMS ((struct file
*file
, int search
));
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");
572 printf("No need to remake target `%s'", file
->name
);
573 if (!streq(file
->name
, file
->hname
))
574 printf("; using VPATH name `%s'", file
->hname
);
579 notice_finished_file (file
);
581 /* Since we don't need to remake the file, convert it to use the
582 VPATH filename if we found one. hfile will be either the
583 local name if no VPATH or the VPATH name if one was found. */
587 file
->name
= file
->hname
;
594 DEBUGPR ("Must remake target `%s'.\n");
596 /* It needs to be remade. If it's VPATH and not reset via GPATH, toss the
598 if (!streq(file
->name
, file
->hname
))
602 print_spaces (depth
);
603 printf(" Ignoring VPATH name `%s'.\n", file
->hname
);
606 file
->ignore_vpath
= 1;
609 /* Now, take appropriate actions to remake the file. */
612 if (file
->command_state
!= cs_finished
)
614 DEBUGPR ("Commands of `%s' are being run.\n");
618 switch (file
->update_status
)
621 DEBUGPR ("Failed to remake target file `%s'.\n");
624 DEBUGPR ("Successfully remade target file `%s'.\n");
627 DEBUGPR ("Target file `%s' needs remade under -q.\n");
630 assert (file
->update_status
>= 0 && file
->update_status
<= 2);
635 return file
->update_status
;
638 /* Set FILE's `updated' flag and re-check its mtime and the mtime's of all
639 files listed in its `also_make' member. Under -t, this function also
642 On return, FILE->update_status will no longer be -1 if it was. */
645 notice_finished_file (file
)
646 register struct file
*file
;
649 int ran
= file
->command_state
== cs_running
;
651 file
->command_state
= cs_finished
;
655 /* The update status will be:
656 -1 if this target was not remade;
657 0 if 0 or more commands (+ or ${MAKE}) were run and won;
658 1 if some commands were run and lost.
659 We touch the target if it has commands which either were not run
660 or won when they ran (i.e. status is 0). */
661 && file
->update_status
== 0)
663 if (file
->cmds
!= 0 && file
->cmds
->any_recurse
)
665 /* If all the command lines were recursive,
666 we don't want to do the touching. */
668 for (i
= 0; i
< file
->cmds
->ncommand_lines
; ++i
)
669 if (!(file
->cmds
->lines_flags
[i
] & COMMANDS_RECURSE
))
670 goto have_nonrecursing
;
676 file
->update_status
= 0;
678 /* Should set file's modification date and do nothing else. */
679 file
->update_status
= touch_file (file
);
683 if (ran
&& !file
->phony
)
687 if (just_print_flag
|| question_flag
688 || (file
->is_target
&& file
->cmds
== 0))
689 file
->last_mtime
= NEW_MTIME
;
691 file
->last_mtime
= 0;
693 /* Propagate the change of modification time to all the double-colon
694 entries for this file. */
695 for (f
= file
->double_colon
; f
!= 0; f
= f
->next
)
696 f
->last_mtime
= file
->last_mtime
;
699 if (ran
&& file
->update_status
!= -1)
700 /* We actually tried to update FILE, which has
701 updated its also_make's as well (if it worked).
702 If it didn't work, it wouldn't work again for them.
703 So mark them as updated with the same status. */
704 for (d
= file
->also_make
; d
!= 0; d
= d
->next
)
706 d
->file
->command_state
= cs_finished
;
707 d
->file
->updated
= 1;
708 d
->file
->update_status
= file
->update_status
;
710 if (ran
&& !d
->file
->phony
)
711 /* Fetch the new modification time.
712 We do this instead of just invalidating the cached time
713 so that a vpath_search can happen. Otherwise, it would
714 never be done because the target is already updated. */
715 (void) f_mtime (d
->file
, 0);
717 else if (file
->update_status
== -1)
718 /* Nothing was done for FILE, but it needed nothing done.
719 So mark it now as "succeeded". */
720 file
->update_status
= 0;
723 /* Check whether another file (whose mtime is THIS_MTIME)
724 needs updating on account of a dependency which is file FILE.
725 If it does, store 1 in *MUST_MAKE_PTR.
726 In the process, update any non-intermediate files
727 that FILE depends on (including FILE itself).
728 Return nonzero if any updating failed. */
731 check_dep (file
, depth
, this_mtime
, must_make_ptr
)
737 register struct dep
*d
;
743 if (!file
->intermediate
)
744 /* If this is a non-intermediate file, update it and record
745 whether it is newer than THIS_MTIME. */
748 dep_status
= update_file (file
, depth
);
749 check_renamed (file
);
750 mtime
= file_mtime (file
);
751 check_renamed (file
);
752 if (mtime
== (time_t) -1 || mtime
> this_mtime
)
757 /* FILE is an intermediate file. */
760 if (!file
->phony
&& file
->cmds
== 0 && !file
->tried_implicit
763 if (try_implicit_rule (file
, depth
))
764 DEBUGPR ("Found an implicit rule for `%s'.\n");
766 DEBUGPR ("No implicit rule found for `%s'.\n");
767 file
->tried_implicit
= 1;
769 if (file
->cmds
== 0 && !file
->is_target
&& file
->secondary
770 && default_file
!= 0 && default_file
->cmds
!= 0)
772 DEBUGPR ("Using default commands for `%s'.\n");
773 file
->cmds
= default_file
->cmds
;
776 /* If the intermediate file actually exists
777 and is newer, then we should remake from it. */
778 check_renamed (file
);
779 mtime
= file_mtime (file
);
780 check_renamed (file
);
781 if (mtime
!= (time_t) -1 && mtime
> this_mtime
)
783 /* Otherwise, update all non-intermediate files we depend on,
784 if necessary, and see whether any of them is more
785 recent than the file on whose behalf we are checking. */
788 register struct dep
*lastd
;
794 if (d
->file
->updating
)
796 error ("Circular %s <- %s dependency dropped.",
797 file
->name
, d
->file
->name
);
800 file
->deps
= d
->next
;
806 lastd
->next
= d
->next
;
813 d
->file
->parent
= file
;
814 dep_status
|= check_dep (d
->file
, depth
, this_mtime
, must_make_ptr
);
815 check_renamed (d
->file
);
816 if (dep_status
!= 0 && !keep_going_flag
)
819 if (d
->file
->command_state
== cs_running
820 || d
->file
->command_state
== cs_deps_running
)
821 /* Record that some of FILE's dependencies are still being made.
822 This tells the upper levels to wait on processing it until
823 the commands are finished. */
824 set_command_state (file
, cs_deps_running
);
836 /* Touch FILE. Return zero if successful, one if not. */
838 #define TOUCH_ERROR(call) return (perror_with_name (call, file->name), 1)
842 register struct file
*file
;
845 message (0, "touch %s", file
->name
);
848 if (ar_name (file
->name
))
849 return ar_touch (file
->name
);
853 int fd
= open (file
->name
, O_RDWR
| O_CREAT
, 0666);
856 TOUCH_ERROR ("touch: open: ");
866 status
= fstat (fd
, &statbuf
);
868 while (status
< 0 && errno
== EINTR
);
871 TOUCH_ERROR ("touch: fstat: ");
872 /* Rewrite character 0 same as it already is. */
873 if (read (fd
, &buf
, 1) < 0)
874 TOUCH_ERROR ("touch: read: ");
875 if (lseek (fd
, 0L, 0) < 0L)
876 TOUCH_ERROR ("touch: lseek: ");
877 if (write (fd
, &buf
, 1) < 0)
878 TOUCH_ERROR ("touch: write: ");
879 /* If file length was 0, we just
880 changed it, so change it back. */
881 if (statbuf
.st_size
== 0)
884 fd
= open (file
->name
, O_RDWR
| O_TRUNC
, 0666);
886 TOUCH_ERROR ("touch: open: ");
895 /* Having checked and updated the dependencies of FILE,
896 do whatever is appropriate to remake FILE itself.
897 Return the status from executing FILE's commands. */
906 /* Phony target. Pretend it succeeded. */
907 file
->update_status
= 0;
908 else if (file
->is_target
)
909 /* This is a nonexistent target file we cannot make.
910 Pretend it was successfully remade. */
911 file
->update_status
= 0;
914 /* This is a dependency file we cannot remake. Fail. */
915 static const char msg_noparent
[]
916 = "%sNo rule to make target `%s'%s";
917 static const char msg_parent
[]
918 = "%sNo rule to make target `%s', needed by `%s'%s";
919 if (keep_going_flag
|| file
->dontcare
)
923 if (file
->parent
== 0)
924 error (msg_noparent
, "*** ", file
->name
, ".");
926 error (msg_parent
, "*** ",
927 file
->name
, file
->parent
->name
, ".");
929 file
->update_status
= 2;
933 if (file
->parent
== 0)
934 fatal (msg_noparent
, "", file
->name
, "");
936 fatal (msg_parent
, "", file
->name
, file
->parent
->name
, "");
942 chop_commands (file
->cmds
);
944 if (!touch_flag
|| file
->cmds
->any_recurse
)
946 execute_file_commands (file
);
950 /* This tells notice_finished_file it is ok to touch the file. */
951 file
->update_status
= 0;
954 /* This does the touching under -t. */
955 notice_finished_file (file
);
958 /* Return the mtime of a file, given a `struct file'.
959 Caches the time in the struct file to avoid excess stat calls.
961 If the file is not found, and SEARCH is nonzero, VPATH searching and
962 replacement is done. If that fails, a library (-lLIBNAME) is tried and
963 the library's actual name (/lib/libLIBNAME.a, etc.) is substituted into
967 f_mtime (file
, search
)
968 register struct file
*file
;
973 /* File's mtime is not known; must get it from the system. */
976 if (ar_name (file
->name
))
978 /* This file is an archive-member reference. */
980 char *arname
, *memname
;
984 /* Find the archive's name. */
985 ar_parse_name (file
->name
, &arname
, &memname
);
987 /* Find the modification time of the archive itself.
988 Also allow for its name to be changed via VPATH search. */
989 arfile
= lookup_file (arname
);
992 arfile
= enter_file (arname
);
995 mtime
= f_mtime (arfile
, search
);
996 check_renamed (arfile
);
997 if (search
&& strcmp (arfile
->name
, arname
))
999 /* The archive's name has changed.
1000 Change the archive-member reference accordingly. */
1002 unsigned int arlen
, memlen
;
1010 arname
= arfile
->name
;
1011 arlen
= strlen (arname
);
1012 memlen
= strlen (memname
);
1016 file
->name
= (char *) xmalloc (arlen
+ 1 + memlen
+ 2);
1017 bcopy (arname
, file
->name
, arlen
);
1018 file
->name
[arlen
] = '(';
1019 bcopy (memname
, file
->name
+ arlen
+ 1, memlen
);
1020 file
->name
[arlen
+ 1 + memlen
] = ')';
1021 file
->name
[arlen
+ 1 + memlen
+ 1] = '\0';
1028 if (mtime
== (time_t) -1)
1029 /* The archive doesn't exist, so it's members don't exist either. */
1032 mtime
= ar_member_date (file
->name
);
1037 mtime
= name_mtime (file
->name
);
1039 if (mtime
== (time_t) -1 && search
&& !file
->ignore_vpath
)
1041 /* If name_mtime failed, search VPATH. */
1042 char *name
= file
->name
;
1043 if (vpath_search (&name
, &mtime
)
1044 /* Last resort, is it a library (-lxxx)? */
1045 || (name
[0] == '-' && name
[1] == 'l'
1046 && library_search (&name
, &mtime
)))
1049 /* vpath_search and library_search store zero in MTIME
1050 if they didn't need to do a stat call for their work. */
1051 file
->last_mtime
= mtime
;
1053 /* If we found it in VPATH, see if it's in GPATH too; if so,
1054 change the name right now; if not, defer until after the
1055 dependencies are updated. */
1056 if (gpath_search (name
, strlen(name
) - strlen(file
->name
) - 1))
1058 rename_file (file
, name
);
1059 check_renamed (file
);
1060 return file_mtime (file
);
1063 rehash_file (file
, name
);
1064 check_renamed (file
);
1065 mtime
= name_mtime (name
);
1071 /* Files can have bogus timestamps that nothing newly made will be
1072 "newer" than. Updating their dependents could just result in loops.
1073 So notify the user of the anomaly with a warning.
1075 We only need to do this once, for now. */
1077 static time_t now
= 0;
1078 if (!clock_skew_detected
1079 && mtime
!= (time_t)-1 && mtime
> now
1082 /* This file's time appears to be in the future.
1083 Update our concept of the present, and compare again. */
1085 extern time_t time ();
1090 * FAT filesystems round time to nearest even second(!). Just
1091 * allow for any file (NTFS or FAT) to perhaps suffer from this
1094 * Apparently, this doesn't happen with the MS-DOS/DJGPP port,
1095 * although MS-DOS and MS-Windows 3.X/9X also use FAT filesystems.
1097 if (mtime
> now
&& (((mtime
% 2) == 0) && ((mtime
-1) > now
)))
1102 error("*** Warning: File `%s' has modification time in the future",
1104 clock_skew_detected
= 1;
1109 /* Store the mtime into all the entries for this file. */
1110 if (file
->double_colon
)
1111 file
= file
->double_colon
;
1114 file
->last_mtime
= mtime
;
1116 } while (file
!= 0);
1122 /* Return the mtime of the file or archive-member reference NAME. */
1126 register char *name
;
1130 if (stat (name
, &st
) < 0)
1133 return (time_t) st
.st_mtime
;
1137 /* Search for a library file specified as -lLIBNAME, searching for a
1138 suitable library file in the system library directories and the VPATH
1142 library_search (lib
, mtime_ptr
)
1146 static char *dirs
[] =
1152 #if defined(WINDOWS32) && !defined(LIBDIR)
1154 * This is completely up to the user at product install time. Just define
1159 LIBDIR
, /* Defined by configuration. */
1163 char *libname
= &(*lib
)[2]; /* Name without the `-l'. */
1166 /* Buffer to construct possible names in. */
1167 char *buf
= xmalloc (sizeof (LIBDIR
) + 8 + strlen (libname
) + 4 + 2 + 1);
1170 /* Look first for `libNAME.a' in the current directory. */
1173 sprintf (buf
, "lib%s.a", libname
);
1175 sprintf (buf
, "%s.lib", libname
);
1177 mtime
= name_mtime (buf
);
1178 if (mtime
!= (time_t) -1)
1186 /* Now try VPATH search on that. */
1189 if (vpath_search (&file
, mtime_ptr
))
1196 /* Now try the standard set of directories. */
1200 /* The default library directory is at ${DJDIR}/lib. */
1201 struct variable
*djdir
= lookup_variable ("DJDIR", 5);
1205 size_t djdir_len
= strlen (djdir
->value
);
1207 if (djdir_len
> sizeof(LIBDIR
) + 8 + strlen(libname
) + 4 + 2)
1208 buf
= (char *) xrealloc (djdir_len
+ 1);
1209 sprintf (buf
, "%s/lib/lib%s.a", djdir
->value
, libname
);
1210 mtime
= name_mtime (buf
);
1211 if (mtime
!= (time_t) -1)
1222 for (dp
= dirs
; *dp
!= 0; ++dp
)
1225 sprintf (buf
, "%s/lib%s.a", *dp
, libname
);
1227 sprintf (buf
, "%s/%s.lib", *dp
, libname
);
1229 mtime
= name_mtime (buf
);
1230 if (mtime
!= (time_t) -1)