@node Package version management @section Package version management @c Copyright (C) 2007--2026 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 . 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