Module Topkg.Pkg

module Pkg: sig .. end
Package description.

See the basics.



Installation description

The installation description generates an OPAM install file which is simply a description of file moves (in the mv sense) from the build or source directory to standard install directories. Describing these moves in a given build configuration effectively determines what needs to built by the package build command.

Note. Always use "/" as a directory seperator for paths, even on Windows.

type install 
The type for representing a set of install moves.
type field = ?force:bool ->
?built:bool ->
?cond:bool ->
?exts:Topkg.Exts.t -> ?dst:Topkg.fpath -> Topkg.fpath -> install
The type for an install field, a function that describe file moves to a particular installation directory. In the simplest form a call field src simply moves the file src at the root of the install directory of the field.

In general field ~force ~built ~cond ~exts ~dst src generates install move as follows:


type exec_field = ?auto:bool -> field 
The type for fields that install executable files. This is like Topkg.Pkg.field except for the additional auto parameter:
val bin : exec_field
bin is a field that installs to a common bin/ directory.
val doc : field
doc is a field that installs to a package specific doc/ directory
val etc : field
etc is a field that installs to a package specific etc/ directory.
val lib : field
lib is a field that installs to a package specific lib/ directory.
val libexec : exec_field
libexec is a field that installs to a package specific lib/ directory but with the executable bit set.
val man : field
man is a field that installs to a common man/ directory. See the OPAM manual for details.
val misc : field
misc is a field that installs to an arbitrary absolute path, the user is prompted for authorization, see the OPAM manual for details.
val sbin : exec_field
sbin is a field that installs to a common sbin/ directory.
val share : field
share is a field that installs to a package specific share/ directory.
val share_root : field
share_root is a field that installs to a common share/ directory.
val stublibs : field
stublibs is a field that install to a common lib/stublibs/ directory. Used for OCaml C stub directory.
val toplevel : field
toplevel is a field that installs to a common lib/toplevel/ directory.

Test executable description


val test : ?run:bool -> ?dir:Topkg.fpath -> ?args:Topkg.Cmd.t -> exec_field
test is a special executable field: it doesn't install the described executable (as such the dst argument is ignored at the moment). If run is true (default) executes the test with args when ocaml pkg/pkg.ml test is run; this will notably run to test the distribution tarball. If run is false the test needs to be invoked explicitely. dir specifies the current working directory for the test, expressed relative to the root directory of the package (defaults to .).

Higher-level installs


val mllib : ?field:field ->
?cond:bool ->
?api:string list -> ?dst_dir:Topkg.fpath -> Topkg.fpath -> install
mllib ~field ~cond ~api ~dst_dir mllib installs an OCaml library described by the OCamlbuild .mllib file mllib with:
val clib : ?dllfield:field ->
?libfield:field ->
?cond:bool -> ?lib_dst_dir:Topkg.fpath -> Topkg.fpath -> install
clib clib installs C stubs described by the OCamlbuild .clib file clib with:

Build description


type build 
The type for package build description.
val build : ?prepare_on_pin:bool ->
?dir:Topkg.fpath ->
?pre:(Topkg.Conf.t -> unit Topkg.result) ->
?cmd:(Topkg.Conf.t -> Topkg.Conf.os -> Topkg.fpath list -> unit Topkg.result) ->
?post:(Topkg.Conf.t -> unit Topkg.result) ->
?clean:(Topkg.Conf.os -> build_dir:Topkg.fpath -> unit Topkg.result) ->
unit -> build
build ~prepare_on_pin ~dir ~cmd ~pre ~post describes the package build procedure. Warning. If you are invoking tools in your hooks consider using Topkg.Conf.tool to look them up it helps for cross-compilation.
val build_cmd : Topkg.Conf.t -> Topkg.Conf.os -> Topkg.Cmd.t
build_cmd c os is the default build command to which files to build are given. Its value is defined by:
fun c os ->
  let ocamlbuild = Conf.tool "ocamlbuild" os in
  let build_dir = Conf.build_dir c in
  let debug = Cmd.(on (Conf.debug c) (v "-tag" % "debug")) in
  let profile = Cmd.(on (Conf.profile c) (v "-tag" % "profile")) in
  Cmd.(ocamlbuild % "-use-ocamlfind" % "-classic-display" %% debug %%
                    profile % "-build-dir" % build_dir)

