jbuilder

Fast, portable and opinionated build system
README

Jbuilder has been renamed to Dune. A full renaming of the documentation and
the tool will be done as part of the 1.0 release.

Jbuilder is a build system designed for OCaml/Reason projects only. It
focuses on providing the user with a consistent experience and takes
care of most of the low-level details of OCaml compilation. All you
have to do is provide a description of your project and Jbuilder will
do the rest.

The scheme it implements is inspired from the one used inside Jane
Street and adapted to the open source world. It has matured over a
long time and is used daily by hundreds of developers, which means
that it is highly tested and productive.

Jbuilder comes with a manual. If you want to get started
without reading too much, you can look at the quick start
guide
or watch this introduction video.

The example directory contains examples of projects using
jbuilder.

Overview

Jbuilder reads project metadata from jbuild files, which are either
static files in a simple S-expression syntax or OCaml scripts. It uses
this information to setup build rules, generate configuration files
for development tools such as merlin, handle installation,
etc...

Jbuilder itself is fast, has very low overhead and supports parallel
builds on all platforms. It has no system dependencies: all you need
to build jbuilder and packages using jbuilder is OCaml. You don't need
make or bash as long as the packages themselves don't use bash
explicitly.

Especially, one can install OCaml on Windows with a binary installer
and then use only the Windows Console to build Jbuilder and packages
using Jbuilder.

Strengths

Composable

Take n repositories that use Jbuilder, arrange them in any way on the
file system and the result is still a single repository that Jbuilder
knows how to build at once.

This make simultaneous development on multiple packages trivial.

Gracefully handles multi-package repositories

Jbuilder knows how to handle repositories containing several
packages. When building via opam, it is able to correctly use
libraries that were previously installed even if they are already
present in the source tree.

The magic invocation is:

$ jbuilder build --only-packages <package-name> @install

Building against several configurations at once

Jbuilder is able to build a given source code repository against
several configurations simultaneously. This helps maintaining packages
across several versions of OCaml as you can tests them all at once
without hassle.

This feature should make cross-compilation easy, see details in the
roadmap.

This feature requires opam.

Jenga bridge

Jenga is another build system for OCaml that has more
advanced features such as polling or much better editor
integration. Jenga is more powerful and more complex and as a result
has many more dependencies. It is planned to implement a small bridge
between the two so that a Jbuilder project can build with Jenga using
this bridge.

Requirements

Jbuilder requires OCaml version 4.02.3 or greater.

installation

The recommended way to install jbuilder is via the
opam package manager:

$ opam install jbuilder

You can also build it manually with:

$ make release
$ make install

Note however that make install requires the opam-installer
tool. Running simply make will build jbuilder using the development
settings.

If you do not have make, you can do the following:

$ ocaml bootstrap.ml
$ ./boot.exe
$ ./_build/default/bin/main.exe install

Support

If you have questions about jbuilder, you can send an email to
ocaml-core@googlegroups.com or open a ticket on github.

Status

Jbuilder is now in beta testing stage. Once a bit more testing has
been done, it will be released in 1.0.

Roadmap

See the roadmap for the current plan. Help on any of
these points is welcome!

FAQ

Why do many Jbuilder projects contain a Makefile?

Many Jbuilder project contain a toplevel Makefile. It is often only
there for convenience, for the following reasons:

  1. there are many different build systems out there, all with a
    different CLI. If you have been hacking for a long time, the one
    true invocation you know is make && make install, possibly
    preceded by ./configure

  2. you often have a few common operations that are not part of the
    build and make <blah> is a good way to provide them

  3. make is shorter to type than jbuilder build @install

How to add a configure step to a jbuilder project?

example/sample-projects/with-configure-step shows
one way to do it which preserves composability; i.e. it doesn't require manually
running ./configure script when working on multiple projects at the same time.

Can I use topkg with jbuilder?

Yes, have a look at the topkg-jbuilder project for
more details.

Where can I find some examples of projects using Jbuilder?

The dune-universe
repository contains a snapshot of the latest versions of all opam packages
depending on jbuilder. It is therefore a useful reference to search through
to find different approaches to constructing build rules.

