automake
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: RFE: allow for computed version number


From: Ralf Wildenhues
Subject: Re: RFE: allow for computed version number
Date: Wed, 3 Jun 2009 00:10:54 +0200
User-agent: Mutt/1.5.18 (2008-05-17)

Hello Bruno,

* Bruno Haible wrote on Sun, May 31, 2009 at 12:50:13PM CEST:
> 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.

For the version strings generated by git, this holds as well.  Which
VCSes do not follow this form of version string append?

> > > 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.

Well, but we're doing exactly that.  It may not happen at the pace users
would like, but that's an issue of manpower not of intent.  Also, all
development is done in public on mailing lists, and the git version of
Automake is intended to be usable at all times as well as installable in
parallel with other released versions (though any development snapshot
between release X and X+1 will have the same name).

AC_INIT doesn't really match the early feedback issue, because the
AC_INIT(PACKAGE, VERSION) API is not new at all.  These changes come
from 2001 and before, and the Automake requirements in this area are
also several years old.

For examples of new and experimental interfaces: there is Autotest, or
the parallel-tests framework in Automake 1.11.  And that one did have a
test release and at least some feedback on that (thanks to all that
tested it!).

No, what I really mean is that we introduce new APIs, and half a decade
later users still haven't moved over to it fully, and in practice it
means we have to support both the new and the old API forever; and then
we learn that the old APIs are better suited for some common task.
The proliferation of different APIs for the same tasks is not good.

> 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.)

Well, if after two years we haven't found a make implementation that
does not grok $(var1$(var2)) as used with silent-rules, we can not only
go ahead and let silent-rules be the default, but also we can start
using this idiom for other, less trivial issues such as per-object
overrides.  However, it would also require the user to acknowledge that
per-object overrides won't create two different objects, which again
makes the user interface so much more difficult conceptually, as that's
yet another leaky abstraction (cf. `info Automake true').

> - 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`])

These kind of quoting hacks are incredibly ugly and error-prone; they
are difficult to understand even by me, I don't see how this can be
communicated to less experienced users in any sane way.  Hidden in the
implementation is the side condition of disallowed single quotes, how
would someone changing this line later ever be able to infer that?
(Some projects use $(...) style command substitutions throughout, for
them the above will be very confusing.)

Leaky abstractions contribute very visibly to maintenance overhead,
as they require endless re-explaining to new users, on this mailing list
and elsewhere.

> "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.

This, too, is quite error-prone, as non-GNU make don't propagate
overridden variables to sub makes.

> + noinst_LIBRARIES = libversion.a
> + libversion_a_SOURCES = version.c

FWIW, this line is not needed with recent Automake; but it is useful
for backward compatibility to older versions.

> + libversion_a_CPPFLAGS = $(AM_CPPFLAGS) address@hidden@echo 
> -DVERSION=\"$(VERSION)\"`

Ugh.  This would at least require hiding in some macro or so.  The user
should have a way to use the version setting API in her own macros and
rules, without having to go through hoops, and certainly without having
to use @foo@ substitutions.  It is a policy (and has also been for a
long time) to prefer $(foo) over @foo@ in Makefile.am files, as it
allows make time overrides, and exposes more of the content to automake.

> + libversion_a-version.$(OBJEXT) : $(top_srcdir)/gen-version

Ugh.  Likewise, this should be hidden somehow, or computed by automake
from the AM_INIT_VERSION arguments.  Having to specify `gen-version'
here and (far away) in configure.ac is error-prone.

> + # 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]);'])])

Putting the shell quoting in the macro time and again proves to be very
unflexible and error-prone.  This should not be done, IMVHO.

> +   m4_define([AM_INIT_VERSION_invoked])

Why not use AC_PROVIDE_IFELSE or put the name in internal _AM_* name
space otherwise?

This macro should contain an AC_BEFORE statement to warn about usage
after AM_INIT_AUTOMAKE.

>   # 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])

Please separate whitespace only changes from functional ones, thanks.
Please post unidiffs rather than context diffs, as documented in
http://sourceware.org/automake/contribute.html, thanks.

A full patch for Automake needs some more items listed on that web page
or in HACKING, among them a few new tests to check that the new API
works as desired, a ChangeLog entry, NEWS and manual updates; the latter
are especially important as they will be the prime decision factor for
me as to whether accepting the change will cost lots of future
maintenance work through user questions on mailing lists or not.

> ! ],
> ! [
> !  _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])
> ! ])
>   

Cheers, and thanks!
Ralf




reply via email to

[Prev in Thread] Current Thread [Next in Thread]