From e518788ad085e02b046e42889039a1f671e4619a Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Wed, 22 Jan 2025 21:21:59 +0100 Subject: [PATCH] New module 'package-version'. * m4/init-package-version.m4: New file, from GNU libunistring. * modules/package-version: New file. * modules/git-version-gen (Depends-on): Add it. --- ChangeLog | 7 +++ m4/init-package-version.m4 | 124 +++++++++++++++++++++++++++++++++++++ modules/git-version-gen | 1 + modules/package-version | 19 ++++++ 4 files changed, 151 insertions(+) create mode 100644 m4/init-package-version.m4 create mode 100644 modules/package-version diff --git a/ChangeLog b/ChangeLog index 7c402b5a0b..87087d2d3b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2025-01-22 Bruno Haible + + New module 'package-version'. + * m4/init-package-version.m4: New file, from GNU libunistring. + * modules/package-version: New file. + * modules/git-version-gen (Depends-on): Add it. + 2025-01-19 Bruno Haible attribute: Add note about ongoing standardization of some attributes. diff --git a/m4/init-package-version.m4 b/m4/init-package-version.m4 new file mode 100644 index 0000000000..525dfe5bf5 --- /dev/null +++ b/m4/init-package-version.m4 @@ -0,0 +1,124 @@ +# init-package-version.m4 +# serial 3 +dnl Copyright (C) 1992-2025 Free Software Foundation, Inc. +dnl This file is free software, distributed under the terms of the GNU +dnl General Public License. As a special exception to the GNU General +dnl Public License, this file may be distributed as part of a program +dnl that contains a configuration script generated by Autoconf, under +dnl the same distribution terms as the rest of that program. + +# Make it possible to pass version numbers extracted from a file in +# $(srcdir) to autoconf. +# +# Autoconf insists on passing the package name and version number to +# every generated .h file and every Makefile. This was a reasonable +# design at times when a version number was changed only once a month. +# Nowadays, people often assign a new version number once a week, or +# even change it each time a 'git' commit is made. Regenerating all +# the files that depend on configure.ac (aclocal.m4, configure, +# config.status, config.h, all Makefiles) may take 15 minutes. These +# delays can severely hamper development. +# +# An alternative is to store the version number in a file in $(srcdir) +# that is separate from configure.ac. It can be a data file, a shell +# script, a .m4 file, or other. The essential point is that the maintainer +# is responsible for creating Makefile dependencies to this version file +# for every file that needs to be rebuilt when the version changes. This +# typically includes +# - distributable documentation files that carry the version number, +# but does not include +# - aclocal.m4, configure, config.status, config.h, all Makefiles, +# - executables. +# +# autoconf and automake make it hard to follow this approach: +# +# - If AC_INIT is used with arguments, there is a chicken-and-egg problem: +# The arguments need to be read from a file in $(srcdir). The location +# of $(srcdir) is only determined by AC_CONFIG_SRCDIR. AC_CONFIG_SRCDIR +# can only appear after AC_INIT (otherwise aclocal gives an error: +# "error: m4_defn: undefined macro: _m4_divert_diversion"). +# Furthermore, the arguments passed to AC_INIT must be literals; for +# example, the assignment to PACKAGE_VERSION looks like this: +# [PACKAGE_VERSION=']AC_PACKAGE_VERSION['] +# +# - If AC_INIT is used without arguments: +# Automake provides its own variables, PACKAGE and VERSION, and uses them +# instead of PACKAGE_NAME and PACKAGE_VERSION that come from Autoconf. +# - If AM_INIT_AUTOMAKE is used with two arguments, automake options +# like 'silent-rules' cannot be specified. +# - If AM_INIT_AUTOMAKE is used in its one-argument form or without +# arguments at all, it triggers an error +# "error: AC_INIT should be called with package and version arguments". +# - If AM_INIT_AUTOMAKE is used in its one-argument form or without +# arguments at all, and _AC_INIT_PACKAGE is used before it, with +# the package and version number from the file as arguments, we get +# a warning: "warning: AC_INIT: not a literal: $VERSION_NUMBER". +# The arguments passed to _AC_INIT_PACKAGE must be literals. +# +# With the macro defined in this file, the approach can be coded like this: +# +# AC_INIT +# AC_CONFIG_SRCDIR(WITNESS) +# . $srcdir/../version.sh +# gl_INIT_PACKAGE(PACKAGE, $VERSION_NUMBER) +# AM_INIT_AUTOMAKE([OPTIONS]) +# +# and after changing version.sh, the developer can directly configure and build: +# +# make distclean +# ./configure +# make +# +# Some other packages use another approach: +# +# AC_INIT(PACKAGE, +# m4_normalize(m4_esyscmd([. ./version.sh; echo $VERSION_NUMBER]))) +# AC_CONFIG_SRCDIR(WITNESS) +# AM_INIT_AUTOMAKE([OPTIONS]) +# +# but here, after changing version.sh, the developer must first regenerate the +# configure file: +# +# make distclean +# ./autogen.sh --skip-gnulib +# ./configure +# make +# + +# gl_INIT_PACKAGE(PACKAGE-NAME, VERSION) +# -------------------------------------- +# followed by an AM_INIT_AUTOMAKE invocation, +# is like calling AM_INIT_AUTOMAKE(PACKAGE-NAME, VERSION) +# except that it can use computed non-literal arguments. +AC_DEFUN([gl_INIT_PACKAGE], +[ + AC_BEFORE([$0], [AM_INIT_AUTOMAKE]) + dnl Redefine AM_INIT_AUTOMAKE. + m4_define([gl_AM_INIT_AUTOMAKE], + m4_bpatsubst(m4_dquote( + m4_bpatsubst(m4_dquote( + m4_bpatsubst(m4_dquote( + m4_defn([AM_INIT_AUTOMAKE])), + [AC_PACKAGE_NAME], [gl_INIT_DUMMY])), + [AC_PACKAGE_TARNAME], [gl_INIT_EMPTY])), + [AC_PACKAGE_VERSION], [gl_INIT_DUMMY]) + [AC_SUBST([PACKAGE], [$1]) + AC_SUBST([VERSION], [$2]) + ]) + m4_define([AM_INIT_AUTOMAKE], + m4_defn([gl_RPL_INIT_AUTOMAKE])) +]) +m4_define([gl_INIT_EMPTY], []) +dnl Automake 1.16.4 no longer accepts an empty value for gl_INIT_DUMMY. +dnl But a macro that later expands to empty works. +m4_define([gl_INIT_DUMMY], [gl_INIT_DUMMY2]) +m4_define([gl_INIT_DUMMY2], []) +AC_DEFUN([gl_RPL_INIT_AUTOMAKE], [ + m4_ifval([$2], + [m4_fatal([After gl_INIT_PACKAGE, the two-argument form of AM_INIT_AUTOMAKE cannot be used.])]) + gl_AM_INIT_AUTOMAKE([$1 no-define]) + m4_if(m4_index([ $1 ], [ no-define ]), [-1], + [AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) + AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package]) + ]) +]) diff --git a/modules/git-version-gen b/modules/git-version-gen index a783ac570d..ee02ef4ee5 100644 --- a/modules/git-version-gen +++ b/modules/git-version-gen @@ -5,6 +5,7 @@ Files: build-aux/git-version-gen Depends-on: +package-version configure.ac: diff --git a/modules/package-version b/modules/package-version new file mode 100644 index 0000000000..fafa8b058a --- /dev/null +++ b/modules/package-version @@ -0,0 +1,19 @@ +Description: +Support for a computed version string. + +Files: +m4/init-package-version.m4 + +Depends-on: + +configure.ac: + +Makefile.am: + +Include: + +License: +GPLed build tool + +Maintainer: +Bruno Haible -- 2.39.5