Known issues

Optional libraries inside a multilib directory

https://github.com/ocaml/dune/issues/51

If a directory contains several libraries and some are marked as
optional (by adding (optional) in the (library ...) stanza), then
the dependencies will still be required to perform the build.

This could be sorted out with some refactoring, but there is a simple
workaround, so it is low-priority.

Workaround

Put each optional library in a separate directory.

mli only modules

https://github.com/ocaml/dune/issues/9

Due to the low-level details of OCaml compilation, it is currently
possible to write a module that has only a .mli and no .ml
file. This works as long as the mli contains only type declarations.

This is not a properly supported feature of the compiler, and in
particular it is not possible to alias such modules or use them as the
argument of a functor. Moreover, if you do write a value declaration,
or even just define an exception in the .mli, then you won't get an
error until the point where you link an executable using this module.

For these reason, mli only modules are not recommended by Jbuilder
until the compiler support them properly.

Workaround

As long as a module type contains no value declaration, it is possible
to turn in to an implementation by using a recursive module:

module rec M : sig
  type t = A | B
end = M
include M

So if you have a module without a .ml file, simply generate a .ml
from the .mli using this trick. For instance you can add the
following rule into your jbuild file:

(rule (with-output-to foo.ml
       (progn
        (echo "module rec HACK : sig\n")
        (cat foo.mli)
        (echo "\nend = HACK\ninclude HACK\n"))))

In fact, jbuilder will automatically add this rule if you have a
module without implementation. However it will print a warning.

Implementation details

This section is for people who want to work on Jbuilder itself.

Bootstrap

In order to build itself, Jbuilder uses an OCaml script
(bootstrap.ml) that dumps most of the sources of Jbuilder into a
single boot.ml file. This file is built using ocamlopt or ocamlc
and used to build everything else.

Note that we don't include all of the sources in boot.ml. We skip a
few parts to speed up the build. In particular:

  • vendored libraries are replaced by simpler implementations taken
    from vendor/boot

  • a few files in src have an alternative version. These alternatives
    versions are named XXX.boot.EXT. For instance: glob_lexer.boot.ml

OCaml compatibility test

Install opam switches for all the entries in the
jbuild-workspace.dev file and run:

$ make all-supported-ocaml-versions

Repository organization

  • vendor/ contains dependencies of Jbuilder, that have been vendored

  • plugin/ contains the API given to jbuild files that are OCaml
    scripts

  • src/ contains the core of Jbuilder, as a library so that it can
    be used to implement the Jenga bridge later

  • bin/ contains the command line interface

  • doc/ contains the manual and rules to generate the manual pages

Design

Jbuilder was initially designed to sort out the public release of Jane
Street packages which became incredibly complicated over time. It is
still successfully used for this purpose.

One necessary feature to achieve this is the ability to precisely
report the external dependencies necessary to build a given set of
targets without running any command, just by looking at the source
tree. This is used to automatically generate the <package>.opam
files for all Jane Street packages.

To implement this, the build rules are described using a build arrow,
which is defined in src/build.mli. In the end it makes the
development of the internal rules of Jbuilder very composable and
quite pleasant.

To deal with process multiplexing, Jbuilder uses a simplified
Lwt/Async-like monad, implemented in src/future.mli.

Code flow
  • src/jbuild.mli contains the internal representation
    of jbuild files and the parsing code

  • src/jbuild_load.mli contains the code to scan
    a source tree and build the internal database by reading
    the jbuild files

  • src/gen_rules.mli contains all the build rules
    of Jbuilder

  • src/build_system.mli contains a trivial
    implementation of a Build system. This is what Jenga will provide
    when implementing the bridge

