aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2017-04-29 12:55:49 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2017-04-29 12:55:49 +0200
commit027b99c35cf0e09fd758666232fd114d67e4346b (patch)
treea08cd63b9dabbda7a67ddf62cba108d0dde5334b
parentf912a6c1090875b16792da4848c47759a38f1ef4 (diff)
Complete version module documentation
-rw-r--r--doc/manual.cli183
1 files changed, 183 insertions, 0 deletions
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:
+
+\
+$<name>.version$ - textual version constraint
+$<name>.condition(<VERSION>[,<SNAPSHOT>])$ - numeric satisfaction condition
+$<name>.check(<VERSION>[,<SNAPSHOT>])$ - 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/version.hxx>
+
+$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 <libprint/version.hxx>
+
+#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)
+\
"