the tar-v7 and other explicit options to force a particular tar
format are unchanged and still override the default. (bug#74847)
+ - mdate-sh uses SOURCE_DATE_EPOCH, if set, instead of a file's mtime.
+ (bug#77805)
+
- New option dist-bzip3 for bzip3 compression of distributions. (bug#73795)
- New option --stderr-prefix for tap-driver.sh, to prefix each line of
is set to "false", do nothing but exit unsuccessfully, also to match
previous behavior. (bug#74434)
- - The no-dist-built-sources Automake option hopefully now operates as
+ - The no-dist-built-sources Automake option now operates (hopefully) as
intended, i.e., omits the dependency on $(BUILT_SOURCES) for the
distdir target. (bug#69908)
error. (bug#19964)
- The compile script is more robust to Windows configurations;
- specifically, avoiding double-path translation on MSYS. (bug#75939)
+ specifically, avoids double-path translation on MSYS. (bug#75939)
- The test infrastructure sets the CONFIG_SITE environment variable to
/dev/null, to avoid the local system's Autoconf site defaults from
@cindex @code{EDITION} Texinfo flag
@cindex @code{UPDATED-MONTH} Texinfo flag
-@cindex @file{mdate-sh}
+@cindex @file{mdate-sh}, Automake helper script
If a @file{.texi} file @code{@@include}s @file{version.texi} (actually
any file named @file{vers...texi}, then that file will be
@code{@@value@{VERSION@}}, @code{@@value@{UPDATED@}}, and
@code{@@value@{UPDATED-MONTH@}}.
+@vindex SOURCE_DATE_EPOCH@r{, and @command{mdate-sh}}
@table @code
@item EDITION
@itemx VERSION
Both of these flags hold the version number of your program. They are
-kept separate for clarity.
+kept separate for historical reasons.
@item UPDATED
-This holds the date the primary @file{.texi} file was last modified.
+This holds the date the primary @file{.texi} file was last modified,
+or the date of the @env{SOURCE_DATE_EPOCH} variable (see below).
@item UPDATED-MONTH
This holds the name of the month in which the primary @file{.texi} file
-was last modified.
+was last modified, or the month of @env{SOURCE_DATE_EPOCH}.
@end table
The @file{version.texi} support requires the @command{mdate-sh}
included when @command{automake} is invoked with the
@option{--add-missing} option.
+@cindex reproducible builds
+@cindex epoch, and reproducible builds
+If the @env{SOURCE_DATE_EPOCH} environment variable is set,
+@command{mdate-sh} uses its value, instead of the modification time of
+any file. This variable is typically set globally for the sake of
+creating a reproducible build across a distribution. Its value is an
+integer, the number of seconds since the Unix epoch (January 1, 1970,
+00:00:00 UTC). If for any reason the @env{SOURCE_DATE_EPOCH} value
+cannot be converted into the human-readable date strings,
+@command{mdate-sh} falls back to using the given file's mtime.
+
If you have multiple Texinfo files, and you want to use the
@file{version.texi} feature, then you have to have a separate version
file for each Texinfo file. Automake will treat any include in a
#!/bin/sh
-# Get modification time of a file or directory and pretty-print it.
+# Get modification time of a file or directory, or value of
+# $SOURCE_DATE_EPOCH, and pretty-print it, formatted like 1 January 2000.
-scriptversion=2024-12-03.03; # UTC
+scriptversion=2025-05-21.01; # UTC
# Copyright (C) 1995-2025 Free Software Foundation, Inc.
# written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, June 1995
Pretty-print the modification day of FILE, in the format:
1 January 1970
+If the environment variable SOURCE_DATE_EPOCH is set, use its value (in
+epoch-seconds) for the date instead of any FILE mtime. The FILE
+argument is still required in this case, but ignored.
+
Report bugs to <bug-automake@gnu.org>.
GNU Automake home page: <https://www.gnu.org/software/automake/>.
General help using GNU software: <https://www.gnu.org/gethelp/>.
;;
esac
+# Warn if more than one file given.
+if test $# -ne 1; then
+ echo "$0: warning: multiple files given, using first: $*" >&2
+fi
+
error ()
{
echo "$0: $1" >&2
exit 1
}
+# set $month ("January") and $nummonth (1) given arg MON ("Jan").
+mon_to_month ()
+{
+ case $1 in
+ Jan) month=January; nummonth=1;;
+ Feb) month=February; nummonth=2;;
+ Mar) month=March; nummonth=3;;
+ Apr) month=April; nummonth=4;;
+ May) month=May; nummonth=5;;
+ Jun) month=June; nummonth=6;;
+ Jul) month=July; nummonth=7;;
+ Aug) month=August; nummonth=8;;
+ Sep) month=September; nummonth=9;;
+ Oct) month=October; nummonth=10;;
+ Nov) month=November; nummonth=11;;
+ Dec) month=December; nummonth=12;;
+ esac
+}
# Prevent date giving response in another language.
LANG=C
TZ=UTC0
export TZ
+# \f
+# https://reproducible-builds.org/docs/source-date-epoch/
+if test -n "$SOURCE_DATE_EPOCH"; then
+ epoch_ok=true # be optimistic
+ date_fmt="+%d %B %Y"
+ result=`date -u --date="@$SOURCE_DATE_EPOCH" "$date_fmt" 2>/dev/null`
+ if test -z "$result"; then
+ result=`date -u -r "$SOURCE_DATE_EPOCH" "$date_fmt" 2>/dev/null`
+ if test -z "$result"; then
+ # The date command on Solaris 10 and 11 doesn't support any way
+ # to do this. Fall back to Perl.
+ #
+ perlout=`perl -e 'print scalar gmtime($SOURCE_DATE_EPOCH)' 2>/dev/null`
+ # Output is, e.g., Thu Jan 1 00:00:00 1970. Split it apart,
+ # since we need to convert "Jan" to "January".
+ # (We could use cut, but surely if a system has perl, it has awk?)
+ day=`echo $perlout | awk '{print $3}'`
+ mon=`echo $perlout | awk '{print $2}'`
+ mon_to_month $mon # sets $month
+ year=`echo $perlout | awk '{print $5}'`
+ result="$day $month $year"
+ #
+ if test -z "$result"; then
+ echo "$0: warning: SOURCE_DATE_EPOCH was set, but can't convert, ignoring: $SOURCE_DATE_EPOCH" >&2
+ epoch_ok=false
+ fi
+ fi
+ fi
+ #
+ if $epoch_ok; then
+ # Remove leading spaces and zeros. We don't want to get into the
+ # various date options to control this. (Not quoting $result here
+ # isn't important, just another way to omit leading spaces.)
+ result=`echo $result | sed 's/^[ 0]*//'`
+ if test -z "$result"; then
+ echo "$0: SOURCE_DATE_EPOCH was set, but converted to empty: $SOURCE_DATE_EPOCH" >&2
+ epoch_ok=false
+ fi
+ fi
+ if $epoch_ok; then
+ echo $result
+ exit 0
+ else
+ echo "$0: SOURCE_DATE_EPOCH failed, falling back to using mtime on: $1" >&2
+ fi
+fi
+# end of SOURCE_DATE_EPOCH support, rest is about the normal case of
+# using the mtime of the specified file.
+
+# \f
# GNU ls changes its time format in response to the TIME_STYLE
# variable. Since we cannot assume 'unset' works, revert this
# variable to its documented default.
shift
# Add another shift to the command.
command="$command shift;"
- case $1 in
- Jan) month=January; nummonth=1;;
- Feb) month=February; nummonth=2;;
- Mar) month=March; nummonth=3;;
- Apr) month=April; nummonth=4;;
- May) month=May; nummonth=5;;
- Jun) month=June; nummonth=6;;
- Jul) month=July; nummonth=7;;
- Aug) month=August; nummonth=8;;
- Sep) month=September; nummonth=9;;
- Oct) month=October; nummonth=10;;
- Nov) month=November; nummonth=11;;
- Dec) month=December; nummonth=12;;
- esac
+ mon_to_month $1
done
test -n "$month" || error "failed parsing '$ls_command /' output"
# Because of the dummy argument above, month is in $2.
#
# On a POSIX system, we should have
-#
# $# = 5
# $1 = file size
# $2 = month
# $5 = filename
#
# On Darwin 7.7.0 and 7.6.0, we have
-#
# $# = 4
# $1 = day
# $2 = month
# $4 = filename
# Get the month.
-case $2 in
- Jan) month=January; nummonth=1;;
- Feb) month=February; nummonth=2;;
- Mar) month=March; nummonth=3;;
- Apr) month=April; nummonth=4;;
- May) month=May; nummonth=5;;
- Jun) month=June; nummonth=6;;
- Jul) month=July; nummonth=7;;
- Aug) month=August; nummonth=8;;
- Sep) month=September; nummonth=9;;
- Oct) month=October; nummonth=10;;
- Nov) month=November; nummonth=11;;
- Dec) month=December; nummonth=12;;
-esac
+mon_to_month $2
case $3 in
???*) day=$1;;
Nov) nummonthtod=11;;
Dec) nummonthtod=12;;
esac
- # For the first six month of the year the time notation can also
+ # For the first six months of the year the time notation can also
# be used for files modified in the last year.
- if (expr $nummonth \> $nummonthtod) > /dev/null;
+ if (expr $nummonth \> $nummonthtod) >/dev/null;
then
year=`expr $year - 1`
fi;;