Nick Bowler wrote:
> Maybe this is a silly question, but, is there a reason why this test
> needs to be performed in every single package that uses Automake?
Excellent point. The best optimization of a certain code is the one
that avoids executing the code entirely.
With Karl's newest patch, it's no longer a 7-seconds delay, but a
2-seconds delay. But if we can avoid executing it entirely, it would
be better.
Zack Weinberg wrote:
> The timestamp resolution is actually used by core automake code, namely
> the "ensuring generated files are newer than source" config.status step,
> which is necessary to make tarball builds work reliably on systems that
> don't have the `automake`, `autoconf`, `aclocal`, etc. tools already
> installed.
Right. And, more precisely, this test "ensuring generated files are newer
than source" makes sure that a newly created file is at least 0.01 or 0.1
or 1 or 2 seconds newer that the 'configure' file. Therefore the situations
where it is needed are:
(A) when a machine has a skewed time clock (like gcc111.fsffrance.org
often has),
(B) when a package creates a configure file in a subtree and then
_immediately_ runs that configure script.
Case (A) affects all packages, but it can usually not be fixed with a
'sleep 1' or 'sleep 2'; that's not what we are talking about.
Case (B) is why the Automake test suite needs this test to be in 'configure'.
This is the case where a 'sleep 1' or 'sleep 2' can help. Still, case (B)
can also occur in other packages (think of distros which — for ill-guided
reasons — routinely regenerate the configure script).
So, I agree with Karl that this code is needed for all packages.
But it is not needed in all configure runs! The 'sleep 1' or 'sleep 2'
is in _AM_FILESYSTEM_TIMESTAMP_RESOLUTION, whose sole purpose is to
determine a variable am_cv_filesystem_timestamp_resolution. The sole
use of this variable is in AM_SANITY_CHECK, in a loop whose structure is:
for (2 times)
Test whether the configure file is old enough (0.01 sec ... 2 sec —
it depends).
If yes:
break;
sleep $am_cv_filesystem_timestamp_resolution
end
In most cases, the test will already succeed in the first loop round,
and then there is *no need* for even determining
am_cv_filesystem_timestamp_resolution.
So, the fix is simply to delay determining am_cv_filesystem_timestamp_resolution
until we actually need it.
The attached patch does it. In my testing on NetBSD, which involves a few
seconds of transfer between creation and execution of a tarball, the 2-seconds
delay goes away, as expected.
Note: The redirection of AS_MESSAGE_FD may look ugly, but is portable.
Gnulib uses this idiom for three years already.
Bruno
>From 3a7f1cb3ea4a51caf77cf6c06a1d9528764adc2b Mon Sep 17 00:00:00 2001
From: Bruno Haible <[email protected]>
Date: Thu, 13 Jun 2024 13:47:49 +0200
Subject: [PATCH] automake: Save up to 2 seconds of configure time.
* m4/sanity.m4 (AM_SANITY_CHECK): Don't require
_AM_FILESYSTEM_TIMESTAMP_RESOLUTION. Instead, execute it only when it is
actually needed. In most cases outside Automake's test suite, it is not
needed.
---
m4/sanity.m4 | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/m4/sanity.m4 b/m4/sanity.m4
index 68fbf36f7..e09bca69f 100644
--- a/m4/sanity.m4
+++ b/m4/sanity.m4
@@ -141,7 +141,7 @@ rm -f conftest.ts?
# AM_SANITY_CHECK
# ---------------
AC_DEFUN([AM_SANITY_CHECK],
-[AC_REQUIRE([_AM_FILESYSTEM_TIMESTAMP_RESOLUTION])
+[
# This check should not be cached, as it may vary across builds of
# different projects.
AC_MSG_CHECKING([whether build environment is sane])
@@ -179,6 +179,14 @@ for am_try in 1 2; do
am_build_env_is_sane=yes
break
fi
+ # Determine am_cv_filesystem_timestamp_resolution. Do it only on the first
+ # loop round, since it is expensive. Do so without visible output, because
+ # we're already in a AC_MSG_CHECKING..AC_MSG_RESULT block.
+ if test $am_try = 1; then
+ exec 9>&AS_MESSAGE_FD AS_MESSAGE_FD>/dev/null
+ _AM_FILESYSTEM_TIMESTAMP_RESOLUTION
+ exec AS_MESSAGE_FD>&9 9>&-
+ fi
# Just in case.
sleep $am_cv_filesystem_timestamp_resolution
am_has_slept=yes
--
2.34.1