val clean_cmd : Topkg.Conf.os -> build_dir:Topkg.fpath -> Topkg.Cmd.t
clean_cmd os ~build_dir is the default clean command. Its value is defined by:
fun os ~build_dir ->
  let ocamlbuild = Conf.tool "ocamlbuild" os in
  Cmd.(ocamlbuild % "-use-ocamlfind" % "-classic-display" %
                    "-build-dir" % build_dir % "-clean"


Distribution description


type watermark = string *
[ `Name
| `Opam of Topkg.fpath option * string * string
| `String of string
| `Vcs of [ `Commit_id ]
| `Version
| `Version_num ]
The type for watermarks. A watermark identifier, e.g. "ID" and its definition:

When a file is watermarked with an identifier "ID", any occurence of the sequence %%ID%% in its content is substituted by its definition.

type distrib 
The type for describing distribution creation.
val distrib : ?watermarks:watermark list ->
?files_to_watermark:(unit -> Topkg.fpath list Topkg.result) ->
?massage:(unit -> unit Topkg.result) ->
?exclude_paths:(unit -> Topkg.fpath list Topkg.result) ->
?uri:string -> unit -> distrib
distrib ~watermarks ~files_to_watermark ~massage ~exclude_paths ~uri () influences the distribution creation process performed by the topkg tool. See the full details about distribution creation.

In the following the distribution build directory is a private clone of the package's source repository's HEAD when topkg distrib is invoked.


val watermarks : watermark list
watermarks is the default list of watermarks. It has the following elements: Prepending to the list overrides default definitions.
val files_to_watermark : unit -> Topkg.fpath list Topkg.result
files_to_watermark () is the default list of files to watermark. It is invoked in the distribution build directory and gets the set of tracked files of this directory from which it removes the files that end with .flv, .gif, .ico, .jpeg, .jpg, .mov, .mp3, .mp4, .otf, .pdf, .png, .ttf, .woff.
val massage : unit -> unit Topkg.result
massage is the default distribution massaging function. It is invoked in the distribution build directory and does nothing.
val exclude_paths : unit -> Topkg.fpath list Topkg.result
exclude_paths () is the default list of paths to exclude from the distribution archive. It is invoked in the distribution build directory and returns the following static set of files.
fun () -> Ok [".git"".gitignore"".gitattributes"".hg"".hgignore";
              "build""Makefile""_build"]


Distribution publication description


type publish 
The type for describing distribution publication.
val publish : ?artefacts:[ `Alt of string | `Distrib | `Doc ] list ->
unit -> publish
publish ~artefacts () influences the distribution publication process performed by the topkg tool:

Package description


type std_file 
The type for specifying a standard file.
val std_file : ?install:bool -> Topkg.fpath -> std_file
std_file ~install p is a standard file p expressed relative to the distribution root directory. The file is automatically installed if install is true (default).
type meta_file 
The type for specifying an OCamlfind META file.
val meta_file : ?lint:bool -> ?install:bool -> Topkg.fpath -> meta_file
meta_file ~lint ~install p is a META file p expressed relative to the distribution root directory. The file is automatically installed in the Topkg.Pkg.lib field if install is true (default). If lint is true (default), it is OCamlfind linted.
type opam_file 
The type for specifying an opam file.
val opam_file : ?lint:bool ->
?lint_deps_excluding:string list option ->
?install:bool -> Topkg.fpath -> opam_file
opam_file ~lint ~lint_deps_excluding ~install p is an OPAM file p expressd relative to the distribution root directory such that:
val describe : ?delegate:Topkg.Cmd.t ->
?readmes:std_file list ->
?licenses:std_file list ->
?change_logs:std_file list ->
?metas:meta_file list ->
?opams:opam_file list ->
?lint_files:Topkg.fpath list option ->
?lint_custom:(unit -> Topkg.R.msg Topkg.result list) ->
?distrib:distrib ->
?publish:publish ->
?build:build ->
string -> (Topkg.Conf.t -> install list Topkg.result) -> unit
describe name install describes a package named name with:

Package distribution creation details

The following describes the exact steps performed by topkg distrib to create the distribution archive. Note that topkg allows to override or disable part of the process via command line arguments, e.g. to specify the version string manually or skip linting. See topkg distrib --help for more information.

The distribution process assumes that the source repository working directory is clean so that its definitions are consistent with those of the distribution build directory. A warning is generated if this is not the case as it may end up in inconsistent distribution archives (but which may be fine to only publish a documentation update).

Let $NAME be the name of the package, $BUILD be its build directory, $VERSION be the VCS tag description (e.g. git-describe(1) if you are using git) of the source repository HEAD commit and distrib the distribution description found in the source's repository pkg/pkg.ml file.

  1. Clone the source repository at HEAD as the distribution build directory $BUILD/$NAME-$VERSION.build.
  2. Prepare the distribution:
    1. Invoke the files_to_watermark function of distrib in the distribution build directory to determine the files to watermark with watermarks and perform the watermarking process.
    2. Adds a version field with value $VERSION to the OPAM files mentioned by Topkg.Pkg.describe.
    3. Run the massage function of distrib in the distribution build directory. This can be used to create distribution time build artefacts.
  3. Invoke the exclude_paths function of distrib in the distribution build directory to determine the paths to exclude from the archive.
  4. Create a distribution tarball $BUILD/$NAME-$VERSION.tbz with the file hierarchy in $BUILD/$NAME-$VERSION.build, excluding the paths determined at the preceeding point and delete the clone $BUILD/$NAME-$VERSION.build. File modifications times in the archive are set to HEAD's commit time and file permissions are preserved. Any other form of file metadata is discarded in the archive.
  5. Test the distribution. Unpack it in directory $BUILD/$NAME-$VERSION, lint the distribution, build the package in the current build environment with its tests, run the tests, on success delete $BUILD/$NAME-$VERSION. Note that this uses the archive's pkg/pkg.ml file, which should not be different from the source's repository file if the latter was clean when topkg distrib was invoked.

Note on watermarking

It is right to doubt the beauty and be concerned about the watermarking process. However experience shows that alternatives like having an OCaml module generated with the appropriate information doesn't work well in practice. Version numbers do not only show up in OCaml source code. They also appear in documentation comments, metadata files, textual data files and non-OCaml source files.

Watermarking by default all the non binary files of the distribution allows one to write %‌%VERSION%% in any context and be sure it is be substituted with the right version number in pin and distribution build contexts (this occurence was not subsituted because a ZERO WIDTH NON-JOINER U+200C was introduced between the first two percent characters).

If this scheme poses a problem for certain files or you remain unconvinced, simply filter the result of Topkg.Pkg.files_to_watermark or replace it by the exact files you would like to watermark.