2017-04-20 15:52:05 +00:00
|
|
|
* JBUILDER - A composable build system for OCaml and Reason
|
2017-05-07 19:43:16 +00:00
|
|
|
%%VERSION%%
|
2016-12-02 13:54:32 +00:00
|
|
|
|
2017-04-20 15:52:05 +00:00
|
|
|
Jbuilder is a build system designed for OCaml/Reason projects only. It
|
2017-02-28 17:20:41 +00:00
|
|
|
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 hundred of developpers, which means
|
|
|
|
that it is highly tested and productive.
|
2016-12-02 13:54:32 +00:00
|
|
|
|
2017-02-21 15:09:26 +00:00
|
|
|
Jbuilder comes with a [[./doc/manual.org][manual]]. If you want to get started without
|
2017-02-28 17:20:41 +00:00
|
|
|
reading too much, you can look at the [[./doc/quick-start.org][quick start guide]].
|
2017-02-21 15:09:26 +00:00
|
|
|
|
2017-03-21 14:37:35 +00:00
|
|
|
The [[example]] directory contains examples of projects using jbuilder.
|
|
|
|
|
2017-03-01 09:04:01 +00:00
|
|
|
[[https://travis-ci.org/janestreet/jbuilder][https://travis-ci.org/janestreet/jbuilder.png?branch=master]]
|
2017-04-24 11:26:23 +00:00
|
|
|
#+html: <a href="https://ci.appveyor.com/project/diml/jbuilder/branch/master"><img src="https://ci.appveyor.com/api/projects/status/bn3kcxx648jt6dyt?svg=true"/></a>
|
2017-03-01 09:04:01 +00:00
|
|
|
|
2016-12-02 13:54:32 +00:00
|
|
|
** Overview
|
|
|
|
|
2017-02-28 17:20:41 +00:00
|
|
|
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 [[https://github.com/ocaml/merlin][merlin]], handle installation, etc...
|
|
|
|
|
2017-03-28 00:05:59 +00:00
|
|
|
Jbuilder itself is fast, has very low overhead and supports parallel
|
2017-02-28 17:20:41 +00:00
|
|
|
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
|
2016-12-02 13:54:32 +00:00
|
|
|
=make= or =bash= as long as the packages themselves don't use =bash=
|
2017-03-28 00:05:59 +00:00
|
|
|
explicitly.
|
2016-12-02 13:54:32 +00:00
|
|
|
|
2017-04-24 11:58:11 +00:00
|
|
|
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.
|
2016-12-02 13:54:32 +00:00
|
|
|
|
2017-02-28 17:20:41 +00:00
|
|
|
** Strengths
|
2016-12-02 13:54:32 +00:00
|
|
|
|
2017-02-28 17:20:41 +00:00
|
|
|
*** Composable
|
2016-12-02 13:54:32 +00:00
|
|
|
|
2017-02-28 17:20:41 +00:00
|
|
|
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.
|
2016-12-02 13:54:32 +00:00
|
|
|
|
2017-02-28 17:20:41 +00:00
|
|
|
This make simultaneous development on multiple packages trivial.
|
2016-12-02 13:54:32 +00:00
|
|
|
|
2017-02-28 17:20:41 +00:00
|
|
|
*** Gracefully handles multi-package repositories
|
2016-12-02 13:54:32 +00:00
|
|
|
|
2017-02-28 17:20:41 +00:00
|
|
|
Jbuilder knows how to handle repositories containing several
|
|
|
|
packages. When building via [[https://opam.ocaml.org/][opam]], it is able to correctly use
|
|
|
|
libraries that were previously installed even if they are already
|
|
|
|
present in the source tree.
|
2016-12-02 13:54:32 +00:00
|
|
|
|
2017-03-02 18:21:19 +00:00
|
|
|
The magic invocation is:
|
|
|
|
|
|
|
|
#+begin_src sh
|
|
|
|
$ jbuilder build --only-packages <package-name> @install
|
|
|
|
#+end_src
|
2016-12-02 13:54:32 +00:00
|
|
|
|
2017-02-28 17:20:41 +00:00
|
|
|
*** Building against several configurations at once
|
2016-12-02 13:54:32 +00:00
|
|
|
|
2017-02-28 17:20:41 +00:00
|
|
|
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.
|
2016-12-02 13:54:32 +00:00
|
|
|
|
2017-02-28 17:20:41 +00:00
|
|
|
This feature should make cross-compilation easy, see details in the
|
|
|
|
[[ROADMAP.org][roadmap]].
|
2016-12-02 13:54:32 +00:00
|
|
|
|
2017-02-28 17:20:41 +00:00
|
|
|
This feature requires [[https://opam.ocaml.org/][opam]].
|
2016-12-02 13:54:32 +00:00
|
|
|
|
2017-02-28 17:20:41 +00:00
|
|
|
*** Jenga bridge
|
2016-12-02 13:54:32 +00:00
|
|
|
|
2017-02-28 17:20:41 +00:00
|
|
|
[[https://github.com/janestreet/jenga][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 as much 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.
|
2016-12-02 13:54:32 +00:00
|
|
|
|
2017-04-21 16:34:34 +00:00
|
|
|
** Requirements
|
|
|
|
|
|
|
|
Jbuilder requires OCaml version 4.02.3 or greater.
|
|
|
|
|
|
|
|
** Installation
|
|
|
|
|
|
|
|
The recommended way to install jbuilder is via the [[https://opam.ocaml.org][opam package manager]]:
|
|
|
|
|
|
|
|
#+begin_src sh
|
|
|
|
$ opam install jbuilder
|
|
|
|
#+end_src
|
|
|
|
|
|
|
|
You can also build it manually with:
|
|
|
|
|
|
|
|
#+begin_src sh
|
|
|
|
$ make
|
|
|
|
$ make install
|
|
|
|
#+end_src
|
|
|
|
|
|
|
|
Note however that =make install= requires the =opam-installer= tool.
|
|
|
|
|
|
|
|
If you do not have =make=, you can do the following:
|
|
|
|
|
|
|
|
#+begin_src sh
|
|
|
|
$ ocaml bootstrap.ml
|
|
|
|
$ ./boot.exe
|
|
|
|
$ ./_build/default/bin/main.exe install
|
|
|
|
#+end_src
|
|
|
|
|
|
|
|
** Support
|
|
|
|
|
|
|
|
If you have questions about jbuilder, you can send an email to
|
|
|
|
ocaml-core@googlegroups.com or [[https://github.com/janestreet/jbuilder/issues][open a ticket on github]].
|
|
|
|
|
2017-02-28 17:20:41 +00:00
|
|
|
** Status
|
2016-12-02 13:54:32 +00:00
|
|
|
|
2017-03-10 12:43:38 +00:00
|
|
|
Jbuilder is now in beta testing stage. Once a bit more testing has
|
|
|
|
been done, it will be released in 1.0.
|
2016-12-02 13:54:32 +00:00
|
|
|
|
|
|
|
** Roadmap
|
|
|
|
|
2017-02-22 15:25:34 +00:00
|
|
|
See [[ROADMAP.org]] for the current plan. Help on any of these points is
|
|
|
|
welcome!
|
2017-02-28 17:20:41 +00:00
|
|
|
|
2017-03-21 14:37:35 +00:00
|
|
|
** FAQ
|
|
|
|
|
|
|
|
*** Why do many Jbuilder projects contain a Makefile?
|
|
|
|
|
|
|
|
Many Jbuilder project contain a toplevel =Makefile=. It is often only
|
|
|
|
there only 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
|
2017-03-28 00:05:59 +00:00
|
|
|
true invocation you know is =make && make install=, possibly
|
2017-03-21 14:37:35 +00:00
|
|
|
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=
|
|
|
|
|
2017-03-21 15:56:31 +00:00
|
|
|
*** How to add a configure step to a jbuilder project?
|
|
|
|
|
|
|
|
[[example/sample-projects/with-configure-step]] shows one way to do it
|
2017-03-28 00:05:59 +00:00
|
|
|
that preserves composability; i.e. it doesn't require to manually run
|
2017-03-21 15:56:31 +00:00
|
|
|
all =./configure= script when working on multiple projects at the same
|
|
|
|
time.
|
|
|
|
|
2017-04-05 11:50:56 +00:00
|
|
|
** Known bugs
|
|
|
|
|
|
|
|
*** Optional libraries inside a multilib directory
|
|
|
|
|
|
|
|
[[https://github.com/janestreet/jbuilder/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.
|
|
|
|
|
2017-02-28 17:20:41 +00:00
|
|
|
** 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.
|
|
|
|
|
|
|
|
*** OCaml compatibility test
|
|
|
|
|
|
|
|
Install opam switches for all the entries in the [[jbuild-workspace.dev]]
|
|
|
|
file and run:
|
|
|
|
|
|
|
|
#+begin_src sh
|
|
|
|
$ make all-supported-ocaml-versions
|
|
|
|
#+end_src
|
|
|
|
|
|
|
|
*** 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
|
2017-03-28 00:05:59 +00:00
|
|
|
report the external dependencies necessary to build a given set of
|
2017-02-28 17:20:41 +00:00
|
|
|
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][src/build]]. In the end it makes the development
|
|
|
|
of the internal rules of Jbuilder very composable and quite pleasant.
|
|
|
|
|
2017-03-28 00:05:59 +00:00
|
|
|
To deal with process multiplexing, Jbuilder uses a simplified
|
|
|
|
Lwt/Async-like monad, implemented in [[src/future.mli][src/future]].
|
2017-02-28 17:20:41 +00:00
|
|
|
|
|
|
|
**** Code flow
|
|
|
|
|
|
|
|
- [[src/jbuild_types.ml][src/jbuild_types]] contains the internal representation of =jbuild=
|
|
|
|
files and the parsing code
|
|
|
|
- [[src/jbuild_load.ml][src/jbuild_load]] contains the code to scan a source tree and build
|
|
|
|
the internal database by reading the =jbuild= files
|
|
|
|
- [[src/gen_rules.ml][src/gen_rules]] contains all the build rules of Jbuilder
|
|
|
|
- [[src/build_system.ml][src/build_system]] contains a trivial implementation of a Build
|
|
|
|
system. This is what Jenga will provide when implementing the bridge
|