package febusy

  1. Overview
  2. Docs

Embedded monadic-ish DSL to build dependency graphs.

Just like "make", "omake", "dune", "ketrew", etc. we are building direct-acyclic-graphs (DAGs) of build artifacts using custom actions (OCaml functions).

The monadic API gives Febusy fully dynamic dependencies.

Values in the DAG have type 'artifact DAG.t where 'artifact is of type ('specification, 'representative) Artifact.t.

  • 'specification defines how to deal with the build artifacts (e.g. “how to tell if we need to re-build”).
  • 'representative is the type of the values that the OCaml code you write to build nodes in the graph can manipulate (e.g. for file-system files, the representative is their path).

See function artifact to build custom artifacts.

An artifact has to be associated with an 'a Action.t to be added to the DAG (see function ensures).

val return : ('a, 'b) Build.Artifact.t -> 'b -> ('a, 'b) Build.Artifact.t Build.DAG.t

Very basic building bloc of the DAG, inject a fresh dependency by returning an artifact definition together with a corresponding value.

val (>>=) : ('a, 'b) Build.Artifact.t Build.DAG.t -> (('a, 'b) Build.Artifact.t -> 'b -> ('c, 'd) Build.Artifact.t Build.DAG.t) -> ('c, 'd) Build.Artifact.t Build.DAG.t

Introduce a dependency in the DAG, for instance: dependency >>= fun artifact representing_value -> (* ... *).

But note that, in practice, most often the first argument is ignored: depedency >>= fun _ v -> (* ... *).

val (=<>=) : ('a, 'b) Build.Artifact.t Build.DAG.t -> ('c, 'd) Build.Artifact.t Build.DAG.t -> ('a * 'c, 'b * 'd) Build.Artifact.t Build.DAG.t

a =<>= b is a node in the graph that depends on a and b.

val join : ('a, 'b) Build.Artifact.t Build.DAG.t list -> ('a list, 'b list) Build.Artifact.t Build.DAG.t

join l is a node that depends on all the nodes in l.

val ocaml : (unit -> 'a) -> 'a Build.Action.t

Make an action from an OCaml function.

val ensures : o:('a, 'b) Build.Artifact.t -> 'b Build.Action.t -> ('a, 'b) Build.Artifact.t Build.DAG.t

Tie an artifact to an action that builds it, this a basic node in the DAG.

val (<--) : ('a, 'b) Build.Artifact.t -> (unit -> 'b) -> ('a, 'b) Build.Artifact.t Build.DAG.t

a <-- f is a shortcut for ensures ~o (ocaml f).

val (**) : ('a, 'b) Build.Artifact.t -> ('c, 'd) Build.Artifact.t -> ('a * 'c, 'b * 'd) Build.Artifact.t

Build a “pair” compound artifact.

val list : ('a, 'b) Build.Artifact.t list -> ('a list, 'b list) Build.Artifact.t

Build a “list” compound artifact.

val artifact : ?serialize:('a -> 'b -> string) -> ?deserialize_exn:('a -> string -> 'b) -> 'a -> to_string:('a -> string) -> hash:('a -> 'b -> string) -> materialize:('a -> 'b option) -> ('a Build.Artifact.custom, 'b) Build.Artifact.t

Create a “root” build artifact.

module File : sig ... end

The File module defines two particular kinds of artifact: normal files and lists of normal files.

module String_value : sig ... end

The String_value module is another kind of artifact.

val file : string -> (File.spec Build.Artifact.custom, [> `File of string ]) Build.Artifact.t

file s is an alias File.create s

string s is an alias String_value.create s

val return_value : string -> 'a -> (string Build.Artifact.custom, 'a) Build.Artifact.t Build.DAG.t

return_value id v puts v in the dependency graph identified by id (in the cache and digest database). v needs to be serializable with the Marshal module (and the digest is computed from the value too).

val phony : string -> (string Build.Artifact.custom, unit) Build.Artifact.t

Artifact that is built “once-per-run.”

val return_fresh : 'a -> (string Build.Artifact.custom, 'a) Build.Artifact.t Build.DAG.t

Return a value which is built “once-per-run” (has to be Marshal-serializable).

module System : sig ... end

Useful functions to deal with the operating system.

module Make_unix : sig ... end

Run the build DAG in a mono-threaded Unix-ish environment.