Discussion:
Dynamic package version numbers with Autoconf and Automake (was: Re: Automake 1.12.0b test release)
Stefano Lattarini
2012-08-14 22:16:23 UTC
Permalink
Hi Bob, I managed to find your old message about "dynamically computing
package versions for Automake and Autoconf". Some initial comments
follows. I'm adding the Autoconf list in CC:, because I believe this
is an Autoconf issue more than an Automake one.
Stefano,
- Support for the two- and three-arguments invocation forms of the
AM_INIT_AUTOMAKE macro will be deprecated in the next minor version
of Automake (1.12.1) and removed in the next major version (1.13).
GraphicsMagick invokes it like
AM_INIT_AUTOMAKE($PACKAGE_NAME,"${PACKAGE_VERSION}${PACKAGE_VERSION_ADDENDUM}", ' ')
The reason is because it avoids needing to edit configure.ac (a really stupid
practice)
I agree with this; with today's DVCS, it's very tempting (and IMHO useful)
to base a package's version number on the current revision number/SHA-1; so
that the version is bound to change with every commit, and forcing a full
re-autotooling + reconfiguration + rebuild of the package for every commit
sounds just crazy.

But then, I believe this is something that should to be fixed at the Autoconf
level. I.e., the version number shouldn't be hard-coded in the generated
configure and config.status scripts, nor put in 'config.h' or other generated
headers -- or at least, we should be able to tell Autoconf not do that, and
how to fetch/define/compute the version number at runtime instead.
every time a new release tarball will be cut. Instead the version information
to apply is computed by a script which is sourced by configure.
What is the workaround for this?
Actually, it depends. Where and why do you use such dynamically-computed
version number in exactly?

Thanks,
Stefano
Bob Friesenhahn
2012-08-14 22:26:17 UTC
Permalink
Post by Stefano Lattarini
AM_INIT_AUTOMAKE($PACKAGE_NAME,"${PACKAGE_VERSION}${PACKAGE_VERSION_ADDENDUM}", ' ')
The reason is because it avoids needing to edit configure.ac (a really stupid
practice)
I agree with this; with today's DVCS, it's very tempting (and IMHO useful)
to base a package's version number on the current revision number/SHA-1; so
that the version is bound to change with every commit, and forcing a full
re-autotooling + reconfiguration + rebuild of the package for every commit
sounds just crazy.
Yes, and in your suggested scenario, it is not possible to edit a file
without adding a new changeset (Catch-22).
Post by Stefano Lattarini
But then, I believe this is something that should to be fixed at the Autoconf
level. I.e., the version number shouldn't be hard-coded in the generated
configure and config.status scripts, nor put in 'config.h' or other generated
headers -- or at least, we should be able to tell Autoconf not do that, and
how to fetch/define/compute the version number at runtime instead.
Agreed.
Post by Stefano Lattarini
every time a new release tarball will be cut. Instead the version information
to apply is computed by a script which is sourced by configure.
What is the workaround for this?
Actually, it depends. Where and why do you use such dynamically-computed
version number in exactly?
A script ("version.sh") is executed in order to obtain the package and
version information. In the most common case, the version is a
development "snapshot" and the version is based on the latest
specified date in the ChangeLog file. For formal releases, the
version is hard-coded in the script.

Any time that 'make' is executed is a candidate time for the package
version to be changed. In the GraphicsMagick project, editing the
top ChangeLog file causes configure to be re-executed (due to added
rules). This assures that the version is always correct (at the
expense of more compilation time).

Bob
--
Bob Friesenhahn
***@simple.dallas.tx.us, http://www.simplesystems.org/users/bfriesen/
GraphicsMagick Maintainer, http://www.GraphicsMagick.org/
Bob Friesenhahn
2012-08-14 23:57:02 UTC
Permalink
The script I intend to use to obtain package information is in the
GraphicsMagick repository and produces information gleaned from a
'version.sh' script which has the smarts to produce some obvious
variable names.

echo `./scripts/pkginfo.sh package_bugreport`
graphicsmagick-***@lists.sourceforge.net

% echo `./scripts/pkginfo.sh package_name`
GraphicsMagick

% echo `./scripts/pkginfo.sh package_version`
1.4.020120814

It is intended to be used like this in configure.ac:

AC_INIT(m4_esyscmd([scripts/pkginfo.sh package_name]),
m4_esyscmd([scripts/pkginfo.sh package_version]),
m4_esyscmd([scripts/pkginfo.sh package_bugreport]))

Unfortunately, the values passed to AC_INIT are cached so even if the
configure script is run again, it uses the cached values rather than
the new values.

The script:

#!/bin/sh
#
# Print the package version based on content of $srcdir/version.sh.
#
# This script is expected to be run under the context of a configure
# script (via AC_INIT) to dynamically determine the package version.
me=$0
info=$1
srcdir=`dirname $0`/..
value=
nl='
'
. version.sh

case "${info}" in
package_bugreport )
value="${PACKAGE_BUGREPORT}"
;;
package_name )
value="${PACKAGE_NAME}"
;;
package_version )
value="${PACKAGE_VERSION}${PACKAGE_VERSION_ADDENDUM}"
;;
* )
echo "$me: Must supply argument {package_bugreport, package_name, package_version}"
exit 1
;;
esac

