From 027b99c35cf0e09fd758666232fd114d67e4346b Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Sat, 29 Apr 2017 12:55:49 +0200 Subject: Complete version module documentation --- doc/manual.cli | 183 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 183 insertions(+) diff --git a/doc/manual.cli b/doc/manual.cli index f23c0f3..5e292bb 100644 --- a/doc/manual.cli +++ b/doc/manual.cli @@ -503,4 +503,187 @@ well as patches the manifest file in the distribution with the snapshot sn and id (that is, replacing \c{.z} in the version value with the actual snapshot information). The result is a package that is specific to this commit. +Besides extracting the version information and making it available as +individual components, the \c{version} module also provide rules for +automatically generating the \c{version} (or \c{Version}/\c{VERSION}) file +that is customarily found in the root of a project as well as the version +headers (or other similar version-based files). + +The \c{version} file rule matches a \c{doc} target that contains the +\c{version} substring in its name (comparison is case-insensitive) and that +depends on the project's \c{manifest} file. To utilize this rule you would +normally have something along these lines to your project's root \c{buildfile}: + +\ +./: ... doc{version} + +doc{version}: file{manifest} # Generated by the version module. +doc{version}: dist = true # Include into the distribution. +\ + +The \c{version} header rule pre-processes a template file (which means it can +be used to generate any kinds of files, not just C/C++ headers). It matches a +\c{file}-based target that has a corresponding \c{in} prerequisite and also +depends on the project's \c{manifest} file. As an example, let's assume we +want to auto-generate a header called \c{version.hxx} for our \c{libhello} +library. To acomplish this we add the \c{version.hxx.in} template as well as +something along these lines to our \c{buildfile}: + +\ +lib{hello}: ... hxx{version} + +hxx{version}: in{version} $src_root/file{manifest} +hxx{version}: dist = true +\ + +The header rule is a line-based pre-processor that substitutes fragments +enclosed between (and including) a pair of dollar signs (\c{$}) with \c{$$} +being the escape sequence. As an example, let's assume our \c{version.hxx.in} +contains the following lines: + +\ +#ifndef LIBHELLO_VERSION + +#define LIBHELLO_VERSION $libhello.version.project_number$ULL +#define LIBHELLO_VERSION_STR \"$libhello.version.project$\" + +#endif +\ + +If our \c{libhello} is at version \c{1.2.3}, then the generated +\c{version.hxx} will look like this: + +\ +#ifndef LIBHELLO_VERSION + +#define LIBHELLO_VERSION 10020030000ULL +#define LIBHELLO_VERSION_STR \"1.2.3\" + +#endif +\ + +The first component after the opening \c{$} should be either the name of the +project itself (like \c{libhello} above) or a name of one of its dependencies +as listed in the manifest. If it is the project itself, then the rest can +refer to one of the \c{version.*} variables that we discussed earlier (in +reality it can be any variable visible from the project's root scope). + +If the name refers to one of the dependecies (that is, projects listed with +\c{depends:} in the manifest), then the following special substitutions are +recognized: + +\ +$.version$ - textual version constraint +$.condition([,])$ - numeric satisfaction condition +$.check([,])$ - numeric satisfaction check +\ + +Here \i{VERSION} is the version number macro and the optional \i{SNAPSHOT} is +the snapshot number macro. The snapshot is only required if you plan to +include snapshot information in your dependency constraints. + +As an example, let's assume our \c{libhello} depends on \c{libprint} which +is reflected with the following line in our manifest: + +\ +depends: libprint >= 2.3.4 +\ + +We also assume that \c{libprint} provides its version information in the +\c{libprint/version.hxx} header and uses analogous-named macros. Here +is how we can add a version check to our \c{version.hxx.in}: + +\ +#ifndef LIBHELLO_VERSION + +#define LIBHELLO_VERSION $libhello.version.project_number$ULL +#define LIBHELLO_VERSION_STR \"$libhello.version.project$\" + +#include + +$libprint.check(LIBPRINT_VERSION)$ + +#endif +\ + +After the substitution our \c{version.hxx} header will look like this: + +\ +#ifndef LIBHELLO_VERSION + +#define LIBHELLO_VERSION 10020030000ULL +#define LIBHELLO_VERSION_STR \"1.2.3\" + +#include + +#ifdef LIBPRINT_VERSION +# if !(LIBPRINT_VERSION >= 20030040000ULL) +# error incompatible libprint version, libprint >= 2.3.4 is required +# endif +#endif + +#endif +\ + +The \c{version} and \c{condition} substitutions are the building blocks of the +\c{check} substitution. For example, here is how we can implement a check with +a customized error message: + +\ +#if !($libprint.condition(LIBPRINT_VERSION)$) +# error bad libprint, need libprint $libprint.version$ +#endif +\ + +The \c{version} module also treats one dependency in a special way: if you +specify the required version of the build system in your manifest, then the +module will automatically check it for you. For example, if we have the +following line in our manifest: + +\ +depends: * build2 >= 0.5.0 +\ + +And someone tries to build our project with \c{build2} \c{0.4.0}, then they +will see an error like this: + +\ +build/bootstrap.build:3:1: error: incompatible build2 version + info: running 0.4.0 + info: required 0.5.0 +\ + +What version constraints should be use when depending on other project. We +start with a simple case where we depend on a release. Let's say \c{libprint} +\c{2.3.0} added a feature that we need in our \c{libhello}. If \c{libprint} +follows the source/binary compatibility guidelines discussed above, then +any \c{2.X.Y} version should work provided \c{X >= 3}. And this how we can +specify it in the manifest: + +\ +depends: libprint [2.3.0 3.0.0-) +\ + +Let's say we are now working on \c{libhello} \c{2.0.0} and would like to start +using features from \c{libprint} \c{3.0.0}. However, currently, only +pre-releases of \c{3.0.0} are available. If you would like to add a dependency +on a pre-release (most likely from your own pre-release), then the +recommendation is to only allow a specific version, essentially \"expiring\" +the combination as soon as newer versions become available. For example: + +\ +version: 2.0.0-b.1 +depends: libprint == 3.0.0-b.2 +\ + +Finally, let's assume we are feeling adventerous and would like to test +development snapshots of \c{libprint} (most likey from our own snapshots). In +this case the recommendation is to only allow a snapshot range for a specific +pre-release with the understanding and a warning that no compatibility between +snapshot versions is guaranteed. For example: + +\ +version: 2.0.0-b.1.z +depends: libprint [3.0.0-b.2.1 3.0.0-b.3) +\ " -- cgit v1.1