Install
Published
14 Mar 2018
Sources
jbuilder-1.0.beta18.1.tbz
md5=81571d6761fb19ba9f9b62572d05da16
Dependencies
ocaml
>= "4.02.3" & < "4.08.0"
Reverse Dependencies
acgtk
>= "1.3.2" & < "1.4.0"
ago
>= "0.4"
aifad
= "2.1.0"
alcotest
>= "0.8.0" & < "0.8.5"
alcotest-lwt
< "0.8.5"
amqp-client
= "1.1.0" | >= "1.1.2" & < "2.0.3"
angstrom
>= "0.6.0" & < "0.11.1"
angstrom-async
< "0.11.1"
angstrom-unix
< "0.11.1"
ascii85
>= "0.4"
asl
>= "0.11"
async
>= "v0.9.0" & < "v0.12.0"
async_durable
< "v0.12.0"
async_extended
>= "v0.9.0"
async_extra
>= "v0.9.0" & < "v0.12.0"
async_find
>= "v0.9.0" & < "v0.12.0"
async_inotify
>= "v0.9.0" & < "v0.12.0"
async_js
< "v0.12.0"
async_kernel
>= "v0.9.0" & < "v0.12.0"
async_parallel
>= "v0.9.0"
async_rpc_kernel
>= "v0.9.0" & < "v0.12.0"
async_sendfile
< "v0.12.0"
async_shell
>= "v0.9.0" & < "v0.12.0"
async_smtp
>= "v0.9.0" & < "v0.12.0"
async_ssl
>= "v0.9.0" & < "v0.12.0"
async_unix
>= "v0.9.0" & < "v0.12.0"
atd
>= "1.2.1" & < "2.2.1"
atdgen
>= "1.10.2" & < "2.2.1"
atdj
< "2.2.1"
aws-s3
>= "1.1.0" & < "4.0.0"
aws-s3-async
< "4.0.0"
aws-s3-lwt
< "4.0.0"
base
>= "v0.9.2" & < "v0.12.0"
base64
= "2.2.0"
benchmark
= "1.5"
bignum
>= "v0.9.0" & < "v0.12.0"
bigstringaf
< "0.5.0"
bin_prot
>= "v0.9.1" & < "v0.12.0"
biniou
>= "1.1.0" & < "1.2.1"
biocaml
= "0.8.0"
bisect_ppx
>= "1.3.0" & < "1.4.0"
bistro
>= "0.3.0" & < "0.5.0"
bitcoinml
< "0.4.1"
bitmasks
= "1.1.0"
bitstring
>= "3.0.0" & < "3.1.1"
brotli
>= "2.0.3"
bst
< "3.0.0"
bun
< "0.3.3"
calculon
>= "0.2" & < "0.4"
camlimages
>= "5.0.0" & < "5.0.2"
camlon
>= "2.0.1" & < "3.0.0"
camomile
>= "0.8.6" & < "1.0.2"
capnp
>= "3.0.0" & < "3.3.0"
capnp-rpc
< "0.3.2"
capnp-rpc-lwt
< "0.3.2"
caqti
< "0.10.2"
caqti-async
< "0.10.2"
caqti-dynload
< "0.10.2"
caqti-lwt
< "0.10.2"
cdrom
= "0.9.3"
cfg
= "2.1.0"
cfstream
>= "1.2.3" & < "1.3.1"
charrua-client
>= "0.9" & < "0.11.2"
charrua-core
>= "0.8" & < "0.11.2"
charrua-unix
>= "0.9" & < "0.11.2"
checkseum
< "0.0.3"
cinaps
< "v0.12.0"
clarity
< "0.4.0"
cmdtui
>= "0.4.3"
cohttp
>= "0.99.0" & < "1.1.1"
cohttp-async
< "1.1.1"
cohttp-lwt
< "1.1.1"
cohttp-mirage
< "1.1.1"
cohttp-top
< "1.1.1"
coin
< "0.1.1"
color
< "0.2.0"
command_rpc
< "v0.12.0"
conduit
>= "1.0.0" & < "1.3.0"
conduit-async
< "1.3.0"
conduit-lwt
< "1.3.0"
containers
>= "2.0" & < "2.4"
core
>= "v0.9.0" & < "v0.12.0"
core_bench
>= "v0.9.0" & < "v0.12.0"
core_extended
>= "v0.9.0" & < "v0.12.0"
core_kernel
>= "v0.9.0" & < "v0.12.0"
core_profiler
>= "v0.9.0" & < "v0.12.0"
cow
= "2.3.0"
cowabloga
>= "0.3.0" & < "0.5.0"
cpm
= "4.0.0"
cppo
>= "1.6.0" & < "1.6.6"
crc
= "2.0.0"
crlibm
< "0.3"
crowbar
< "0.2"
crunch
= "2.1.0"
cryptodbm
>= "0.84.2"
cstruct
>= "3.0.0" & < "3.3.0"
cstruct-async
< "3.3.0"
cstruct-lwt
>= "3.0.0" & < "3.3.0"
cstruct-unix
>= "3.0.0" & < "3.3.0"
csv
= "2.0"
csv-lwt
< "2.1"
csvfields
< "v0.12.0"
cuid
< "0.2"
curly
< "0.2.0"
DrawGrammar
= "0.2.1"
datakit-ci
>= "0.12.0" & < "0.12.2"
datakit-client
= "0.12.0"
datakit-github
= "0.12.0"
datakit-server
= "0.12.0"
decoders
< "0.1.2"
decompress
= "0.8"
depyt
= "0.2.0"
diet
< "0.2"
digestif
= "0.6.1"
dispatch
= "0.4.0"
dispatch-js
< "0.4.1"
distributed
= "0.5.0"
dlm
< "0.3.1"
dns
>= "1.0.0" & < "1.1.0"
dns-async
< "1.1.0"
dns-forward
>= "0.9.0"
dns-lwt
< "1.1.0"
dns-lwt-unix
< "1.1.0"
doc-ock
>= "1.1.0"
doc-ock-html
>= "1.1.0"
doc-ock-xml
>= "1.1.0"
dockerfile
>= "3.0.0" & < "6.0.0"
dokeysto
< "2.0.0"
dokeysto_lz4
< "3.0.0"
dtoa
>= "0.3.0" & < "0.3.2"
duff
< "0.2"
dune-release
< "1.0.0"
easy-format
>= "1.3.0" & < "1.3.2"
ecaml
< "v0.12.0"
electrod
< "0.1.6"
email_message
>= "v0.9.0" & < "v0.12.0"
emile
< "0.4"
encore
< "0.2"
eqaf
< "0.2"
exenum
>= "0.82.0" & < "0.86"
ezgzip
< "0.2.3"
ezjsonm
>= "0.5.0" & < "1.0.0"
ezjsonm-lwt
< "1.0.0"
ezxenstore
= "0.1.2"
ezxmlm
= "1.0.2"
facile
>= "1.1.4"
faraday
>= "0.3.0" & < "0.7.1"
faraday-async
< "0.7.1"
faraday-lwt
< "0.7.1"
fat-filesystem
>= "0.12.1" & < "0.13.0"
fd-send-recv
= "1.0.5"
fftw3
>= "0.8" & < "0.8.2"
fieldslib
>= "v0.9.0" & < "v0.12.0"
frenetic
>= "5.0.0" & < "5.0.5"
functoria
>= "2.1.0" & < "2.2.1"
functoria-runtime
>= "2.1.0" & < "2.2.2"
General
>= "0.4.0" & < "0.6.0"
gammu
>= "0.9.4"
gapi-ocaml
= "0.3.6"
gdbprofiler
>= "0.2" & < "0.4"
gen
= "0.5.1"
get_line
= "4.0.0"
git
>= "1.11.0" & < "2.0.0"
git-http
>= "1.11.0" & < "2.0.0"
git-mirage
>= "1.11.0" & < "2.0.0"
git-unix
>= "1.11.1" & < "2.0.0"
github
>= "3.0.0" & < "4.0.0"
github-hooks
>= "0.2.0" & < "0.4.0"
github-jsoo
< "4.0.0"
github-unix
< "4.0.0"
gnuplot
= "0.5.3"
gpr
>= "1.3.0" & < "1.4.0"
graphql
< "0.8.0"
graphql-async
< "0.8.0"
graphql-lwt
< "0.8.0"
grenier
= "0.7"
gsl
>= "1.20.0" & < "1.24.0"
hashids
< "1.0.1"
hex
>= "1.1.0" & < "1.3.0"
hidapi
< "1.1"
hiredis
>= "0.8"
horned_worm
< "0.3.4"
httpaf
< "0.6.0"
httpaf-async
< "0.6.0"
hvsock
>= "1.0.0" & < "2.0.0"
incr_dom
< "v0.12.0"
incr_dom_widgets
< "v0.12.0"
incr_map
< "v0.12.0"
incr_select
< "v0.12.0"
incremental
>= "v0.9.0" & < "v0.12.0"
interval
= "1.4"
inuit
>= "0.4.1"
io-page
>= "2.0.0" & < "2.1.0"
io-page-unix
>= "2.0.0" & < "2.1.0"
io-page-xen
>= "2.0.0" & < "2.1.0"
ipaddr
= "2.8.0"
irc-client
>= "0.6.0" & < "0.6.2"
irmin
>= "1.2.0" & < "2.0.0"
irmin-chunk
= "1.3.0"
irmin-fs
< "2.0.0"
irmin-git
>= "1.2.0" & < "2.0.0"
irmin-http
>= "1.2.0" & < "2.0.0"
irmin-mem
< "2.0.0"
irmin-mirage
>= "1.2.0" & < "2.0.0"
irmin-unix
>= "1.2.0" & < "1.3.3"
irmin-watcher
= "0.3.0"
JsOfOCairo
>= "1.0.1" & < "2.0.0"
jenga
>= "v0.9.0"
js_of_ocaml
>= "3.0" & < "3.3.0"
junit
>= "1.0" & < "2.0.1"
junit_ounit
< "2.0.1"
jupyter
>= "2.2.2" & < "2.3.2"
kafka
>= "0.3" & < "0.5"
kicadsch
< "0.4.0"
lacaml
>= "10.0.1" & < "11.0.2"
lambda-term
>= "1.11" & < "2.0"
lambdasoup
>= "0.6.2" & < "0.6.4"
lbfgs
= "0.9"
ldap
< "2.4.1"
lens
>= "1.2.1" & < "1.2.3"
let-if
< "0.2.0"
levenshtein
>= "1.1.3"
libsvm
= "0.9.4"
line-up-words
< "v0.12.0"
linenoise
= "1.1.0"
links
>= "0.7.2" & < "0.8"
lwt
>= "3.1.0" & < "4.2.0"
lwt_glib
= "1.1.0"
lwt_log
< "1.1.1"
lwt_ppx
< "1.2.2"
lwt_react
>= "1.1.0" & < "1.1.2"
lwt_ssl
>= "1.1.0" & < "1.1.3"
magic-mime
>= "1.0.1" & < "1.1.1"
markup
>= "0.7.6" & < "0.8.0"
mccs
< "1.1+5"
mesh
>= "0.8.9" & < "0.9.5"
mesh-easymesh
< "0.9.5"
mesh-graphics
< "0.9.5"
mesh-triangle
< "0.9.5"
milter
>= "1.0.4"
mirage
>= "3.0.5" & < "3.3.0"
mirage-block
= "1.1.0"
mirage-block-unix
>= "2.8.2" & < "2.11.0"
mirage-block-xen
>= "1.5.2" & < "1.6.0"
mirage-clock
= "1.3.0"
mirage-clock-unix
>= "1.3.0" & < "2.0.0"
mirage-conduit
< "1.3.0" | >= "3.0.0" & < "3.1.0"
mirage-console
>= "2.3.2" & < "2.4.0"
mirage-console-lwt
>= "2.3.2" & < "2.4.0"
mirage-console-unix
>= "2.3.2" & < "2.4.1"
mirage-console-xen
>= "2.3.2" & < "2.4.0"
mirage-console-xen-backend
>= "2.3.2" & < "2.4.0"
mirage-console-xen-proto
>= "2.3.2" & < "2.4.0"
mirage-device
= "1.1.0"
mirage-dns
>= "3.0.0" & < "3.1.0"
mirage-flow
>= "1.3.0" & < "1.6.0"
mirage-flow-lwt
>= "1.3.0" & < "1.6.0"
mirage-flow-unix
>= "1.3.0" & < "1.6.0"
mirage-fs
= "1.1.1"
mirage-fs-lwt
= "1.1.1"
mirage-fs-unix
>= "1.4.0" & < "1.6.0"
mirage-http
>= "3.2.0"
mirage-kv
= "1.1.1"
mirage-kv-lwt
= "1.1.0"
mirage-nat
< "1.1.0"
mirage-net
>= "1.1.1" & < "2.0.0"
mirage-net-fd
>= "0.2.1"
mirage-net-lwt
>= "1.1.0" & < "2.0.0"
mirage-net-xen
>= "1.7.1" & < "1.9.0"
mirage-profile
>= "0.8.0" & < "0.9.0"
mirage-protocols
>= "1.2.0" & < "2.0.0"
mirage-protocols-lwt
>= "1.2.0" & < "2.0.0"
mirage-qubes
>= "0.5" & < "0.7.0"
mirage-random
= "1.1.0"
mirage-runtime
>= "3.0.5" & < "3.3.0"
mirage-stack
>= "1.1.0" & < "1.4.0"
mirage-stack-lwt
>= "1.1.0" & < "1.4.0"
mirage-time
= "1.1.0"
mirage-types
>= "3.0.5" & < "3.3.0"
mirage-types-lwt
>= "3.0.5" & < "3.3.0"
mirage-vnetif
>= "0.4.0" & < "0.4.2"
mlt_parser
< "v0.12.0"
mock
< "0.1.1"
mock-ounit
< "0.1.1"
moss
< "0.1.1"
msgpck
>= "1.3" & < "1.5"
mstruct
>= "1.3.3"
mustache
= "3.0.2"
nbd
= "2.2.0"
netchannel
< "1.9.0"
nonstd
>= "0.0.3"
npy
>= "0.0.5" & < "0.0.8"
nsq
< "0.4.0"
nunchaku
>= "0.5.1"
ocal
>= "0.1.3" & < "0.2.2"
ocaml-basics
>= "0.5.0"
ocaml-monadic
= "0.4.0"
ocaml-r
= "0.1.0"
ocaml-top
>= "1.1.4"
ocaml-version
< "1.0.0"
ocaml_plugin
>= "v0.9.0" & < "v0.12.0"
ocamlspot
>= "4.07.0.2.3.2"
ocp-browser
>= "1.1.6" & < "1.1.9"
ocp-index
= "1.1.7"
octavius
>= "1.1.0" & < "1.2.2"
odoc
>= "1.1.0" & < "1.3.0"
opam-client
>= "2.0.0~beta5" & < "2.0.0~rc3"
opam-core
>= "2.0.0~rc" & < "2.0.2"
opam-devel
>= "2.0.0~beta5" & < "2.0.0~rc3"
opam-format
>= "2.0.0~beta5" & < "2.0.2"
opam-repository
>= "2.0.0~beta5" & < "2.0.2"
opam-solver
>= "2.0.0~beta5" & < "2.0.2"
opam-state
>= "2.0.0~beta5" & < "2.0.2"
open
< "0.2.2"
opium
= "0.16.0"
opium_kernel
< "0.17.0"
optint
< "0.0.2"
oranger
< "2.0.1"
orec
< "1.0.1"
orsvm_e1071
< "3.0.2"
orxgboost
< "1.1.0"
oseq
< "0.2"
owl
>= "0.3.0" & < "0.4.0"
owl-base
< "0.4.0"
owl-top
< "0.4.0"
owl-zoo
< "0.4.0"
parse-argv
= "0.1.0"
parsexp
< "v0.12.0"
parsexp_io
< "v0.12.0"
patdiff
>= "v0.9.0" & < "v0.12.0"
patience_diff
>= "v0.9.0" & < "v0.12.0"
pbkdf
= "0.3.0"
pcap-format
= "0.5.1"
pcre
>= "7.3.0" & < "7.3.5"
pecu
< "0.2"
pgx
< "1.0"
pla
= "1.2"
plotkicadsch
< "0.4.0"
pomap
= "4.0.0"
posixat
< "v0.12.0"
postgresql
>= "4.1.0" & < "4.4.1"
ppx_assert
>= "v0.9.0" & < "v0.12.0"
ppx_base
< "v0.12.0"
ppx_bench
>= "v0.9.1" & < "v0.12.0"
ppx_bin_prot
>= "v0.9.0" & < "v0.12.0"
ppx_bitstring
>= "2.0.0" & < "4.0.0"
ppx_blob
>= "0.3.0" & < "0.6.0"
ppx_compare
>= "v0.9.0" & < "v0.12.0"
ppx_compose
< "0.1.0"
ppx_conv_func
>= "v0.9.0" & < "v0.12.0"
ppx_core
>= "v0.9.0"
ppx_cstruct
>= "3.0.1" & < "3.3.0"
ppx_csv_conv
>= "v0.9.0" & < "v0.12.0"
ppx_custom_printf
>= "v0.9.0" & < "v0.12.0"
ppx_defer
= "0.3.0"
ppx_derivers
< "1.2.1"
ppx_driver
>= "v0.9.1"
ppx_enumerate
>= "v0.9.0" & < "v0.12.0"
ppx_expect
>= "v0.9.0" & < "v0.12.0"
ppx_fail
>= "v0.9.0" & < "v0.12.0"
ppx_fields_conv
>= "v0.9.0" & < "v0.12.0"
ppx_gen_rec
< "1.1.0"
ppx_hardcaml
>= "1.3.0"
ppx_hash
< "v0.12.0"
ppx_here
>= "v0.9.1" & < "v0.12.0"
ppx_inline_test
>= "v0.9.2" & < "v0.12.0"
ppx_jane
>= "v0.9.0" & < "v0.12.0"
ppx_js_style
< "v0.12.0"
ppx_jsobject_conv
>= "0.5.0" & < "0.6.0"
ppx_let
>= "v0.9.0" & < "v0.12.0"
ppx_meta_conv
= "4.0.0"
ppx_monadic
>= "2.3.0"
ppx_optcomp
>= "v0.9.0" & < "v0.12.0"
ppx_optional
< "v0.12.0"
ppx_orakuda
>= "3.3.0"
ppx_pipebang
>= "v0.9.0" & < "v0.12.0"
ppx_regexp
< "0.4.0"
ppx_sexp_conv
>= "v0.9.0" & < "v0.12.0"
ppx_sexp_message
>= "v0.9.0" & < "v0.12.0"
ppx_sexp_value
>= "v0.9.0" & < "v0.12.0"
ppx_test
= "1.6.0"
ppx_tools_versioned
>= "5.2" & < "5.2.2"
ppx_type_conv
>= "v0.9.0"
ppx_typerep_conv
>= "v0.9.0" & < "v0.12.0"
ppx_variants_conv
>= "v0.9.0" & < "v0.12.0"
ppx_xml_conv
>= "v0.9.0" & < "v0.12.0"
ppxfind
< "1.3"
ppxlib
!= "0.2.1" & != "0.3.0" & < "0.4.0"
ppxx
>= "2.3.1" & < "2.4.0"
prometheus
>= "0.2" & < "0.6"
prometheus-app
>= "0.2" & < "0.6"
protocol-9p
>= "0.10.0" & < "1.0.0"
qcheck
= "0.8"
qcow
>= "0.10.0" & < "0.11.0"
qcow-tool
< "0.11.0"
radare2
= "0.0.2"
re
>= "1.7.2" & < "1.9.0"
re2
>= "v0.10.1" & < "v0.12.0"
reason
>= "3.0.3" & < "3.3.5"
record_builder
< "v0.12.0"
redis
>= "0.3.4" & < "0.4"
redis-lwt
< "0.4"
redis-sync
< "0.4"
regenerate
< "0.2"
res
= "5.0.0"
resource_cache
< "v0.12.0"
result
= "1.3"
rfc1951
< "0.8.1"
root1d
= "0.5"
rope
>= "0.6" & < "0.6.2"
rpc
>= "5.9.0" & < "6.1.0"
rpc_parallel
>= "v0.9.0" & < "v0.12.0"
rpclib
< "6.1.0"
rpclib-async
< "6.1.0"
rpclib-lwt
< "6.1.0"
rtop
< "3.3.5"
safepass
= "3.0"
sanddb
< "0.2"
secp256k1
>= "0.2.5" & < "0.4.1"
sequence
>= "1.0"
sequencer_table
< "v0.12.0"
session
= "0.4.0"
sexp_pretty
< "v0.12.0"
sexplib
>= "v0.9.2" & < "v0.12.0"
sexplib0
< "v0.12.0"
sha
= "1.12"
shared-memory-ring
>= "2.0.0" & < "3.1.0"
shexp
< "v0.12.0"
smbc
= "0.4.2"
spacetime_lib
= "0.2.0"
spawn
>= "v0.9.0" & < "v0.12.0"
spf
>= "2.0.2"
splay_tree
< "v0.12.0"
spotlib
= "4.0.3"
sqlexpr
>= "0.9.0"
sqlite3
>= "4.2.0" & < "4.4.1"
srs
>= "2.0.0"
ssh-agent
< "0.2.0"
stdint
= "0.5.1"
stdio
< "v0.12.0"
string_dict
< "v0.12.0"
stringext
= "1.5.0"
swagger
< "0.2.0"
tar
< "1.0.0"
tar-mirage
< "1.0.0"
tar-unix
< "1.0.0"
tcpip
>= "3.4.1" & < "3.7.0"
telegraml
>= "2.2.0"
tensorflow
= "0.0.10"
textutils
>= "v0.9.0" & < "v0.12.0"
textutils_kernel
< "v0.12.0"
tiny_json
>= "1.1.5"
toplevel_expect_test
>= "v0.9.1" & < "v0.12.0"
topological_sort
< "v0.12.0"
touist
>= "3.5.0"
travis-opam
>= "1.2.0" & < "1.5.0"
trax
< "0.4.0"
treeprint
>= "2.2.0"
tube
< "4.4.0"
tuntap
>= "1.5.0" & < "1.7.0"
typerep
>= "v0.9.0" & < "v0.12.0"
typerep_extended
>= "v0.9.0"
typpx
>= "1.4.3"
tyre
>= "0.4" & < "0.5"
unmagic
>= "1.0.4"
uri
>= "1.9.4" & < "2.0.0"
utop
>= "2.0.0" & < "2.3.0"
uuuu
< "0.1.1"
variantslib
>= "v0.9.0" & < "v0.12.0"
vcardgen
< "1.2"
vchan
= "3.0.0"
vchan-unix
< "4.0.0"
vchan-xen
< "4.0.0"
vhd-format
>= "0.9.1" & < "0.12.0"
vhd-format-lwt
< "0.12.0"
virtual_dom
< "v0.12.0"
vlq
< "0.2.1"
vmnet
>= "1.2.0" & < "1.3.2"
vpnkit
>= "0.1.1"
vpt
< "5.0.0"
wall
< "0.4"
wamp
>= "1.2"
weberizer
= "0.7.8"
webmachine
>= "0.5.0" & < "0.6.2"
websocket
= "2.10"
win-error
= "0.3"
wtf8
< "1.0.2"
xen-evtchn
= "2.0.0"
xen-gnt
>= "3.0.0" & < "3.1.0"
xen-gnt-unix
< "3.1.0"
xenstore
>= "1.4.0" & < "2.1.0"
xenstore_transport
>= "0.9.6" & < "1.1.0"
yaml
< "1.0.0"
yara
< "0.2"
yojson
>= "1.4.0" & < "1.5.0"
yuscii
< "0.2.0"
zed
>= "1.5" & < "2.0"
zmq
= "5.0.0"
zmq-async
< "5.1.0"
zmq-lwt
< "5.1.0"