The Assemblage Library.
Assemblage
provides a simple embedded domain specific language
to describe OCaml
projects. It also provides simple
tools to configure, manage, install and use OCaml projects.
Describing a project eventually leads to describe its build
artifacts. The exact mapping betweem project elements and those
build artifacts depends on the presence or absence of
features. Examples of such features are weather to
compile and run the tests (user-defined feature), the presence of
the native compiler (system-dependant feature), compiling a
library using async
or lwt
as a backend (environment-dependant
feature), ...
Finally, generating build artifacts means refining the project
description into concrete command line arguments to pass
to the different compilers (ocamlc
, ocamlopt
) on the different
compilation and linking phases.
Release %%VERSION%% - %%AUTHOR%%
#
module Features : sig
Features.
Features declare booleans to be determined by the
build environment. They allow to condition the
application of certain flags and restrict the build of
project components or of certain of their artifacts.
Examples of features are: native compilation availability,
optional package availability, debug build support, etc.
#
type t
The type for features. Given a build environment a value of this type
denotes a boolean value.
#
val create : ?default:bool
-> string
-> doc:string
-> t
create default name doc
is a feature named name
. default
(defaults to true
) indicates the boolean value the feature
takes if the build environment doesn't determine it. doc
is
used for documenting the feature in various contexts, keep it
short and to the point.
#
val neg : ?on:bool
-> t -> t
neg f
is true iff
f
is false. If on
is specified, negates
if on
is true
and true_
is returned if on
is false
.
not_ f
is true iff f
is false.
#
val (&&&) :
t -> t -> t
f &&& f'
is true iff both f
and f'
are true.
#
val (|||) :
t -> t -> t
f ||| f'
is true iff either f
or f'
is true.
#
val byte :
t
byte
is true iff byte code compilation is available.
#
val native :
t
native
is true iff native code compilation is available.
#
val native_dynlink :
t
native_dynlink
is true iff native code dynamic linking is available.
#
val js :
t
js
is true iff JavaScript compilation is available.
#
val annot :
t
annot
is true iff binary annotations files must be built.
#
val debug :
t
debug
is true iff builds must support debugging.
#
val warn_error :
t
warn_error
is true iff builds must consider warnings as errors.
#
val test :
t
test
is true iff tests must be built.
#
val doc :
t
public_doc
is true iff the documentation must be built.
end
#
module Flags : sig
Flags
Flags values denote sets of partial command line arguments given
to tools in a given context. A context is defined by a compilation
[root:phase].
FIXME describe valid context and to what they correspond.
#
type phase = [
| `Prepare
| `Dep
| `Pp
of [
| `Byte
| `Native
]
| `Compile
of [
| `Intf
| `Byte
| `Native
| `C
| `Js
]
| `Archive
of [
| `Byte
| `Native
| `Shared
| `C
]
| `Link
of [
| `Byte
| `Native
| `Js
]
| `Run
of [
| `Byte
| `Native
]
| `Test
| `Doc
| `Other of string
]
The type for compilation phases.
#
type args = string list
The type for partial command line arguments.
#
type t
The type for multi-context, partial, command line arguments.
#
val v : ?available:
Features.
t -> phase -> args -> t
v available phase mode args
is the partial command line
args
in the context defined by phase
and modes
. This partial
command line is only available whenever the feature available
is true (defaults to Features.true_).
#
val (@@@) :
t -> t -> t
f @@@ f'
concatenates context wise f'
to f
. f'
and
f'
remain available according to their own available
argument.
#
val empty :
t
empty
is the command line []
for every context.
#
val debug :
t
debug
is the debug flag as needed per context, only
available when Features.debug is true.
#
val annot :
t
annot
is the -bin-annot
flag in appropriate contexts, only
available when Features.annot is true.
#
val warn_error :
t
warn_error
is the -warn-error
in appropriate contexts, only
available when Features.warn_error is true.
#
val linkall :
t
linkall
is the -linkall
flag in appropriate contexts.
#
val thread :
t
thread
is the -thread
flag in appropriate contexts.
#
val vmthread :
t
vmthread
is the -vmthread
flag in appropriate contexts.
#
val cclib : string list
-> t
#
val ccopt : string list
-> t
#
val stub : string
-> t
stub s
adds -cclib -ls
-dllib -ls
to the bytecode
linking options and -cclib -ls
to the native linking
options.
end
A project defines different kinds of names: local and external
library names. A local library name needs to be associated with
the name of the local directory where the build artifacts for that
library are created and an external library name needs to be
associated with the global directory where the object files for
that library are installed.
#
module Resolver : sig
#
type t
The type for internal and external name resolvers.
#
val build_dir :
t -> string
build_dir t
is the directory where lives all the build
artifacts.
#
val pkgs :
t -> string list
-> Flags.
t
Resolve global package names into command line flags.
end
#
module Action : sig
Actions to generate source files.
#
type file = [
| `Dep
of [
| `Ml
| `Mli
]
| `Ml
| `Mli
| `C
| `Js
| `Cmt
| `Cmti
| `Cmi
| `Cmo
| `Cmx
| `O
| `So
| `Cma
| `Cmxa
| `Cmxs
| `A
| `Byte
| `Native
| `Dir
| `Ext of string
| `Other of string -> string
]
The different kinds of files.
#
val create : ?dir:string
-> ('a, unit, string,
action)
Pervasives.
format4 -> 'a
bash ~dir fmt
is a generator which produces some results by
calling fmt
in a bash shell, running in the directory
dir
.
#
type 'a node = [
| `Phony of string
]
The type of nodes in the action graph.
#
type 'a rule = {
}
An action rule is a list of target nodes, prerequesite nodes and
an action.
#
val empty : 'a
t
The generator of empty actions.
end
A project is a set of components. Each component describes a
logical build unit like a compilation unit, a library, a binary, a
test, the documentation of a library, etc. A component can depend
on other components, either because it needs the dependencies to
be part of it or because it needs them to be build.
#
type comp_unit
The type for compilation unit descriptions.
#
type other
The type for arbitrarily constructed files descriptions.
#
type pkg
The type for package descriptions.
#
type lib
The type for library descriptions.
#
type bin
The type for binary executable descriptions.
#
type container
The type for containers of components.
#
type test
The type for test descriptions.
#
type doc
The type for documentation descriptions.
#
type component = [
]
The type for components.
`Unit u
u is a project compilation unit.`Lib l
is a project library.`Bin b
is a project binary.`Test b
is a project test.`Pkg p
is an external named package.- FIXME
#
val unit : ?available:
Features.
t -> ?flags:
Flags.
t -> ?deps:
component list
-> ?interface:[
| `Normal
| `Opaque
| `Hidden
]
-> string
-> [
| `Path of string list
]
-> [>
]
unit name dir ~available ~flags ~deps
is a compilation unit
named name
(the filename without extension) present in directory
dir
. It is only available whenever available
is true, it must
be build with flags
and depends on deps
to be built.
TODO document opaque & hidden.
#
val pack : ?available:
Features.
t -> ?flags:
Flags.
t -> ?deps:
component list
-> string
-> [
] list
-> [>
]
Pack compilation units together.
#
val c : ?available:
Features.
t -> ?flags:
Flags.
t -> ?deps:
component list
-> ?cclib:string list
-> ?ccopt:string list
-> string
-> [
| `Path of string list
]
-> [>
]
Same as unit but for C source files.
#
val js : ?available:
Features.
t -> ?flags:
Flags.
t -> ?deps:
component list
-> ?jsflags:string list
-> string
-> [
| `Path of string list
]
-> [>
]
Same as unit but for javascript source files.
#
val lib : ?available:
Features.
t -> ?flags:
Flags.
t -> ?deps:
component list
-> ?byte:bool
-> ?native:bool
-> ?native_dynlink:bool
-> ?pack:bool
-> string
-> [
]
-> [>
]
lib name units
is the project library name
composed by the compilation
units cus
. If lib
is set, use ocamldep
to approximate the
compilation units and their dependecies in the given directory.
#
val lib_pp : ?available:
Features.
t -> ?flags:
Flags.
t -> ?deps:
component list
-> ?byte:bool
-> ?native:bool
-> ?native_dynlink:bool
-> ?pack:bool
-> string
-> [
]
-> [>
]
lib_pp
is like lib but it defines a project pre-processor.
#
val bin : ?available:
Features.
t -> ?flags:
Flags.
t -> ?deps:
component list
-> ?byte:bool
-> ?native:bool
-> ?js:bool
-> ?linkall:bool
-> ?install:bool
-> string
-> [
]
-> [>
]
bin name units
is the binary name
obtained by compiling
the compilation units units
, with the dependencies deps
. By
default, the source files are located into bin/ (this is
controled by the value of dir
).
#
val pkg : ?available:
Features.
t -> ?flags:
Flags.
t -> ?opt:bool
-> string
-> [>
]
pkg available opt name
is an external OCaml package named name
. It is
only available whenever available
is true. If opt
is true (defaults
to false
) a feature f
is automatically created for the package
and anded to available
.
#
val pkg_pp : ?available:
Features.
t -> ?flags:
Flags.
t -> ?opt:bool
-> string
-> [>
]
pkg_pp available opt name
is like pkg except it denotes
an external OCaml pre-processor package.
#
val pkg_c : ?available:
Features.
t -> ?flags:
Flags.
t -> ?opt:bool
-> string
-> [>
]
pkg_c available opt name
is like pkg except it denotes an
external C package.
#
type test_command
The type for test commands.
#
type test_args =
Resolver.
t -> string list
The type for command line arguments when calling tests of executable.
#
val test_bin : [
]
-> ?args:
test_args -> unit
-> test_command
A test which runs a binary built in the project.
#
val pick : string
-> component -> component
unit_in c name
is the unit named name
is the component
c
. Raise Not_found
if not unit has this name.
#
val build_dir :
component -> Resolver.
t -> string
build_dir t r
is the directory where the component t
is
built.
#
val root_dir :
Resolver.
t -> string
root_dir r
is the root directory of the project.
#
val cstubs : ?available:
Features.
t -> ?deps:
component list
-> ?headers:string list
-> ?cflags:string list
-> ?clibs:string list
-> string
-> [
| `Path of string list
]
-> [>
]
stubs name dir
is the C stub generations, using Ctypes, of the
compilation unit name
. The Name_bindings
module should be
located in dir
.
#
type project
The type for OCaml projects descriptions. Simply a set of
components.
#
module Build_env : sig
Build environment.
The build environment (which can be an human) discovers available
features.
#
val default :
t
Default project configuration.
end
#
val assemble :
project -> unit
assemble project
runs the default assemblage command line
tool with the assemble file file
(defaults to assemble.ml
.
#
val (/) : string
-> string
-> string