# Omit the trailing newline, so that m4_esyscmd can use the result directly.
echo "${value}" | tr -d "$nl"
--
Bob Friesenhahn
***@simple.dallas.tx.us, http://www.simplesystems.org/users/bfriesen/
GraphicsMagick Maintainer, http://www.GraphicsMagick.org/
Roger Leigh
2012-08-15 13:36:38 UTC
Permalink
Post by Bob Friesenhahn
AC_INIT(m4_esyscmd([scripts/pkginfo.sh package_name]),
m4_esyscmd([scripts/pkginfo.sh package_version]),
m4_esyscmd([scripts/pkginfo.sh package_bugreport]))
Unfortunately, the values passed to AC_INIT are cached so even if
the configure script is run again, it uses the cached values rather
than the new values.
I've been doing a similar thing, though I do it directly in configure.ac
rather than using an external script:

AC_INIT(sbuild_m4_esyscmd_s([sed -ne '/^Package:/{s/Package:[[:space:]][[:space:]]*//p;q}' VERSION]),
[sbuild_m4_esyscmd_s([sed -ne '/^Version:/{s/Version:[[:space:]][[:space:]]*//p;q}' VERSION])],
[buildd-tools-***@lists.alioth.debian.org])

In this case, the information is taken from a static file with the format:

Package: schroot
Version: 1.6.3
Release-Date: 23 Jul 2012
Released-By: Roger Leigh <***@debian.org>
Git-Tag: release/schroot-1.6.3

This is generated by the bootstrap script.
Package and Version are derived from NEWS (since this must be updated
for a release, we require the version here to be the definitive source
of the version.
The other date is taken from the release tag in git; if it's not a
release, i.e. isn't tagged, it's just left as "Unreleased".

Your version is better, because it permits vanilla autoreconf to be
used. Providing that we have a stable interface for autoconf to
call an external script, packages could do whatever they wish to
provide the information. Maybe a single-argument AC_INIT which
just has a script file as its argument? However it's done, having
this standardised would be beneficial to all.

In addition to it invoking the script with arguments for
package, version and bugreport address, it might also be nice to
provide the ability to supply information for arbitrary other
stuff such as
- public git URI
- public website
- public bug tracker
- git release and distribution tags
- git branch

And perhaps also allow this to be extended by the builder/distributor,
for example with
- build date
- builder
- distribution
- distribution bug tracker etc.

These are all examples of things which are currently done by some
packages on an ad-hoc basis, but which would benefit from more
generalised support in autoconf. Maybe add a command-line option
to run additional script(s) to source supplementary/overriding
information?


On the automake side, I'm still using custom targets for git integration
with "make dist" which inject $(distdir) into a separate git branch and
tag that as a "distribution"; a separate step tags the "release", which
is then distributed. If it's not possible to support directly in
automake, being able to disable tarball generation in the dist target
and do completely custom stuff there would be useful. In particular,
having a logical separation of "releasing" and "distributing" would be
good.

One thing which is currently done wrong is that some stuf, e.g.
gettext, tries to regenerate stuff at "make dist" time. This is
rather annoying, as it's creating updated versions of files /after/
you've tagged the release. This means you need to run "make dist", then
tag, then run "make dist" again. While workable, it's easy to forget and
mess up the release process. When you're using a DVCS, this is the wrong
point. We only want to tag the release /after/ all sources changes have
been made and *committed*. Thus there are three steps:

1) release preparation
- updates any files e.g. gettext po files etc.
- commit any changes resulting from this step
2) release
- tags the repo with a signed release tag
3) distribution
- makes the distdir and injects it onto a distribution branch
- branch is tagged
- release tarball is obtained (if required) using "git archive"
to export the tagged distribution. Not needed for an all-git
workflow (e.g. future Debian git source package format).

The existing "make dist" does of course do everything in a single
step; but it would be nice if these were split into separate,
overridable/hookable targets, and tools like gettext updated to
run in the release prep stage.


Regards,
Roger
--
.''`. Roger Leigh
: :' : Debian GNU/Linux http://people.debian.org/~rleigh/
`. `' schroot and sbuild http://alioth.debian.org/projects/buildd-tools
`- GPG Public Key F33D 281D 470A B443 6756 147C 07B3 C8BC 4083 E800
Miles Bader
2012-08-15 04:13:21 UTC
Permalink
Post by Stefano Lattarini
Actually, it depends. Where and why do you use such
dynamically-computed version number in exactly?
That seems the real question.

My own method is to have:

(1) The "primary" version number is based on VCS info (this is
obviously unavailable for source trees not based on a VCS
checkout).

(2) The "autoconf" version number (in AC_INIT) is used as a
backup/default only when VCS info is unavailable. This number is
relatively static, and typically only updated after a release.

(3) The final version info is updated (using VCS info and/or autoconf
version info) at make time using a script, and when it changes,
only causes a source file (e.g., version.c) to change.

This means that although some things are rebuilt after a commit
(version.o, and relinking of any binaries that use it), the amount
of rebuilding is relatively minor while still yielding accurate
info.

-miles
--
Non-combatant, n. A dead Quaker.
Bob Friesenhahn
2012-08-15 13:45:01 UTC
Permalink
Post by Miles Bader
(3) The final version info is updated (using VCS info and/or autoconf
version info) at make time using a script, and when it changes,
only causes a source file (e.g., version.c) to change.
This means that although some things are rebuilt after a commit
(version.o, and relinking of any binaries that use it), the amount
of rebuilding is relatively minor while still yielding accurate
info.
Likewise, GraphicsMagick configures a "version.h" as well as a version
file used for non-autotools builds under Windows. With the currently
used mechanism, only the few files depending on version.h need to be
rebuilt but the whole project relinks.

