GNU make 3.79.1 introduced a new configure-time option
--disable-nsec-timestamps that lets the "make" builder optionally
build a version of "make" that ignores high resolution time stamps.
This solution is awkward, as it means users need two versions of
"make", one built with and one built without high resolution time
stamps. It's better to make it a run-time option. Better yet, it
should be a selective option: the option should apply only to files
with low resolution time stamps, i.e. files that are created by
commands like "cp -p" that cannot generate high resolution time
stamps.
Here's a proposed patch to do this. It assumes the previous patches
I've submitted for Make 3.79.1. It replaces --disable-nsec-timestamps
with a new pseudo-target .LOW_RESOLUTION_TIME. The user specifies
which files are built by commands like "cp -p" by having
.LOW_RESOLUTION_TIME depend on them.
This proposed change affects behavior only on hosts that have high
resolution time stamps.
2000-07-23 Paul Eggert <[EMAIL PROTECTED]>
* NEWS, make.texinfo: Document .LOW_RESOLUTION_TIME, which
supersedes --disable-nsec-timestamps.
* make.texinfo: Consistently use "time stamp" instead of "timestamp".
* README: Remove --disable-nsec-timestamps.
* filedef.h (struct file.low_resolution_time): New member.
* file.c (snap_deps): Add support for .LOW_RESOLUTION_TIME.
* remake.c (update_file_1):
Avoid spurious rebuilds due to low resolution time stamps,
generalizing the earlier code that applied only to archive members.
(f_mtime): Archive members always have low resolution time stamps.
* configure.in: Remove --disable-nsec-timestamps, as this has
been superseded by .LOW_RESOLUTION_TIME.
===================================================================
RCS file: NEWS,v
retrieving revision 3.79.1.0
retrieving revision 3.79.1.1
diff -pu -r3.79.1.0 -r3.79.1.1
--- NEWS 2000/06/23 15:57:59 3.79.1.0
+++ NEWS 2000/07/24 06:44:47 3.79.1.1
@@ -12,17 +12,20 @@ Please send GNU make bug reports to <bug
See the README file and the GNU make manual for details on sending bug
reports.
+* New pseudo-target .LOW_RESOLUTION_TIME, superseding the configure
+ option --disable-nsec-timestamps. You might need this if your build
+ process depends on tools like "cp -p" preserving time stamps, since
+ "cp -p" (right now) doesn't preserve the subsecond portion of a time
+ stamp.
+
Version 3.79.1
* .SECONDARY with no prerequisites now prevents any target from being
removed because make thinks it's an intermediate file, not just those
listed in the makefile.
-* New configure option --disable-nsec-timestamps will keep make from
- using sub-second timestamps on systems which support it. If your
- build process depends on proper timestamp-preserving behavior of tools
- like "cp -p" you might need this option, since "cp -p" (right now)
- doesn't preserve the sub-second portion of the timestamp.
+* New configure option --disable-nsec-timestamps, but this was
+ superseded in later versions by the .LOW_RESOLUTION_TIME pseudo-target.
Version 3.79
===================================================================
RCS file: README,v
retrieving revision 3.79.1.0
retrieving revision 3.79.1.1
diff -pu -r3.79.1.0 -r3.79.1.1
--- README 2000/06/23 16:20:40 3.79.1.0
+++ README 2000/07/24 06:44:47 3.79.1.1
@@ -121,14 +121,3 @@ files (LFS) in configure for those opera
Please report any bugs that you find in this area. If you run into
difficulties, then as a workaround you should be able to disable LFS by
adding the `--disable-largefile' option to the `configure' script.
-
-On systems that support micro- and nano-second timestamp values and
-where stat(2) provides this information, GNU make will use it when
-comparing timestamps to get the most accurate possible result. However,
-at the moment there is no system call (that I'm aware of) that will
-allow you to *set* a timestamp to a micro- or nano-second granularity.
-This means that "cp -p" and other similar tools (tar, etc.) cannot
-exactly duplicate timestamps with micro- and nano-second granularity.
-If your build system contains rules that depend on proper behavior of
-tools like "cp -p", you should configure make to not use micro- and
-nano-second timestamps with the --disable-nsec-timestamps flag.
===================================================================
RCS file: make.texinfo,v
retrieving revision 3.79
retrieving revision 3.79.1.1
diff -pu -r3.79 -r3.79.1.1
--- make.texinfo 2000/06/20 14:00:17 3.79
+++ make.texinfo 2000/07/24 06:53:15 3.79.1.1
@@ -2451,6 +2451,42 @@ this affects every command in the makefi
recommend you use the more selective ways to ignore errors in specific
commands. @xref{Errors, ,Errors in Commands}.
+@findex .LOW_RESOLUTION_TIME
+@item .LOW_RESOLUTION_TIME
+
+If you specify prerequisites for @code{.LOW_RESOLUTION_TIME},
+@command{make} assumes that these files are created by commands that
+generate low resolution time stamps. The commands for
+@code{.LOW_RESOLUTION_TIME} are not meaningful.
+
+The high resolution file time stamps of many modern hosts lessen the
+chance of @command{make} incorrectly concluding that a file is up to
+date. Unfortunately, these hosts provide no way to set a high
+resolution file time stamp, so commands like @samp{cp -p} that
+explicitly set a file's time stamp must discard its subsecond part. If
+a file is created by such a command, you should list it as a dependency
+of @code{.LOW_RESOLUTION_TIME} so that @command{make} does not
+mistakenly conclude that the file is out of date. For example:
+
+@example
+@group
+.LOW_RESOLUTION_TIME: dst
+dst: src
+ cp -p src dst
+@end group
+@end example
+
+Since @samp{cp -p} discards the subsecond part of @file{src}'s time
+stamp, @file{dst} is typically slightly older than @file{src} even when
+it is up to date. The @code{.LOW_RESOLUTION_TIME} line causes
+@command{make} to consider @file{dst} to be up to date if its time stamp
+is at the start of the same second that @file{src}'s time stamp is in.
+
+Due to a limitation of the archive format, archive member time stamps
+are always low resolution. You need not list archive members as
+dependencies of @code{.LOW_RESOLUTION_TIME}, as @command{make} does this
+automatically.
+
@findex .SILENT
@item .SILENT
@@ -3341,7 +3377,7 @@ default.
@cindex target, deleting on error
Usually when a command fails, if it has changed the target file at all,
the file is corrupted and cannot be used---or at least it is not
-completely updated. Yet the file's timestamp says that it is now up to
+completely updated. Yet the file's time stamp says that it is now up to
date, so the next time @code{make} runs, it will not try to update that
file. The situation is just the same as when the command is killed by a
signal; @pxref{Interrupts}. So generally the right thing to do is to
===================================================================
RCS file: filedef.h,v
retrieving revision 3.79.1.2
retrieving revision 3.79.1.3
diff -pu -r3.79.1.2 -r3.79.1.3
--- filedef.h 2000/07/23 07:22:51 3.79.1.2
+++ filedef.h 2000/07/24 06:44:47 3.79.1.3
@@ -72,6 +72,8 @@ struct file
} command_state ENUM_BITFIELD (2);
unsigned int precious:1; /* Non-0 means don't delete file on quit */
+ unsigned int low_resolution_time:1; /* Nonzero if this file's time stamp
+ has only one-second resolution. */
unsigned int tried_implicit:1; /* Nonzero if have searched
for implicit rule for making
this file; don't search again. */
===================================================================
RCS file: file.c,v
retrieving revision 3.79.1.2
retrieving revision 3.79.1.3
diff -pu -r3.79.1.2 -r3.79.1.3
--- file.c 2000/07/23 07:22:51 3.79.1.2
+++ file.c 2000/07/24 06:44:47 3.79.1.3
@@ -467,6 +467,11 @@ snap_deps ()
for (f2 = d->file; f2 != 0; f2 = f2->prev)
f2->precious = 1;
+ for (f = lookup_file (".LOW_RESOLUTION_TIME"); f != 0; f = f->prev)
+ for (d = f->deps; d != 0; d = d->next)
+ for (f2 = d->file; f2 != 0; f2 = f2->prev)
+ f2->low_resolution_time = 1;
+
for (f = lookup_file (".PHONY"); f != 0; f = f->prev)
for (d = f->deps; d != 0; d = d->next)
for (f2 = d->file; f2 != 0; f2 = f2->prev)
===================================================================
RCS file: remake.c,v
retrieving revision 3.79.1.2
retrieving revision 3.79.1.3
diff -pu -r3.79.1.2 -r3.79.1.3
--- remake.c 2000/07/07 07:01:18 3.79.1.2
+++ remake.c 2000/07/24 06:44:47 3.79.1.3
@@ -396,14 +396,15 @@ update_file_1 (file, depth)
noexist = this_mtime == NONEXISTENT_MTIME;
if (noexist)
DBF (DB_BASIC, _("File `%s' does not exist.\n"));
- else
+ else if (ORDINARY_MTIME_MIN <= this_mtime && this_mtime <= ORDINARY_MTIME_MAX
+ && file->low_resolution_time)
{
-#ifndef NO_ARCHIVES
- /* Avoid spurious rebuilds of archive members due to their
- timestamp resolution being only one second. */
- if (1 < FILE_TIMESTAMPS_PER_S && ar_name (file->name))
- this_mtime += FILE_TIMESTAMPS_PER_S - 1;
-#endif
+ /* Avoid spurious rebuilds due to low resolution time stamps. */
+ int ns = FILE_TIMESTAMP_NS (this_mtime);
+ if (ns != 0)
+ error (NILF, _("*** Warning: .LOW_RESOLUTION_TIME file `%s' has a high
+resolution time stamp"),
+ file->name);
+ this_mtime += FILE_TIMESTAMPS_PER_S - 1 - ns;
}
must_make = noexist;
@@ -1106,6 +1107,8 @@ f_mtime (file, search)
free (arname);
free (memname);
+ file->low_resolution_time = 1;
+
if (mtime == NONEXISTENT_MTIME)
/* The archive doesn't exist, so its members don't exist either. */
return NONEXISTENT_MTIME;
===================================================================
RCS file: configure.in,v
retrieving revision 3.79.1.2
retrieving revision 3.79.1.3
diff -pu -r3.79.1.2 -r3.79.1.3
--- configure.in 2000/07/23 07:44:05 3.79.1.2
+++ configure.in 2000/07/24 06:44:47 3.79.1.3
@@ -45,45 +45,35 @@ dnl Handle internationalization
ALL_LINGUAS="de es fr ja ko nl pl pt_BR ru"
pds_WITH_GETTEXT
-
-dnl See if the user wants nsec timestamps
-
-AC_ARG_ENABLE(nsec-timestamps,
- [ --disable-nsec-timestamps disable use of sub-second timestamps],
- [enable_nsec_timestamps="$enableval"],
- [enable_nsec_timestamps="yes"])
-
jm_AC_TYPE_UINTMAX_T
-if test "x$enable_nsec_timestamps" != xno; then
- AC_STRUCT_ST_MTIM_NSEC
- AC_MSG_CHECKING([whether to use high resolution file timestamps])
- AC_CACHE_VAL(make_cv_file_timestamp_hi_res, [
- make_cv_file_timestamp_hi_res=no
- if test $ac_cv_struct_st_mtim_nsec != no; then
- AC_TRY_COMPILE([
+AC_STRUCT_ST_MTIM_NSEC
+AC_MSG_CHECKING([whether to use high resolution file timestamps])
+AC_CACHE_VAL(make_cv_file_timestamp_hi_res, [
+ make_cv_file_timestamp_hi_res=no
+ if test $ac_cv_struct_st_mtim_nsec != no; then
+ AC_TRY_COMPILE([
# if HAVE_INTTYPES_H
# include <inttypes.h>
# endif],
- [char a[0x7fffffff < (uintmax_t) -1 >> 30 ? 1 : -1];],
- make_cv_file_timestamp_hi_res=yes)
- fi])
- AC_MSG_RESULT($make_cv_file_timestamp_hi_res)
- if test $make_cv_file_timestamp_hi_res = yes; then
- val=1
- else
- val=0
- fi
- AC_DEFINE_UNQUOTED(FILE_TIMESTAMP_HI_RES, $val,
- [Use high resolution file timestamps if nonzero.])
+ [char a[0x7fffffff < (uintmax_t) -1 >> 30 ? 1 : -1];],
+ make_cv_file_timestamp_hi_res=yes)
+ fi])
+AC_MSG_RESULT($make_cv_file_timestamp_hi_res)
+if test $make_cv_file_timestamp_hi_res = yes; then
+ val=1
+else
+ val=0
+fi
+AC_DEFINE_UNQUOTED(FILE_TIMESTAMP_HI_RES, $val,
+ [Use high resolution file timestamps if nonzero.])
- if test $make_cv_file_timestamp_hi_res = yes; then
- # Solaris 2.5.1 needs -lposix4 to get the clock_gettime function.
- # Solaris 7 prefers the library name -lrt to the obsolescent name -lposix4.
- AC_SEARCH_LIBS(clock_gettime, [rt posix4])
- if test "$ac_cv_search_clock_gettime" != no; then
- AC_DEFINE(HAVE_CLOCK_GETTIME, 1,
- [Define if you have the clock_gettime function.])
- fi
+if test $make_cv_file_timestamp_hi_res = yes; then
+ # Solaris 2.5.1 needs -lposix4 to get the clock_gettime function.
+ # Solaris 7 prefers the library name -lrt to the obsolescent name -lposix4.
+ AC_SEARCH_LIBS(clock_gettime, [rt posix4])
+ if test "$ac_cv_search_clock_gettime" != no; then
+ AC_DEFINE(HAVE_CLOCK_GETTIME, 1,
+ [Define if you have the clock_gettime function.])
fi
fi