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%