# Module Topkg.Conf

    module Conf: sig .. end

Build configuration.

## Key value converters

    type 'a conv

The type for key value converters.

    val conv : ?docv:string ->
           (string -> 'a Topkg.result) ->
           (Stdlib.Format.formatter -> 'a -> unit) -> 'a conv

`conv ~docv parse print` is a configuration value converter parsing values with `parse` and printing them with `print`. `docv` is a documentation meta-variable used in the documentation to stand for the configuration value, defaults to `"VALUE"`.

    val bool : bool conv

`bool` is a converter for booleans.

    val int : int conv

`int` is a converter for integers.

    val string : string conv

`string` is a converter for strings.

    val fpath : Topkg.fpath conv

`fpath` is a converter for file paths.

    val some : ?none:string -> 'a conv -> 'a option conv

`some conv` is like `conv` but wraps the parsed value in `Some`. `none` is the string printed for `None` by the converter printer, defaults to `""`.

## Keys

Warning. Configuration keys must be created before the call to `Topkg.Pkg.describe`. Yes you are right, that's a little bit dirty.

    type 'a key

The type for configuration keys whose lookup value is of type `'a`.

A configuration key has a name and represents a value of type `'a` in a build configuration. If `"name"` is the name of the key then its value can be specified on the command line using `--name v` where `v` is the value of the key and is parsed according to the key's value converter.

There are a few predefined key, see the configuration section.

    val key : ?docv:string ->
           ?doc:string ->
           ?env:string -> string -> 'a conv -> absent:'a -> 'a key

`key name conv ~absent ~env ~doc ~docv` is a configuration key with name `name` parsed from the command line with `conv`. `absent` is used if the value is not specified on the command line. If `env` is specified and exists in the process environment, the value of the variable is parsed with `conv` and used instead of `absent` when needed.

`doc` is a documentation string for the key. `docv` is a documentation meta-variable to stand for the key value, defaulting to the `docv` of `conv`. In `doc`, occurences of the substring `"$(docv)"` are replaced by the value of `docv`.

    val discovered_key : ?docv:string ->
           ?doc:string ->
           ?env:string ->
           string ->
           'a conv -> absent:(unit -> 'a Topkg.result) -> 'a key

`discovered_key` is like `Topkg.Conf.key` but the absent value is discovered, if needed, with `absent`.

    val with_pkg : ?default:bool -> string -> bool key

`with_pkg ~default pkg` is a boolean configuration key named `(strf "with-%s" pkg)` to assert existence of opam packages. If absent defaults to `default`.

Usually specified in opam build instructions with:

    "--with-thatpkg" thatpkg:installed

along with an entry in the depopt field of the opam file.

Warning. Only use this combinator for denoting opam package existence, the resulting key may switch to a discovery process in the future.

## Configurations

    type t

The type for configurations.

    val value : t -> 'a key -> 'a

`value c k` is the value of configuration key `k` in `c`.

- Raises `Invalid_argument` If `k` was (illegaly) created after the call to `Topkg.Pkg.describe` or if dirty tricks are being played.

    val pkg_name : t -> string

`pkg_name c` is either the value of the package name as given to `Topkg.Pkg.describe` or the value of a predefined key `--pkg-name` which overrides the package name. This defines the name of the generated opam install file. Used to handle multiple opam packages.

    val build_dir : t -> Topkg.fpath

`build_dir c` is either the value of build directory as given to `Topkg.Pkg.describe` via `Topkg.Pkg.build` or the value of a predefined key `--build-dir` which overrides the package definition.

    val vcs : t -> bool

`vcs c` is the value of a predefined key `--vcs`. It is `true` if the package directory is VCS managed. Usually should not be specified manually: if absent it is determined automatically by using `Topkg.Vcs.find` and used to determine the `Topkg.Conf.build_context`.

    val dev_pkg : t -> bool

`dev_pkg c` is the value of a predefined key `--dev-pkg`. It is `true` if the build is initiated by an installer like opam and the package sources are a checkout from a VCS rather than a distribution archive. Usually specified in opam build instruction with either:

    "--dev-pkg" "%{dev}%"    # for opam >= 2.0
    "--dev-pkg" "%{pinned}%" #           < 2.0

    val pinned : t -> bool

Deprecated.use `Topkg.Conf.dev_pkg` `pinned c` is the value of a predefined key `--pinned`. It has exactly the same semantics as `Topkg.Conf.dev_pkg` but is misnamed.

    val jobs : t -> int

`jobs c` is the value of a predefined key `--jobs`. If absent it is determined from the build context as follows.

- ``Dev` builds default to number of CPU cores, or 4 if it cannot be determined.
- all other contexts default to 4

    type build_context = [ `Dev | `Distrib | `Pin ]

