Ralf Wildenhues wrote:
> I have been playing with the idea of having two separate version strings.
> ...
> smells of the developer working around limitations of the tools, rather
> than the tools providing adequate functionality

Yes, exactly.

This approach of two pieces is useful for the PACKAGE name - after all,
even a "GNU Binutils for Fedora" is a "GNU Binutils", and the tarname
remains 'binutils' -, but not for the version.

> > Why AC_INIT(PACKAGE, VERSION) is bad
> > ====================================
> 
> I hear you.  When we go and revise newer interfaces, to find out they
> are not actually better than their older counterparts, we may need to
> ask ourselves if our strategy to move forward can be improved.  Such
> moves are painful, and they should be minimized, which in practice may
> mean that we should think harder when adding new interfaces.

Not "think harder", but "work in an early feedback loop with the users".
It may mean announcing more frequent prereleases. Or it can be achieved by
declaring some new features "experimental" (but documented!) and upgrading
them to "stable" only at the next release.

> > It would be good to be able to invoke AM_INIT_AUTOMAKE with options, and
> > be able to set the package and version names (with computed values)
> > separately.
> 
> So that then there would not be any version nor package information in
> files generated by automake and autoconf and config.status?

No version information, yes. The package information can stay there, since
it does not change between "./configure" and "make distclean".

> do you allow package and version information in config.status output,
> i.e., letting configure be rerun upon version change, in automake lingo,
>   CONFIG_STATUS_DEPENDENCIES = $(srcdir)/../version.sh
> 
> ?

This is undesired. Eric wants to make the version be `git-version-gen`,
which means that it changes at every git commit. We *don't* want to rerun
configure when the version changes.

> How should 'make dist' work in this case?

Find attached a prototype with diffs to Automake 1.11, and to GNU hello 2.4.

On GNU hello side, I added a script that computes the version number in some
way. and told automake how to retrieve the version number. Also, I moved the
version number out of hello.c, so that only a tiny version.c needs to be
recompiled when the version changes. In Makefile.am I added a dependency
for version.o and special CPPFLAGS for version.c. (It is a pity that adding
special CPPFLAGS for a single file requires the creation of an intermediate
library.)

On the Automake side, you find a prototype of a macro AM_INIT_VERSION. It can
be used in three ways:

- with a lazily computed version number (this is for projects where the version
  changes several times a day):

    AM_INIT_VERSION([$$version], [version=`sh $(top_srcdir)/gen-version`])

- with a version number that is known at configure time (for projects where
  the version number changes once a week):

    . $srcdir/version.sh # sets myversion
    AM_INIT_VERSION([$myversion])

- with a version number that is known at autoconf time (like the status quo
  in automake):

    AM_INIT_VERSION([3.14])
  or
    AM_INIT_VERSION([esyscmd([./gen-version])])

"make dist" computes the version number once, then computes the 'distdir'
variable from it, and passes it to a sub-make invocation, from where it
and the 'top_distdir' variable will be propagated to subdirectories.

Bruno

diff -r -c3 --unidirectional-new-file hello-2.4.orig/gen-version hello-2.4/gen-version
*** hello-2.4.orig/gen-version	1970-01-01 01:00:00.000000000 +0100
--- hello-2.4/gen-version	2009-05-31 12:10:00.000000000 +0200
***************
*** 0 ****
--- 1,2 ----
+ #!/bin/sh
+ echo 2.4-20090531-2133
diff -r -c3 --unidirectional-new-file hello-2.4.orig/configure.ac hello-2.4/configure.ac
*** hello-2.4.orig/configure.ac	2008-12-09 19:49:08.000000000 +0100
--- hello-2.4/configure.ac	2009-05-31 12:05:21.000000000 +0200
***************
*** 8,17 ****
  dnl WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
  dnl implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  
! AC_INIT([GNU Hello], [2.4], [bug-he...@gnu.org])
  
  dnl Must come before AM_INIT_AUTOMAKE.
  AC_CONFIG_AUX_DIR([build-aux])
  AM_INIT_AUTOMAKE([readme-alpha])
  
  # Minimum Autoconf version required.
--- 8,19 ----
  dnl WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
  dnl implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  
! AC_INIT([GNU Hello], [-], [bug-he...@gnu.org])
  
  dnl Must come before AM_INIT_AUTOMAKE.
  AC_CONFIG_AUX_DIR([build-aux])
+ AM_INIT_VERSION([$$version], [version=`sh $(top_srcdir)/gen-version`])
+ 
  AM_INIT_AUTOMAKE([readme-alpha])
  
  # Minimum Autoconf version required.
