Module Assemblage

module Assemblage: sig .. end
Assemble software projects.

Assemblage provides functions to describe the structure of your software project as a project description value. This data structure allows tools known as assemblage drivers to explore, build and manage your project.

Open the module to use it, this defines only modules, types and a few combinators in your scope.

Consult the basics.

Release %%VERSION%% — %%MAINTAINER%%



Preliminaries


module String: sig .. end
Extended String module, string sets and maps.
module Fmt: sig .. end
Formatters.
module Path: sig .. end
File system paths, path sets and maps.
module Log: sig .. end
Assemblage log.
module Cmd: sig .. end
Executing non-build commands and IO operations.

Building


module Conf: sig .. end
Build configuration.
module Ctx: sig .. end
Command execution contexts.
module Args: sig .. end
Command argument bundles.
module Acmd: sig .. end
Action commands.
module Action: sig .. end
Build action.

Parts


type part_kind = [ `Base | `Bin | `Dir | `Doc | `Lib | `Pkg | `Run | `Unit ] 
The type for part kinds.
type +[< part_kind ] part 
The type for project parts.
module Part: sig .. end
Parts, part sets and maps.
module Unit: sig .. end
Compilation unit part.
module Lib: sig .. end
Library part.
module Bin: sig .. end
Binary executable part.
module Pkg: sig .. end
Package part.
module Doc: sig .. end
Unit documentation set part.
module Dir: sig .. end
Directory part.
module Run: sig .. end
Runs.

Part specification combinators


type path = Path.t Conf.value 
The type for part paths specifications.
val root : path
root is the current directory relative to the project root.
val (/) : path -> string -> path
path / seg is Conf.(const Path.( / ) $ path $ const seg).
val (//) : path ->
Path.rel Conf.value -> path
path // rel is Conf.(const Path.( // ) $ path $ rel).
val unit : ?usage:Part.usage ->
?exists:bool Conf.value ->
?args:Args.t ->
?needs:[< `Lib | `Pkg ] part list ->
?kind:Unit.kind ->
?dir:path ->
string -> [< part_kind > `Unit ] part
See Assemblage.Unit.v. kind defaults to `OCaml (`Both, `Normal).
val lib : ?usage:Part.usage ->
?exists:bool Conf.value ->
?args:Args.t ->
?byte:bool ->
?native:bool ->
?native_dynlink:bool ->
?kind:Lib.kind ->
string ->
[< `Lib | `Pkg | `Unit ] part list ->
[< part_kind > `Lib ] part
See Assemblage.Lib.v. kind defaults to `OCaml.
val bin : ?usage:Part.usage ->
?exists:bool Conf.value ->
?args:Args.t ->
?byte:bool ->
?native:bool ->
?js:bool ->
?kind:Bin.kind ->
string ->
[< `Lib | `Pkg | `Unit ] part list ->
[< part_kind > `Bin ] part
See Assemblage.Bin.v. kind defaults to `OCaml.
val pkg : ?usage:Part.usage ->
?exists:bool Conf.value ->
?opt:bool ->
?kind:Pkg.kind ->
string -> [< part_kind > `Pkg ] part
See Assemblage.Pkg.v. kind defaults to `OCamlfind.
val doc : ?usage:Part.usage ->
?exists:bool Conf.value ->
?args:Args.t ->
?keep:([< `Unit ] part -> bool) ->
?kind:Doc.kind ->
string ->
[< `Bin | `Lib | `Unit ] part list ->
[< part_kind > `Doc ] part
See Assemblage.Doc.v. kind defaults to `OCamldoc.
val dir : ?usage:Part.usage ->
?exists:bool Conf.value ->
?args:Args.t ->
?spec:Dir.spec ->
?install:bool ->
Dir.kind ->
[< `Base | `Bin | `Dir | `Doc | `Lib | `Unit ] part list ->
[< part_kind > `Dir ] part
See Assemblage.Dir.v.
val file : ?usage:Part.usage ->
?exists:bool Conf.value ->
Path.t -> [< part_kind > `Base ] part
See Assemblage.Part.file.
val run : ?usage:Part.usage ->
?exists:bool Conf.value ->
?args:Args.t ->
?dir:path ->
string ->
Action.t Conf.value ->
[< part_kind > `Run ] part
See Assemblage.Run.v. FIXME maybe removed that one from the toplevel.

Projects


type project 
The type for projects descriptions.
module Project: sig .. end
Project descriptions.
val assemble : project -> unit
assemble p registers p for assembling by an assemblage driver.

Private API


module Private: sig .. end
Private functions and types for implementing drivers.

Basics

An assemblage project is made of parts. This was very basic.

Don't

Make the project depend on direct conditions. E.g.

    if Sys.file_exists file then Some (unit "src")  else None
    if Sys.win32 then ...
    if Sys.ocaml_version = ...

That's the way of doing it:

    let exists = Conf.(const Cmd.File.exists $ const (Path.file file)) in
     unit ~exists "src"
TODO the rule to hammer in people's mind is the following: don't do anything that doesn't make the set of configuration keys constant on *every* load of the assemble.ml file. Maybe we could still make an exception for a units combinator that looksup the units in a directory automatically.

Limitations

The build model behind assemblage has the following limitation.

Designing new part kind

  1. Define configuration keys for the utilities.
  2. Make non lifted action creators for the main operations. Don't use the keys yet, use a bin type to represent them. Arguments to the creators should be those that allow to correctly determine the inputs and outputs of the operation (e.g. for OCaml annot is handled in the creator). Add an ?args optional argument.
  3. In the part action definition function lift the utilities and common build configuration keys (debug, warn_error, etc). Handle the command argument for those at that level an pass them to actions using the ?args optional argument of creators.
  4. Don't support all command line flags, the user can use argument bundles. You may want to provide some of them already created.