The OBazl Book Last updated Mar 31, 2025

This site documents the OBazl toolsuite, version 3.0.0.beta.1

This documentation is a Work-In-Progress. Things will be a little messy and incomplete. The best way to learn how to use the rules is probably to find some relevant demos.

Getting started

The easiest way to get started is to fork/clone one of the demo projects, but you can also use the @obazl//new tool to generate a project from a template.

Demo projects

The demo projects use the xdg opam toolchain strategy (explained in tools-opam); this means the initial build will create an opam root and switch in $XDG_DATA_HOME. This only happens once, and xdg toolchains are shared by all OBazl projects. So the initial build may take a while; thereafter builds should be reasonably fast.
demo_hello
$ git clone https://github.com/obazl/demo_hello.git
$ cd demo_hello
$ bazel run bin:greetings
$ bazel run bin:greetings --tc=ocamlc              (0)
$ bazel test test
$ bazel run @opam                                  (1)
$ bazel clean                                      (2)
$ bazel build //...                                (3)
$ bazel test //...                                 (4)
$ bazel test //... --build_tests_only              (5)

$ bazel build lib/hello:Hello --config=modinfo     (6)
$ bazel build lib/hello:Hello --config=modinfo --tc=ocamlc
$ bazel build lib/hello:Hello --config=siginfo     (7)
$ bazel build lib/hello:Hello --config=cmtinfo     (8)
$ bazel build lib/hello:Hello --config=cmtiinfo    (9)
$ bazel build lib/goodbye:Goodbye --config=gensig  (10)

$ bazel run @ocaml
$ bazel run @utop
$ bazel run @dbg --pgm=bin:greetings               (11)

$ dune build                                       (12)
$ dune run bin/main.exe                            (13)
$ dune test
1 Uses ocamlc.opt compiler. --tc=<compiler> can be used with all cmds here.
2 Runs opam; shows location of switch.
3 Forces rebuild. Rarely needed in practice.
4 Builds all targets
5 Builds all targets and runs all tests
6 Runs all tests but only builds targets required by the tests
7 Runs ocamlobjinfo against hello.cmx (see .bazelrc)
8 Runs ocamlobjinfo against hello.cmi (see .bazelrc)
9 Runs ocamlcmt against hello.cmt (see .bazelrc)
10 Runs ocamlcmt against hello.cmti (see .bazelrc)
11 Generate interface for goodbye.ml (ocamlc -i) (see .bazelrc)
12 Runs ocamldebug. See .bazelrc
13 Dune and Bazel play nice together.
14 Dune requires that the executable name match a module name.

Other demos:

@obazl//new: generating a new project

Generate a new project
$ mkdir obazl && cd obazl
$ cat > .bazelrc <<EOF
common --registry=https://raw.githubusercontent.com/obazl/registry/main/
common --registry=https://bcr.bazel.build
EOF
$ cat > MODULE.bazel <<EOF
module(name="myproj")
bazel_dep(name = "tools_obazl", version = "3.0.0.beta.1", repo_name = "obazl")
EOF
$ bazel run @obazl//new -- --help
$ bazel run @obazl//new -- --list
Templates available from library @templates_ocaml
	ffi/ctypes
		Minimal project using ctypes library
        ...
	proj/hello
		Minimal working example
...
$ bazel run @obazl//new -- -t proj/hello -n howdy
$ cd howdy
$ bazel build //... --show_result=10            (1)
$ bazel test //... --show_result=10
1 Builds all targets. --show_result is optional; it tells OBazl to tell print information about build outputs, which is not printed by default.

Support

Acknowledgements

Support for the development of OBazl was provided by a Mina Genesis Token Grant and the generous assistance of the Mina team. Additional support provided by Tweag