Branch
Hash :
a150644b
Author :
Date :
2025-03-01T15:59:29
package-version: Improve wording in './configure --help'. Reported by Benno Schulenberg <bensberg@telfort.nl> in <https://lists.gnu.org/archive/html/bug-gettext/2025-03/msg00000.html>. * doc/package-version.texi: Recommend a dummy version number named 'package', not 'dummy'. * m4/init-package-version.m4: Update comments accordingly. * build-aux/git-version-gen: Likewise.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236
@node Package version management
@section Package version management
@c Copyright (C) 2007--2025 Free Software Foundation, Inc.
@c Permission is granted to copy, distribute and/or modify this document
@c under the terms of the GNU Free Documentation License, Version 1.3 or
@c any later version published by the Free Software Foundation; with no
@c Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A
@c copy of the license is at <https://www.gnu.org/licenses/fdl-1.3.en.html>.
The goals of a package maintainer,
when dealing with the version number of a package, are:
@itemize
@item
Programs should identify themselves with that version number
when invoked as @command{@var{program} --version}.
@item
Every package tarball should contain the version number, in up to four ways:
@itemize
@item
The tarball name should be @code{@var{package}-@var{version}.tar.gz}.
@item
The tarball should unpack into a directory
named @code{@var{package}-@var{version}}.
@item
Programs built from that tarball should identify themselves
when invoked as @command{@var{program} --version}.
@item
Documentation (especially in PDF format) and man pages
may contain the version number, as an important bit of meta information.
@end itemize
@item
The package maintainer should be able to
easily set the version number before making a release,
and doing so should be quick.
@item
When a contributor is
building from the git repository (as opposed to a tarball),
the version number should, by default, reflect the git commit,
in order to avoid confusion w.r.t. official releases.
@end itemize
Here's how the GNU Build System and Gnulib achieve these goals.
@menu
* Setting the package version::
* Propagating the package version::
* Using the package version::
@end menu
@node Setting the package version
@subsection Setting the package version
@cindex @code{.tarball-version}
When the maintainer has decided about the version number
for the next build (and likely also the next tarball),
they implement that decision by storing this version number
in a file named @file{.tarball-version} at the top level of the package.
This is a simple one-line text file.
The maintainer can, alternatively, decide to
let the git version be the version number.
To implement this choice,
they remove the file @file{.tarball-version} at the top level of the package.
@mindex git-version-gen
The actual version number comes from an invocation of
the program @code{git-version-gen},
part of the Gnulib module @code{git-version-gen}.
It looks at the file @file{.tarball-version}, if that exists,
and at the current checkout, otherwise.
The file @file{.tarball-version} should not be put under version control.
Therefore you may want to list it
in the package's top-level @code{.gitignore} file.
But you need a @code{Makefile.am} rule that will
make sure that @file{.tarball-version} will exist in distribution tarballs:
@example
dist-hook: dist-tarball-version
.PHONY: dist-tarball-version
dist-tarball-version:
echo '$(VERSION)' > $(distdir)/.tarball-version
@end example
Typically, the maintainer will set the version number in a clean directory
(i.e. after ``make distclean'').
@mindex gnumakefile
In order to adapt to alternative workflows,
the file @file{GNUmakefile}, part of the Gnulib module @code{gnumakefile},
contains a rule that will print a warning or possibly call @code{autoreconf}
if it finds that the version has changed but has not yet been propagated.
Reminder: Not every package supports @code{autoreconf}.
@node Propagating the package version
@subsection Propagating the package version
At the end of a @file{configure} run,
@code{config.status} is run,
that creates various files with embedded pieces of information.
It thus propagates the values of various variables
to various files in the build tree
(most notably, @code{Makefile}s and @code{config.h}).
One such propagated value is
the value of the Automake-defined variable @code{$(VERSION)}.
(There is also the Autoconf-defined variable @code{$(PACKAGE_VERSION)},
but nothing except Automake ought to use it.)
For @code{$(VERSION)} to have a sensible value,
a few lines are needed in @code{configure.ac}.
The recommended code pattern is
@example
AC_INIT([@var{package}], [package])
AC_CONFIG_SRCDIR([@var{unique-file-in-source-dir}])
AC_CONFIG_AUX_DIR([build-aux])
VERSION_NUMBER=`cd $srcdir \
&& build-aux/git-version-gen .tarball-version`
gl_INIT_PACKAGE_VERSION([$VERSION_NUMBER])
AM_INIT_AUTOMAKE([@var{options}])
@end example
@noindent
With this code pattern,
the contents of the file @file{.tarball-version} and the git status
are considered when @code{configure} is run.
Two older code patterns are deprecated, because they read
the contents of the file @file{.tarball-version} and the git status
when @code{autoconf} is run, not when @code{configure} is run.
These older code patterns thus require a longer turnaround cycle
when the maintainer has changed the version number.
The first such old code pattern
is to set the version number directly in @code{configure.ac}:
@example
AC_INIT([@var{package}, @var{version}])
AC_CONFIG_SRCDIR([@var{unique-file-in-source-dir}])
AC_CONFIG_AUX_DIR([build-aux])
AM_INIT_AUTOMAKE([@var{options}])
@end example
The second such old code pattern
is to invoke @code{git-version-gen} at @code{autoconf} time:
@example
AC_INIT([@var{package}],
m4_esyscmd([build-aux/git-version-gen .tarball-version])])
AC_CONFIG_SRCDIR([@var{unique-file-in-source-dir}])
AC_CONFIG_AUX_DIR([build-aux])
AM_INIT_AUTOMAKE([@var{options}])
@end example
@mindex package-version
The macro @code{gl_INIT_PACKAGE_VERSION}
is defined in the Gnulib module @code{package-version}.
@node Using the package version
@subsection Using the package version during the build
@subsubheading The unoptimized way
Once propagated through @code{config.status},
the value of @code{$(VERSION)} can appear anywhere in built files.
For built files that are
distributed (that is, not erased by ``make distclean''),
it is important to add a dependency in the @code{Makefile.am},
so that the file gets rebuilt:
@example
@var{built-file}: $(top_builddir)/config.status
@end example
For files that are erased by ``make distclean'', this is not really necessary,
because
@itemize
@item
In the main workflow, where the developer
changes the version only between ``make distclean'' and ``./configure'',
the built files have been remade.
@item
Most @code{.o} files depend on @code{config.h},
which is rebuilt when @code{configure} runs.
@end itemize
Thus, only in packages that don't use Gnulib would a dependency such as
@example
hello-hello.$(OBJEXT): $(top_builddir)/config.status
@end example
@noindent
be needed.
@subsubheading The optimized way
Notice that
@code{config.status} usually changes much more often than the version number.
Therefore, for built files which depend
@emph{only} on @code{$(VERSION)} and not on other variables,
the following optimized technique can be used.
The technique consists of keeping a file named @code{$(top_srcdir)/.version},
which is a timestamp file.
Its modification time represents the last time
the value of @code{$(VERSION)} was changed.
Its contents is an undocumented implementation detail.
With such a file, the dependency in @code{Makefile.am} becomes:
@example
@var{built-file}: $(top_srcdir)/.version
@end example
In order to prepare for using @code{$(top_srcdir)/.version},
three modifications in the package are needed:
@itemize
@item
In the top-level @code{configure.ac} file,
add an invocation of the macro @code{gl_CONFIG_VERSION_STAMP},
near the end (before @code{AC_OUTPUT}).
This macro is defined in file @file{m4/version-stamp.m4},
part of the Gnulib module @code{version-stamp}.
@item
In the top-level @code{Makefile.am}, add:
@example
EXTRA_DIST += $(top_srcdir)/.version
BUILT_SOURCES += $(top_srcdir)/.version
@end example
@noindent
so that the file @code{.version} will be present in tarballs
and so that ``make maintainer-clean'' will erase it.
@item
Add @code{.version} to the package's top-level @code{.gitignore} file.
@end itemize