***************
*** 24,29 ****
--- 26,32 ----
  dnl Checks for programs.
  # We need a C compiler.
  AC_PROG_CC
+ AM_PROG_CC_C_O
  
  # Since we use gnulib: gl_EARLY must be called as soon as possible after
  # the C compiler is checked.  The others could be later, but we just
diff -r -c3 --unidirectional-new-file hello-2.4.orig/src/hello.c hello-2.4/src/hello.c
*** hello-2.4.orig/src/hello.c	2008-12-03 19:48:12.000000000 +0100
--- hello-2.4/src/hello.c	2009-05-31 11:49:51.000000000 +0200
***************
*** 187,193 ****
  static void
  print_version (void)
  {
!   printf ("hello (GNU %s) %s\n", PACKAGE, VERSION);
    /* xgettext: no-wrap */
    puts ("");
    
--- 187,193 ----
  static void
  print_version (void)
  {
!   printf ("hello (GNU %s) %s\n", PACKAGE, version);
    /* xgettext: no-wrap */
    puts ("");
    
diff -r -c3 --unidirectional-new-file hello-2.4.orig/src/system.h hello-2.4/src/system.h
*** hello-2.4.orig/src/system.h	2008-11-27 20:48:24.000000000 +0100
--- hello-2.4/src/system.h	2009-05-31 11:50:07.000000000 +0200
***************
*** 37,40 ****
--- 37,42 ----
  /* Check for errors on write.  */
  #include "closeout.h"
  
+ extern char const version[];
+ 
  #endif /* HELLO_SYSTEM_H */
diff -r -c3 --unidirectional-new-file hello-2.4.orig/src/version.c hello-2.4/src/version.c
*** hello-2.4.orig/src/version.c	1970-01-01 01:00:00.000000000 +0100
--- hello-2.4/src/version.c	2009-05-31 11:49:58.000000000 +0200
***************
*** 0 ****
--- 1,4 ----
+ #include <config.h>
+ #include "system.h"
+ 
+ char const version[] = VERSION;
diff -r -c3 --unidirectional-new-file hello-2.4.orig/src/Makefile.am hello-2.4/src/Makefile.am
*** hello-2.4.orig/src/Makefile.am	2008-11-27 20:48:24.000000000 +0100
--- hello-2.4/src/Makefile.am	2009-05-31 12:10:24.000000000 +0200
***************
*** 20,28 ****
  bin_PROGRAMS = hello
  hello_SOURCES = hello.c system.h
  
! hello_LDADD = @LIBINTL@ ../gnulib/lib/libgnu.a
  
  localedir = $(datadir)/locale
  
  AM_CPPFLAGS = -I$(top_srcdir)/gnulib/lib -I$(top_builddir)/gnulib/lib
  DEFS = -DLOCALEDIR=\"$(localedir)\" @DEFS@
--- 20,33 ----
  bin_PROGRAMS = hello
  hello_SOURCES = hello.c system.h
  
! hello_LDADD = @LIBINTL@ ../gnulib/lib/libgnu.a libversion.a
  
  localedir = $(datadir)/locale
  
  AM_CPPFLAGS = -I$(top_srcdir)/gnulib/lib -I$(top_builddir)/gnulib/lib
  DEFS = -DLOCALEDIR=\"$(localedir)\" @DEFS@
+ 
+ noinst_LIBRARIES = libversion.a
+ libversion_a_SOURCES = version.c
+ libversion_a_CPPFLAGS = $(AM_CPPFLAGS) `...@set_version_escaped@echo -DVERSION=\"$(VERSION)\"`
+ libversion_a-version.$(OBJEXT) : $(top_srcdir)/gen-version
diff -r -c3 1.11/share/aclocal-1.11/init.m4 1.11-modified/share/aclocal-1.11/init.m4
*** 1.11/share/aclocal-1.11/init.m4	2009-05-19 00:35:06.000000000 +0200
--- 1.11-modified/share/aclocal-1.11/init.m4	2009-05-31 12:04:17.000000000 +0200
***************
*** 9,14 ****
--- 9,30 ----
  
  # serial 16
  
+ # AM_INIT_VERSION(VERSION, [SET-VERSION])
+ # VERSION and SET-VERSION are shell statements, for use in Makefile.
+ # I.e. $(var) and ${var} refer to Makefile variables, whereas $$var
+ # refers to a shell variable.
+ AC_DEFUN([AM_INIT_VERSION],
+ [
+   m4_if([$2], ,
+     [AC_SUBST([VERSION], [$1])
+      AC_SUBST([SET_VERSION], [])
+      AC_SUBST([SET_VERSION_ESCAPED], [])],
+     [AC_SUBST([VERSION], ['$1'])
+      AC_SUBST([SET_VERSION], ['$2;'])
+      AC_SUBST([SET_VERSION_ESCAPED], ['AS_ESCAPE([$2]);'])])
+   m4_define([AM_INIT_VERSION_invoked])
+ ])
+ 
  # 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.
  
***************
*** 53,71 ****
  # Define the identity of the package.
  dnl Distinguish between old-style and new-style calls.
  m4_ifval([$2],
! [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], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,,
!   [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
! 
  _AM_IF_OPTION([no-define],,
! [AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
!  AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl
  
  # Some tools Automake needs.
  AC_REQUIRE([AM_SANITY_CHECK])dnl
--- 69,95 ----
  # Define the identity of the package.
  dnl Distinguish between old-style and new-style calls.
  m4_ifval([$2],
! [
!  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_TARNAME], 1), 1,,
!    [m4_fatal([AC_INIT should be called with package argument])])dnl
   AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl
!  m4_ifdef([AM_INIT_VERSION_invoked], , [
!   AC_SUBST([VERSION], ['m4_ifdef([AC_PACKAGE_VERSION], [AC_PACKAGE_VERSION])'])
!   _AM_IF_OPTION([no-define],,
!     [AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl
!  ])
! ])
  _AM_IF_OPTION([no-define],,
! [
!  AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
! ])
  
  # Some tools Automake needs.
  AC_REQUIRE([AM_SANITY_CHECK])dnl
diff -r -c3 1.11/share/automake-1.11/am/distdir.am 1.11-modified/share/automake-1.11/am/distdir.am
*** 1.11/share/automake-1.11/am/distdir.am	2009-05-19 00:35:05.000000000 +0200
--- 1.11-modified/share/automake-1.11/am/distdir.am	2009-05-31 11:20:24.000000000 +0200
***************
*** 337,382 ****
  ?GZIP?DIST_ARCHIVES += $(distdir).tar.gz
  GZIP_ENV = --best
  .PHONY: dist-gzip
! dist-gzip: distdir
! 	tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
! 	$(am__remove_distdir)
  
  ?BZIP2?DIST_ARCHIVES += $(distdir).tar.bz2
  .PHONY: dist-bzip2
! dist-bzip2: distdir
! 	tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2
! 	$(am__remove_distdir)
  
  ?LZMA?DIST_ARCHIVES += $(distdir).tar.lzma
  .PHONY: dist-lzma
! dist-lzma: distdir
! 	tardir=$(distdir) && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma
! 	$(am__remove_distdir)
  
  ?XZ?DIST_ARCHIVES += $(distdir).tar.xz
  .PHONY: dist-xz
! dist-xz: distdir
! 	tardir=$(distdir) && $(am__tar) | xz -c >$(distdir).tar.xz
! 	$(am__remove_distdir)
  
  ?COMPRESS?DIST_ARCHIVES += $(distdir).tar.Z
  .PHONY: dist-tarZ
! dist-tarZ: distdir
! 	tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
! 	$(am__remove_distdir)
  
  ?SHAR?DIST_ARCHIVES += $(distdir).shar.gz
  .PHONY: dist-shar
! dist-shar: distdir
! 	shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
! 	$(am__remove_distdir)
  
  ?ZIP?DIST_ARCHIVES += $(distdir).zip
  .PHONY: dist-zip
! dist-zip: distdir
! 	-rm -f $(distdir).zip
! 	zip -rq $(distdir).zip $(distdir)
! 	$(am__remove_distdir)
  
  endif %?TOPDIR_P%
  
--- 337,395 ----
  ?GZIP?DIST_ARCHIVES += $(distdir).tar.gz
  GZIP_ENV = --best
  .PHONY: dist-gzip
! dist-gzip:
! 	$(SET_VERSION)distdir=$(PACKAGE)-$(VERSION); \
! 	$(MAKE) $(AM_MAKEFLAGS) distdir="$$distdir" distdir \
! 	&& { tardir="$$distdir" && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >"$$distdir.tar.gz"; } \
! 	&& $(am__remove_distdir)
  
  ?BZIP2?DIST_ARCHIVES += $(distdir).tar.bz2
  .PHONY: dist-bzip2
! dist-bzip2:
! 	$(SET_VERSION)distdir=$(PACKAGE)-$(VERSION); \
! 	$(MAKE) $(AM_MAKEFLAGS) distdir="$$distdir" distdir \
! 	&& { tardir="$$distdir" && $(am__tar) | bzip2 -9 -c >"$$distdir.tar.bz2"; } \
! 	&& $(am__remove_distdir)
  
  ?LZMA?DIST_ARCHIVES += $(distdir).tar.lzma
  .PHONY: dist-lzma
! dist-lzma:
! 	$(SET_VERSION)distdir=$(PACKAGE)-$(VERSION); \
! 	$(MAKE) $(AM_MAKEFLAGS) distdir="$$distdir" distdir \
! 	&& { tardir="$$distdir" && $(am__tar) | lzma -9 -c >"$$distdir.tar.lzma"; } \
! 	&& $(am__remove_distdir)
  
  ?XZ?DIST_ARCHIVES += $(distdir).tar.xz
  .PHONY: dist-xz
! dist-xz:
! 	$(SET_VERSION)distdir=$(PACKAGE)-$(VERSION); \
! 	$(MAKE) $(AM_MAKEFLAGS) distdir="$$distdir" distdir \
! 	&& { tardir="$$distdir" && $(am__tar) | xz -c >"$$distdir.tar.xz"; } \
! 	&& $(am__remove_distdir)
  
  ?COMPRESS?DIST_ARCHIVES += $(distdir).tar.Z
  .PHONY: dist-tarZ
! dist-tarZ:
! 	$(SET_VERSION)distdir=$(PACKAGE)-$(VERSION); \
! 	$(MAKE) $(AM_MAKEFLAGS) distdir="$$distdir" distdir \
! 	&& { tardir="$$distdir" && $(am__tar) | compress -c >"$$distdir.tar.Z"; } \
! 	&& $(am__remove_distdir)
  
  ?SHAR?DIST_ARCHIVES += $(distdir).shar.gz
  .PHONY: dist-shar
! dist-shar:
! 	$(SET_VERSION)distdir=$(PACKAGE)-$(VERSION); \
! 	$(MAKE) $(AM_MAKEFLAGS) distdir="$$distdir" distdir \
! 	&& { shar "$$distdir" | GZIP=$(GZIP_ENV) gzip -c >"$$distdir.shar.gz"; } \
! 	&& $(am__remove_distdir)
  
  ?ZIP?DIST_ARCHIVES += $(distdir).zip
  .PHONY: dist-zip
! dist-zip:
! 	$(SET_VERSION)distdir=$(PACKAGE)-$(VERSION); \
! 	$(MAKE) $(AM_MAKEFLAGS) distdir="$$distdir" distdir \
! 	&& { rm -f "$$distdir.zip"; zip -rq "$$distdir.zip" "$$distdir"; } \
! 	&& $(am__remove_distdir)
  
  endif %?TOPDIR_P%
  
***************
*** 396,411 ****
  AM_RECURSIVE_TARGETS += dist dist-all
  endif %?SUBDIRS%
  
! dist dist-all: distdir
! ?GZIP?	tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
! ?BZIP2?	tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2
! ?LZMA?	tardir=$(distdir) && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma
! ?XZ?	tardir=$(distdir) && $(am__tar) | xz -c >$(distdir).tar.xz
! ?COMPRESS?	tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
! ?SHAR?	shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
! ?ZIP?	-rm -f $(distdir).zip
! ?ZIP?	zip -rq $(distdir).zip $(distdir)
! 	$(am__remove_distdir)
  
  endif %?TOPDIR_P%
  
--- 409,425 ----
  AM_RECURSIVE_TARGETS += dist dist-all
  endif %?SUBDIRS%
  
! dist dist-all:
! 	$(SET_VERSION)distdir=$(PACKAGE)-$(VERSION); \
! 	$(MAKE) $(AM_MAKEFLAGS) distdir="$$distdir" distdir \
! ?GZIP?	&& { tardir="$$distdir" && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz; } \
! ?BZIP2?	&& { tardir="$$distdir" && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2; } \
! ?LZMA?	&& { tardir="$$distdir" && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma; } \
! ?XZ?	&& { tardir="$$distdir" && $(am__tar) | xz -c >$(distdir).tar.xz; } \
! ?COMPRESS?	&& { tardir="$$distdir" && $(am__tar) | compress -c >$(distdir).tar.Z; } \
! ?SHAR?	&& { shar "$$distdir" | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz; } \
! ?ZIP?	&& { rm -f $(distdir).zip; zip -rq $(distdir).zip $(distdir); } \
! 	&& $(am__remove_distdir)
  
  endif %?TOPDIR_P%
  

Reply via email to