| # init-package-version.m4 | |
| # serial 7 | |
| dnl Copyright (C) 1992-2026 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(PACKAGE, [package], [MORE OPTIONS]) | |
| # AC_CONFIG_SRCDIR(WITNESS) | |
| # . $srcdir/../version.sh | |
| # gl_INIT_PACKAGE_VERSION($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_VERSION(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_VERSION], | |
| [ | |
| AC_BEFORE([$0], [AM_INIT_AUTOMAKE]) | |
| dnl Redefine AM_INIT_AUTOMAKE. | |
| m4_define([gl_AM_INIT_AUTOMAKE], | |
| m4_bpatsubst(m4_dquote(m4_defn([AM_INIT_AUTOMAKE])), | |
| [AC_PACKAGE_VERSION], [gl_INIT_DUMMY]) | |
| [dnl Set variables documented in Automake. | |
| AC_SUBST([VERSION], ["$1"]) | |
| dnl Set variables documented in Autoconf. | |
| AC_SUBST([PACKAGE_VERSION], ["$1"]) | |
| AC_SUBST([PACKAGE_STRING], ["AC_PACKAGE_NAME $1"]) | |
| _AC_DEFINE([#undef PACKAGE_VERSION]) | |
| AC_DEFINE_UNQUOTED([PACKAGE_VERSION], ["$1"], | |
| [Define to the version of this package.]) | |
| _AC_DEFINE([#undef PACKAGE_STRING]) | |
| AC_DEFINE_UNQUOTED([PACKAGE_STRING], ["AC_PACKAGE_NAME $1"], | |
| [Define to the full name and version of this package.]) | |
| ]) | |
| 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_VERSION, 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]) | |
| ]) | |
| ]) |