If the project "config.h" was to be re-generated (seems to be
necessary with new AC_INIT), then all of the source modules would need
to be recompiled and relinked since everything depends on the
configuration header.

Bpb
--
Bob Friesenhahn
***@simple.dallas.tx.us, http://www.simplesystems.org/users/bfriesen/
GraphicsMagick Maintainer, http://www.GraphicsMagick.org/
Robert Boehne
2012-08-15 16:58:46 UTC
Permalink
Post by Bob Friesenhahn
Post by Miles Bader
(3) The final version info is updated (using VCS info and/or autoconf
version info) at make time using a script, and when it changes,
only causes a source file (e.g., version.c) to change.
This means that although some things are rebuilt after a commit
(version.o, and relinking of any binaries that use it), the amount
of rebuilding is relatively minor while still yielding accurate
info.
Likewise, GraphicsMagick configures a "version.h" as well as a version
file used for non-autotools builds under Windows. With the currently
used mechanism, only the few files depending on version.h need to be
rebuilt but the whole project relinks.
If the project "config.h" was to be re-generated (seems to be
necessary with new AC_INIT), then all of the source modules would need
to be recompiled and relinked since everything depends on the
configuration header.
Bpb
I've had a similar complaint when using Autotest. In my project, the
test suite depends on an M4 input file that has the project version
encoded in it.
cat test_suite/package.m4
# Signature of the current package.
m4_define([AT_PACKAGE_NAME], [my_server])
m4_define([AT_PACKAGE_TARNAME], [my_server])
m4_define([AT_PACKAGE_MINOR_VERSION], 4.18)
m4_define([AT_PACKAGE_VERSION], [4.18.5])
m4_define([AT_PACKAGE_STRING], [my_server 4.18.5])

Which is created by a makefile rule as suggested in the autoconf
documentation:

http://www.gnu.org/software/autoconf/manual/autoconf.html#Making-testsuite-Scripts

So when I change the version of the package, I autoreconf, then make
then autoreconf again.

Scenario #2 -

I have inherited a library versioning scheme that doesn't play nice with
Libtool (an absolute requirement)
when the Automake name is not encoded with the version -

lib_LTLIBRARIES = libmy_server-4.18.la

So every time I change the version argument to AC_INIT, I have to
search around my makefiles for anything
that references each library and make the same changes there.

So I would be very interested in a solution to these issues.

Cheers,

Robert
Stefano Lattarini
2012-08-24 09:43:33 UTC
Permalink
Reference:
<http://lists.gnu.org/archive/html/automake/2012-08/msg00025.html>
Post by Stefano Lattarini
Hi Bob, I managed to find your old message about "dynamically computing
package versions for Automake and Autoconf". Some initial comments
follows. I'm adding the Autoconf list in CC:, because I believe this
is an Autoconf issue more than an Automake one.
Stefano,
- Support for the two- and three-arguments invocation forms of the
AM_INIT_AUTOMAKE macro will be deprecated in the next minor version
of Automake (1.12.1) and removed in the next major version (1.13).
GraphicsMagick invokes it like
AM_INIT_AUTOMAKE($PACKAGE_NAME,"${PACKAGE_VERSION}${PACKAGE_VERSION_ADDENDUM}", ' ')
The reason is because it avoids needing to edit configure.ac (a really stupid
practice)
I agree with this; with today's DVCS, it's very tempting (and IMHO useful)
to base a package's version number on the current revision number/SHA-1; so
that the version is bound to change with every commit, and forcing a full
re-autotooling + reconfiguration + rebuild of the package for every commit
sounds just crazy.
But then, I believe this is something that should to be fixed at the Autoconf
level. I.e., the version number shouldn't be hard-coded in the generated
configure and config.status scripts, nor put in 'config.h' or other generated
headers -- or at least, we should be able to tell Autoconf not do that, and
how to fetch/define/compute the version number at runtime instead.
every time a new release tarball will be cut. Instead the version information
to apply is computed by a script which is sourced by configure.
What is the workaround for this?
Actually, it depends. Where and why do you use such dynamically-computed
version number in exactly?
Since we've not managed to find a proper workaround yet, nor a consensus on
how this should be fixed in Autoconf, I want to revert the removal of support
for two-args (and three-args) AM_INIT_AUTOMAKE invocation in Automake 1.13.

Below is the proposed patch, that I'll push in a couple of days. Reviews
welcome.

Regards,
Stefano

-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----
Post by Stefano Lattarini
From 2abe18335cffce365cbe09bdc1d0315f5ed8f24d Mon Sep 17 00:00:00 2001
Message-Id: <***@gmail.com>
From: Stefano Lattarini <***@gmail.com>
Date: Fri, 24 Aug 2012 10:47:17 +0200
Subject: [PATCH] AM_INIT_AUTOMAKE: allow obsolescent two-args invocation once
again

This partially reverts commit 'v1.12-67-ge186355' of 2012-05-25,
"init: obsolete usages of AM_INIT_AUTOMAKE not supported anymore"

Some users still need to be able to define the version number for
their package dynamically, at configure runtime.