The type for build contexts. See `Topkg.Conf.build_context` for semantics.

    val build_context : t -> [ `Dev | `Distrib | `Pin ]

`build_context c` is the build context of `c`. This is derived from `Topkg.Conf.vcs` and `Topkg.Conf.dev_pkg` (or the deprecated `Topkg.Conf.pinned`) as follows.

- ``Distrib` iff `not (vcs c)`. No VCS is present, this is a build from a distribution. If there are configuration bits they should be setup according to the build configuration.
- ``Dev` iff `vcs c && not (dev_pkg c || pinned c)`. This is a development build invoked manually in a source repository. The repository checkout should likely not be touched and configuration bits not be setup. This is happening for example if the developer is testing the package description in her working source repository by invoking `pkg/pkg.ml` or `topkg build`.
- ``Pin` iff `vcs c && (dev_pkg c || pinned c)`. This is a package manager development build. In this case the repository checkout may need to be massaged into a pseudo-distribution for the package to be installed. This means that distribution watermarking and massaging should be performed, see `Topkg.Pkg.distrib` and the `prepare_on_pin` argument of `Topkg.Pkg.build`. Besides exisiting configuration bits should be setup according to the build environment. Note. This is called ``Pin` due to a blind spot, a more approriate name would be something like ``Dev_pkg` build.

    val build_tests : t -> bool

`build_tests c` is the value of a predefined key `--tests` that indicates if the tests should be built. If absent the value depends on the `Topkg.Conf.build_context`, it is `true` in the ``Dev` context and `false` in the other contexts.

    val debug : t -> bool

`debug c` is the value of a predefined key `--debug` that indicates if the build should include debugging information in the build artefacts. If absent the value is `true` or the value of the environment variable TOPKG_CONF_DEBUG if specified.

    val debugger_support : t -> bool

`debugger_support c` is the value of a predefined key `--debugger-support` that indicates if build artefacts needed for source level debuggers should be built and installed. If absent the value is `false` or the value of the environment variable TOPKG_CONF_DEBUGGER_SUPPORT if specified.

    val profile : t -> bool

`profile c` is the value of a predefined key `--profile` that indicates if the build artefacts include run-time profiling support. If absent the value is `false` or the value of the environment variable TOPKG_CONF_PROFILE if specified.

    val toolchain : t -> string option

`toolchain c` is the value of a predefined key `--toolchain` that specifies the ocamlbuild toolchain. If absent the value is `None` or the value of the environment variable TOPKG_CONF_TOOLCHAIN if specified.

    val dump : Stdlib.Format.formatter -> t -> unit

`dump ppf c` formats an unspecified representation of `c` on `ppf`.

## Tool lookup

If your package description needs to run tools (e.g. in the pre and post build hooks, see `Topkg.Pkg.build`) it should get the tool to invoke with the following function. This allows to control the executable being run which is useful for cross-compilation scenarios.

    type os = [ `Build_os | `Host_os ]

The type for operating systems.

- ``Build_os` is the build OS, the OS on which the package is built.
- ``Host_os` is the host OS, the OS on which the package is hosted and runs.

    val tool : ?conf:t -> string -> os -> Topkg.Cmd.t

`tool ~conf cmd os` is a command `cmd` which can be run on the build OS which produces output suitable for the OS `os`, taking into account configuration `conf`.

The actual command returned depends on the following lookup procedure, here exemplified on the invocation `tool "mytool" `Host_os` (resp. ``Build_os`).

1. `Cmd.v "cmd"`, if the environment variable HOST_OS_MYTOOL (resp. BUILD_OS_MYTOOL) is set to `"cmd"`
2. `Cmd.v (Fpath.append path "mytool")`, if the environment variable HOST_OS_XBIN (resp. BUILD_OS_BIN) is set to `path`.
3. `Cmd.v ("mytool" ^ "suff")`, if the environment variable HOST_OS_SUFF (resp. BUILD_OS_SUFF).
4. `Cmd.(v "ocamlfind" % "-toolchain" % "toolchain" % "mytool")` if `"mytool"` is part of the OCaml tools that can be invoked through ocamlfind, `toolchain conf` is not `None`, and `os` is ``Host_os`.
5. `Cmd.(v "ocamlfind" % "mytool")` if `"mytool"` is part of the OCaml tools that can be invoked through ocamlfind.
6. `Cmd.v "mytool"` otherwise.

## OCaml configuration

    module OCaml: sig .. end

OCaml configuration.