Their user case is that, for development snapshots, they want to be
able to base the complete version of the package on the VCS revision
ID (mostly Git or Mercurial). They could of course do so by
specifying such version dynamically in their call to AC_INIT, as is
done by several GNU packages. But then they would need to regenerate
and re-run the configure script before each snapshot, which might be
very time-consuming for complex packages, to the point of slowing
down and even somewhat impeding development.

The situation should truly be solved in Autoconf, by allowing a way
to specify the version dynamically in a way that doesn't force the
configure script to be regenerated and re-run every time the package
version changes. But until Autoconf has been improved to allow
this, Automake will have to support the obsolescent two-arguments
invocation for AM_INIT_AUTOMAKE, to avoid regressing the suboptimal
but working solution for the use case described above.

See also:
<http://lists.gnu.org/archive/html/automake/2012-08/msg00025.html>

* NEWS: Update.
* m4/init.m4 (AM_INIT_AUTOMAKE): Support once again invocation with
two or three arguments.
* t/aminit-moreargs-no-more.sh: Renamed ...
* t/aminit-moreargs-deprecated.sh: ... like this, and updated.
* t/nodef.sh: Recovered test, with minor adjustments.
* t/backcompat.sh: Likewise.
* t/backcompat2.sh: Likewise.
* t/backcompat3.sh: Likewise.
* t/backcompat6.sh: Likewise.
* t/list-of-tests.mk: Adjust.

Suggested-by: Bob Friesenhahn n<***@simple.dallas.tx.us>
Signed-off-by: Stefano Lattarini <***@gmail.com>
---
NEWS | 15 ++-
m4/init.m4 | 26 +++-
...s-no-more.sh => aminit-moreargs-deprecation.sh} | 18 ++-
t/backcompat.sh | 64 +++++++++
t/backcompat2.sh | 73 ++++++++++
t/backcompat3.sh | 147 +++++++++++++++++++++
t/backcompat6.sh | 104 +++++++++++++++
t/list-of-tests.mk | 7 +-
t/nodef.sh | 58 ++++++++
9 files changed, 489 insertions(+), 23 deletions(-)
rename t/{aminit-moreargs-no-more.sh => aminit-moreargs-deprecation.sh} (73%)
create mode 100755 t/backcompat.sh
create mode 100755 t/backcompat2.sh
create mode 100755 t/backcompat3.sh
create mode 100755 t/backcompat6.sh
create mode 100755 t/nodef.sh

diff --git a/NEWS b/NEWS
index 59b86ea..5490e72 100644
--- a/NEWS
+++ b/NEWS
@@ -7,11 +7,6 @@ New in 1.13:
- The rules to build PDF and DVI output from Texinfo input now
requires Texinfo 4.9 or later.

-* Obsolete features removed:
-
- - Use of the long-deprecated two- and three-arguments invocation forms
- of the AM_INIT_AUTOMAKE is not supported anymore.
-
- Support for the "Cygnus-style" trees (once enabled by the 'cygnus'
option) has been removed. See discussion about automake bug#11034
for more background.
@@ -44,6 +39,16 @@ New in 1.13:

- All the "old alias" macros in 'm4/obsolete.m4' have been removed.

+* Obsolescent features:
+
+ - Use of the long-deprecated two- and three-arguments invocation forms
+ of the AM_INIT_AUTOMAKE is not documented anymore. It's still
+ supported though (albeit with a warning in the 'obsolete' category),
+ to cater for people who want to define the version number for their
+ package dynamically (e.g., from the current VCS revision). We'll
+ have to continue this support until Autoconf itself is fixed to allow
+ better support for such dynamic version numbers.
+
* Elisp byte-compilation:

- The byte compilation of '.el' files into '.elc' files is now done
diff --git a/m4/init.m4 b/m4/init.m4
index 1d5dffd..fc05148 100644
--- a/m4/init.m4
+++ b/m4/init.m4
@@ -9,8 +9,17 @@
# This macro actually does too much. Some checks are only needed if
# your package does certain things. But this isn't really a big deal.

+# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
# AM_INIT_AUTOMAKE([OPTIONS])
-# ---------------------------
+# -----------------------------------------------
+# The call with PACKAGE and VERSION arguments is the old style
+# call (pre autoconf-2.50), which is being phased out. PACKAGE
+# and VERSION should now be passed to AC_INIT and removed from
+# the call to AM_INIT_AUTOMAKE.
+# We support both call styles for the transition. After
+# the next Automake release, Autoconf can make the AC_INIT
+# arguments mandatory, and then we can depend on a new Autoconf
+# release and drop the old call support.
AC_DEFUN([AM_INIT_AUTOMAKE],
[AC_PREREQ([2.65])dnl
dnl Autoconf wants to disallow AM_ names. We explicitly allow
@@ -39,18 +48,21 @@ fi
AC_SUBST([CYGPATH_W])

# Define the identity of the package.
-dnl Error out on old-style AM_INIT_AUTOMAKE calls.
-m4_ifval([$2], [m4_fatal(
-[$0: old-style two- and three-arguments forms are now unsupported. For more info:
-http://www.gnu.org/software/automake/manual/automake.html#Modernize-AM_INIT_AUTOMAKE-invocation])])
-_AM_SET_OPTIONS([$1])dnl
+dnl Distinguish between old-style and new-style calls.
+m4_ifval([$2],
+[AC_DIAGNOSE([obsolete],
+ [$0: two- and three-arguments forms are deprecated.])
+m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl
+ AC_SUBST([PACKAGE], [$1])dnl
+ AC_SUBST([VERSION], [$2])],
+[_AM_SET_OPTIONS([$1])dnl
dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT.
m4_if(
m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]),
[ok:ok],,
[m4_fatal([AC_INIT should be called with package and version arguments])])dnl
AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl
- AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])dnl
+ AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl

_AM_IF_OPTION([no-define],,
[AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package])
diff --git a/t/aminit-moreargs-no-more.sh b/t/aminit-moreargs-deprecation.sh
similarity index 73%
rename from t/aminit-moreargs-no-more.sh
rename to t/aminit-moreargs-deprecation.sh
index ce30c29..a8d4605 100755
--- a/t/aminit-moreargs-no-more.sh
+++ b/t/aminit-moreargs-deprecation.sh
@@ -14,16 +14,12 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

-# Check that automake error out (with an helpful error message) against
-# old-style usages of AM_INIT_AUTOMAKE (i.e., calls with two or three
-# arguments).
+# Check that automake warns against old-style usages of AM_INIT_AUTOMAKE
+# (i.e., calls with two or three arguments).

. ./defs || exit 1

-warn_rx='AM_INIT_AUTOMAKE.* old-style two-.* three-arguments form.*unsupported'
-
-$ACLOCAL
-mv aclocal.m4 aclocal.sav
+warn_rx='AM_INIT_AUTOMAKE.* two-.* three-arguments form.*deprecated'

cat > configure.ac <<'END'
AC_INIT([Makefile.am])
@@ -31,14 +27,16 @@ AM_INIT_AUTOMAKE([twoargs], [1.0])
AC_CONFIG_FILES([Makefile])
END

+$ACLOCAL
+
do_check()
{
rm -rf autom4te*.cache
- for cmd in "$ACLOCAL" "$AUTOCONF" "$AUTOMAKE"; do
- cp aclocal.sav aclocal.m4
- $cmd -Wnone -Wno-error 2>stderr && { cat stderr; exit 1; }
+ for cmd in "$AUTOCONF" "$AUTOMAKE"; do
+ $cmd -Werror -Wnone -Wobsolete 2>stderr && { cat stderr; exit 1; }
cat stderr >&2
grep "^configure\.ac:2:.*$warn_rx" stderr
+ $cmd -Werror -Wall -Wno-obsolete || exit 1
done
}

diff --git a/t/backcompat.sh b/t/backcompat.sh
new file mode 100755
index 0000000..fa83687
--- /dev/null
+++ b/t/backcompat.sh
@@ -0,0 +1,64 @@
+#! /bin/sh
+# Copyright (C) 2010-2012 Free Software Foundation, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# Test usage of AM_INIT_AUTOMAKE with two or three arguments, for
+# backward-compatibility.
+
+. ./defs || exit 1
+
+cat > Makefile.am <<'END'
+.PHONY: test display
+
+## Might be useful for debugging.
+display:
+## The following should be substituted by AM_INIT_AUTOMAKE.
+ @echo PACKAGE = $(PACKAGE)
+ @echo VERSION = $(VERSION)
+## The following should not be substituted, as we used the
+## old form of AC_INIT.
+ @echo PACKAGE_NAME = $(PACKAGE_NAME)
+ @echo PACKAGE_VERSION = $(PACKAGE_VERSION)
+ @echo PACKAGE_TARNAME = $(PACKAGE_TARNAME)
+ @echo PACKAGE_STRING = $(PACKAGE_STRING)
+
+test: display
+ test x'$(PACKAGE)' = x'FooBar'
+ test x'$(VERSION)' = x'0.7.1'
+ test x'$(PACKAGE_NAME)' = x
+ test x'$(PACKAGE_VERSION)' = x
+ test x'$(PACKAGE_TARNAME)' = x
+ test x'$(PACKAGE_STRING)' = x
+END
+
+for ac_init in 'AC_INIT' 'AC_INIT([Makefile.am])'; do
+ for am_extra_args in '' ', []' ', [:]' ', [false]'; do
+ rm -rf autom4te*.cache config* Makefile.in Makefile
+ unindent > configure.in <<END
+ $ac_init
+ AM_INIT_AUTOMAKE([FooBar], [0.7.1]$am_extra_args)
+ AC_CONFIG_FILES([Makefile])
+ AC_OUTPUT
+END
+ cat configure.in # For debugging.
+ $ACLOCAL
+ $AUTOCONF
+ $AUTOMAKE -Wno-obsolete
+ ./configure
+ $MAKE test
+ done
+done
+
+:
diff --git a/t/backcompat2.sh b/t/backcompat2.sh
new file mode 100755
index 0000000..109483b
--- /dev/null
+++ b/t/backcompat2.sh
@@ -0,0 +1,73 @@
+#! /bin/sh
+# Copyright (C) 2010-2012 Free Software Foundation, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# Backward-compatibility test: check that AM_INIT_AUTOMAKE with two or
+# three arguments does AC_DEFINE the symbols PACKAGE and VERSION iff the
+# third argument is empty or non-existent.
+
+am_create_testdir=empty
+. ./defs || exit 1
+
+# A trick to make the test run muuuch faster, by avoiding repeated
+# runs of aclocal (one order of magnitude improvement in speed!).
+echo 'AC_INIT(x,0) AM_INIT_AUTOMAKE' > configure.ac
+$ACLOCAL
+rm -rf configure.ac autom4te.*
+
+touch install-sh missing
+
+cat > config.h.in <<'END'
+#undef PACKAGE
+#undef VERSION
+END
+
+for am_arg3 in ':' 'false' '#' ' '; do
+ unindent > configure.ac <<END
+ AC_INIT
+ AC_CONFIG_HEADERS([config.h])
+ AM_INIT_AUTOMAKE([pkgname], [pkgversion], [$am_arg3])
+ AC_OUTPUT
+END
+ cat configure.ac # For debugging.
+ $AUTOCONF
+ ./configure
+ cat config.h # For debugging.
+ # The non-empty third argument should prevent PACKAGE and VERSION
+ # from being AC_DEFINE'd.
+ $EGREP 'pkg(name|version)' config.h && exit 1
+ # This is required because even relatively-recent versions of the
+ # BSD shell wrongly exit when the 'errexit' shell flag is active if
+ # the last command of a compound statement fails, even if it should
+ # be protected by the use of "&&".
+ :
+done
+
+for am_extra_args in '' ',' ', []'; do
+ unindent > configure.ac <<END
+ AC_INIT
+ AC_CONFIG_HEADERS([config.h])
+ AM_INIT_AUTOMAKE([pkgname], [pkgversion]$am_extra_args)
+ AC_OUTPUT
+END
+ cat configure.ac # For debugging.
+ $AUTOCONF
+ ./configure
+ cat config.h # For debugging.
+ grep '^ *# *define *PACKAGE *"pkgname" *$' config.h
+ grep '^ *# *define *VERSION *"pkgversion" *$' config.h
+done
+
+:
diff --git a/t/backcompat3.sh b/t/backcompat3.sh
new file mode 100755
index 0000000..26ea7d4
--- /dev/null
+++ b/t/backcompat3.sh
@@ -0,0 +1,147 @@
+#! /bin/sh
+# Copyright (C) 2010-2012 Free Software Foundation, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# Backward-compatibility test: check what happens when AC_INIT and
+# AM_INIT_AUTOMAKE are both given two or more arguments.
+
+am_create_testdir=empty
+. ./defs || exit 1
+
+empty=''
+
+AUTOMAKE="$AUTOMAKE -Wno-obsolete"
+
+cat > Makefile.am <<'END'
+## Leading ':;' here required to work around bugs of (at least) bash 3.2
+got: Makefile
+ @:; { \
+ echo 'PACKAGE = $(PACKAGE)'; \
+ echo 'VERSION = $(VERSION)'; \
+ echo 'PACKAGE_NAME = $(PACKAGE_NAME)'; \
+ echo 'PACKAGE_VERSION = $(PACKAGE_VERSION)'; \
+ echo 'PACKAGE_STRING = $(PACKAGE_STRING)'; \
+ echo 'PACKAGE_TARNAME = $(PACKAGE_TARNAME)'; \
+ echo 'PACKAGE_BUGREPORT = $(PACKAGE_BUGREPORT)'; \
+ echo 'PACKAGE_URL = $(PACKAGE_URL)'; \
+ } >$@
+END
+
+
+### Run 1 ###
+
+cat > configure.ac <<END
+AC_INIT([ac_name], [ac_version])
+AM_INIT_AUTOMAKE([am_name], [am_version])
+AC_CONFIG_FILES([Makefile])
+AC_OUTPUT
+END
+
+cat configure.ac
+
+$ACLOCAL
+$AUTOCONF
+$AUTOMAKE -a
+
+./configure
+
+cat >exp <<END
+PACKAGE = am_name
+VERSION = am_version
+PACKAGE_NAME = ac_name
+PACKAGE_VERSION = ac_version
+PACKAGE_STRING = ac_name ac_version
+PACKAGE_TARNAME = ac_name
+PACKAGE_BUGREPORT = $empty
+PACKAGE_URL = $empty
+END
+
+$MAKE got
+
+diff exp got
+
+
+### Run 2 ###
+
+cat > configure.ac <<'END'
+AC_INIT([ac_name], [ac_version], [ac_bugreport], [ac_tarname],
+ [ac_url])],
+AM_INIT_AUTOMAKE([am_name], [am_version])
+AC_CONFIG_FILES([Makefile])
+AC_OUTPUT
+END
+
+cat configure.ac
+
+$ACLOCAL
+$AUTOCONF
+$AUTOMAKE
+
+./configure
+
+cat >exp <<END
+PACKAGE = am_name
+VERSION = am_version
+PACKAGE_NAME = ac_name
+PACKAGE_VERSION = ac_version
+PACKAGE_STRING = ac_name ac_version
+PACKAGE_TARNAME = ac_tarname
+PACKAGE_BUGREPORT = ac_bugreport
+PACKAGE_URL = ac_url
+END
+
+$MAKE got
+
+diff exp got
+
+
+### Run 3 ###
+
+cat > configure.ac <<END
+AC_INIT([ac_name], [ac_version])
+AM_INIT_AUTOMAKE([am_name], [am_version], [am_foo_quux])
+AC_CONFIG_FILES([Makefile])
+AC_OUTPUT
+END
+
+cat configure.ac
+
+$ACLOCAL
+$AUTOCONF
+$AUTOMAKE
+
+./configure
+
+cat >exp <<END
+PACKAGE = am_name
+VERSION = am_version
+PACKAGE_NAME = ac_name
+PACKAGE_VERSION = ac_version
+PACKAGE_STRING = ac_name ac_version
+PACKAGE_TARNAME = ac_name
+PACKAGE_BUGREPORT = $empty
+PACKAGE_URL = $empty
+END
+
+$MAKE got
+
+diff exp got
+
+$FGREP am_foo_quux Makefile.in Makefile configure config.status && exit 1
+
+
+### Done ###
+
+:
diff --git a/t/backcompat6.sh b/t/backcompat6.sh
new file mode 100755
index 0000000..9fc4946
--- /dev/null
+++ b/t/backcompat6.sh
@@ -0,0 +1,104 @@
+#! /bin/sh
+# Copyright (C) 2010-2012 Free Software Foundation, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# Backward-compatibility test: try to build and distribute a package
+# using obsoleted forms of AC_INIT, AM_INIT_AUTOMAKE and AC_OUTPUT.
+# This script can also serve as mild stress-testing for Automake.
+# See also the similar test 'backcompat5.test'.
+
+required=cc
+am_create_testdir=empty
+. ./defs || exit 1
+
+# Anyone doing something like this in a real-life package probably
+# deserves to be killed.
+cat > configure.ac <<'END'
+dnl: Everything here is *deliberately* underquoted!
+AC_INIT(quux.c)
+PACKAGE=nonesuch-zardoz
+VERSION=nonesuch-0.1
+AM_INIT_AUTOMAKE($PACKAGE, $VERSION)
+AC_SUBST(one,1)
+two=2
+AC_SUBST(two, $two)
+three=3
+AC_SUBST(three)
+AC_PROG_CC
+AC_CONFIG_HEADERS(config.h:config.hin)
+AM_CONDITIONAL(CROSS_COMPILING, test "$cross_compiling" = yes)
+AC_OUTPUT(Makefile foo.got:foo1.in:foo2.in:foo3.in)
+END
+
+echo @one@ > foo1.in
+echo @two@ > foo2.in
+echo @three@ > foo3.in
+
+cat >config.hin <<'END'
+#undef PACKAGE
+#undef VERSION
+END
+
+cat >> Makefile.am <<'END'
+bin_PROGRAMS = foo
+foo_SOURCES = quux.c
+check-local:
+ test x'$(PACKAGE)' = x'nonesuch-zardoz'
+ test x'$(VERSION)' = x'nonesuch-0.1'
+if ! CROSS_COMPILING
+ ./foo
+## Do not anchor the regexps w.r.t. the end of line, because on
+## MinGW/MSYS, grep may assume LF line endings only, while our
+## 'foo' program may generate CRLF line endings.
+ ./foo | grep '^PACKAGE = nonesuch-zardoz!'
+ ./foo | echo '^VERSION = nonesuch-0\.1!'
+endif
+END
+
+cat > quux.c <<'END'
+#include <config.h>
+#include <stdio.h>
+int main (void)
+{
+ printf("PACKAGE = %s!\nVERSION = %s!\n", PACKAGE, VERSION);
+ return 0;
+}
+END
+
+$ACLOCAL
+$AUTOMAKE -Wno-obsolete --add-missing
+$AUTOCONF
+
+./configure
+
+cat >foo.exp <<'END'
+1
+2
+3
+END
+
+diff foo.exp foo.got
+
+$MAKE
+$MAKE check
+
+distdir=nonesuch-zardoz-nonesuch-0.1
+$MAKE distdir
+test -f $distdir/quux.c
+test ! -f $distdir/foo.got
+
+$MAKE distcheck
+
+:
diff --git a/t/list-of-tests.mk b/t/list-of-tests.mk
index a299262..2706e95 100644
--- a/t/list-of-tests.mk
+++ b/t/list-of-tests.mk
@@ -124,7 +124,7 @@ t/alpha2.sh \
t/amhello-cflags.sh \
t/amhello-cross-compile.sh \
t/amhello-binpkg.sh \
-t/aminit-moreargs-no-more.sh \
+t/aminit-moreargs-deprecation.sh \
t/amassign.sh \
t/am-macro-not-found.sh \
t/amopt.sh \
@@ -172,6 +172,10 @@ t/auxdir-computed.tap \
t/auxdir-misplaced.sh \
t/auxdir-nonexistent.sh \
t/auxdir-unportable.tap \
+t/backcompat.sh \
+t/backcompat2.sh \
+t/backcompat3.sh \
+t/backcompat6.sh \
t/backcompat-acout.sh \
t/backsl.sh \
t/backsl2.sh \
@@ -688,6 +692,7 @@ t/nobase.sh \
t/nobase-libtool.sh \
t/nobase-python.sh \
t/nobase-nodist.sh \
+t/nodef.sh \
t/nodef2.sh \
t/nodep.sh \
t/nodep2.sh \
diff --git a/t/nodef.sh b/t/nodef.sh
new file mode 100755
index 0000000..979b906
--- /dev/null
+++ b/t/nodef.sh
@@ -0,0 +1,58 @@
+#! /bin/sh
+# Copyright (C) 2002-2012 Free Software Foundation, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# Make sure that PACKAGE and VERSION are AC_DEFINEd when requested.
+
+. ./defs || exit 1
+
+# -------------------------------------------------------------------
+# Do not upgrade this file to use the modern AC_INIT/AM_INIT_AUTOMAKE
+# forms. The day these obsolete AC_INIT and AM_INIT_AUTOMAKE forms
+# are dropped, just erase the file.
+# nodef2.test contains the modern version of this test.
+# -------------------------------------------------------------------
+
+# First, check that PACKAGE and VERSION are output by default.
+
+cat > configure.ac << 'END'
+AC_INIT
+AM_INIT_AUTOMAKE([UnIqUe_PaCkAgE], [UnIqUe_VeRsIoN])
+AC_OUTPUT(output)
+END
+
+echo 'DEFS = @DEFS@' > output.in
+
+$ACLOCAL
+$AUTOCONF
+./configure
+
+grep 'DEFS.*-DVERSION=\\"UnIqUe' output
+
+# Then, check that PACKAGE and VERSION are not output if requested.
+
+cat > configure.ac << 'END'
+AC_INIT
+AM_INIT_AUTOMAKE([UnIqUe_PaCkAgE], [UnIqUe_VeRsIoN], [no])
+AC_OUTPUT(output)
+END
+
+$ACLOCAL
+$AUTOCONF
+./configure
+
+grep 'DEFS.*-DVERSION=\\"UnIqUe' output && exit 1
+
+:
--
1.7.12
Stefano Lattarini
2012-08-26 11:26:32 UTC
Permalink
Post by Stefano Lattarini
<http://lists.gnu.org/archive/html/automake/2012-08/msg00025.html>
Post by Stefano Lattarini
Hi Bob, I managed to find your old message about "dynamically computing
package versions for Automake and Autoconf". Some initial comments
follows. I'm adding the Autoconf list in CC:, because I believe this
is an Autoconf issue more than an Automake one.
Stefano,
- Support for the two- and three-arguments invocation forms of the
AM_INIT_AUTOMAKE macro will be deprecated in the next minor version
of Automake (1.12.1) and removed in the next major version (1.13).
GraphicsMagick invokes it like
AM_INIT_AUTOMAKE($PACKAGE_NAME,"${PACKAGE_VERSION}${PACKAGE_VERSION_ADDENDUM}", ' ')
The reason is because it avoids needing to edit configure.ac (a really stupid
practice)
I agree with this; with today's DVCS, it's very tempting (and IMHO useful)
to base a package's version number on the current revision number/SHA-1; so
that the version is bound to change with every commit, and forcing a full
re-autotooling + reconfiguration + rebuild of the package for every commit
sounds just crazy.
But then, I believe this is something that should to be fixed at the Autoconf
level. I.e., the version number shouldn't be hard-coded in the generated
configure and config.status scripts, nor put in 'config.h' or other generated
headers -- or at least, we should be able to tell Autoconf not do that, and
how to fetch/define/compute the version number at runtime instead.
every time a new release tarball will be cut. Instead the version information
to apply is computed by a script which is sourced by configure.
What is the workaround for this?
Actually, it depends. Where and why do you use such dynamically-computed
version number in exactly?
Since we've not managed to find a proper workaround yet, nor a consensus on
how this should be fixed in Autoconf, I want to revert the removal of support
for two-args (and three-args) AM_INIT_AUTOMAKE invocation in Automake 1.13.
Below is the proposed patch, that I'll push in a couple of days. Reviews
welcome.
Regards,
Stefano
-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----
From 2abe18335cffce365cbe09bdc1d0315f5ed8f24d Mon Sep 17 00:00:00 2001
Date: Fri, 24 Aug 2012 10:47:17 +0200
Subject: [PATCH] AM_INIT_AUTOMAKE: allow obsolescent two-args invocation once
again
This partially reverts commit 'v1.12-67-ge186355' of 2012-05-25,
"init: obsolete usages of AM_INIT_AUTOMAKE not supported anymore"
Some users still need to be able to define the version number for
their package dynamically, at configure runtime.
Their user case is that, for development snapshots, they want to be
able to base the complete version of the package on the VCS revision
ID (mostly Git or Mercurial). They could of course do so by
specifying such version dynamically in their call to AC_INIT, as is
done by several GNU packages. But then they would need to regenerate
and re-run the configure script before each snapshot, which might be
very time-consuming for complex packages, to the point of slowing
down and even somewhat impeding development.
The situation should truly be solved in Autoconf, by allowing a way
to specify the version dynamically in a way that doesn't force the
configure script to be regenerated and re-run every time the package
version changes. But until Autoconf has been improved to allow
this, Automake will have to support the obsolescent two-arguments
invocation for AM_INIT_AUTOMAKE, to avoid regressing the suboptimal
but working solution for the use case described above.
<http://lists.gnu.org/archive/html/automake/2012-08/msg00025.html>
* NEWS: Update.
* m4/init.m4 (AM_INIT_AUTOMAKE): Support once again invocation with
two or three arguments.
* t/aminit-moreargs-no-more.sh: Renamed ...
* t/aminit-moreargs-deprecated.sh: ... like this, and updated.
* t/nodef.sh: Recovered test, with minor adjustments.
* t/backcompat.sh: Likewise.
* t/backcompat2.sh: Likewise.
* t/backcompat3.sh: Likewise.
* t/backcompat6.sh: Likewise.
* t/list-of-tests.mk: Adjust.
Pushed now.

Regards,
Stefano

Loading...