common --registry=https://raw.githubusercontent.com/obazl/registry/main/ common --registry=https://bcr.bazel.build
Development environment and workflow Last updated Feb 11, 2025
Currently, released versions of OBazl rules and tools are registered in the OBazl registry. Eventually they will be migrated to the Bazel Central Registry, but in the meantime, to use them you must put the following in a bazelrc file:
However, code under development is not published to any registry and
so cannot be accessed via the bzlmod
package management system. But
OBazl is open-source and development is public, so you are welcome to
fork a repository and offer contributions or just eavesdrop.
To use unreleased versions of a module (whether rules_ocaml
or one
of the other OBazl modules) you must use one of the following methods:
-
Create a local registry with
source.json
files of typegit_repository
-
Use the
git_override
method in yourMODULE.bazel
file, specifying the branch you want; or -
Fork/clone the repo to your local drive, and then use either
-
local_path_override
in yourMODULE.bazel
file, or -
--override_module
option on the command line or in a bazelrc file.
-
Even if you use one of these methods, you must nonetheless
always use the --registry directives as shown above. This is because
the module may itself depend on resources only accessible
in those registries.
|
I develop primarily on a Mac (arm) and test on Linux (Ubuntu, x86).
The next section describes the configuration I use for development using these techniques.
Local registry
This is the easiest and most flexible method.
Summary: create a local registry
, whose records will point either to local copies of repos or to
commits in a git service. Then use --registry=…
to use this local
registry, and you will pick any changes to local repos automatically.
With this method you avoid cluttering your MODULE.bazel
files with
override code that will have to be deleted eventually anyway, and you
don’t need to keep track of which modules have overrides and which
don’t.
Another advantage of this approach is that it facilitates sharing a
configuration across hosts, so that modules under development can be
tested without publishing to a registry. Each developer on each host
maintains a copy of the local registry, and can update the
source.json
files as needed.
Registries are very simple. A local registry looks like this:
. ├── bazel_registry.json (1) ├── modules │ ├── module_a │ ├── module_b . . .
1 | Contents: { "module_base_path": "../../" } |
An individual module record looks like this:
module_a └── 1.0.0.dev ├── MODULE.bazel -> /path/to/local/module_a/MODULE.bazel └── source.json
Pretty simple. The source.json
file will have one of the following two forms:
{ "type": "local_path", "path": "relpath/to/module_a" } (1)
1 | path will be interpreted relative to the module_base_path set
in the bazel_registry.json file as noted above. |
{ "type": "git_repository", "remote": "git@github.com:<user>/module_a.git", "commit": "bb43b97e95b7e02b120c43373e52e3e86d065230", }
Use a local source record until your code is stable enough for testing
or sharing on other platforms. Then create and push a commit, and
switch the registry record to use the remote source format. Repeat,
updating the commit
field of the registry record, until ready to
publish.
With this method you do not need to cut a release or prerelease archive, or publish to a shared bzlmod registry, in order to share code under development. Instead you “distribute” a local registry (which can itself be put under version control).
POLICY always use "dev ids" for code under development. OBazl
convention is to use <version>.dev for both the module Id and the
branch name. Such Ids are never used for published versions, so it is
easy to keep track of what has been published (e.g. when viewing the
output of ‘bazel mod graph`).
|
Using dev versions of the repos
I use the following branches:
-
<version>.dev
is where active development takes place. Unstable.
For example, to depend directly on the 5.0.0.dev
branch of the
rules_ocaml
repo:
bazel_dep(name = "rules_ocaml", version = "5.0.0") git_override(module_name = "rules_ocaml", branch = "5.0.0.dev", (1) remote = "https://github.com/obazl/rules_ocaml.git")
1 | You can depend on whichever branch you prefer. |
The override tells Bazel to use the head commit of the named branch.
Since that may change, if you use this method, you will need to run
bazel clean --expunge
in order to pick up any new commits on the
branch you are using.
Alternatively, you can fork the rules_ocaml
repo and clone it to
your local machine (for example, to /home/<uid>/obazl/rules_ocaml
),
and then use either local_path_override
in your MODULE.bazel
or
--override_module
in .bazelrc
.
For example:
bazel_dep(name = "rules_ocaml", version = "5.0.0") local_path_override(module_name = "rules_ocaml", path="/home/<uid>/obazl/rules_ocaml")
or you can omit the local_path_override
directive and instead do this:
common --override_module=rules_ocaml=/home/<uid>/obazl/rules_ocaml
If you use this method, you will of course need to sync your fork with the upstream repo in order to pick up any new commits.
Be sure to check out the branch of interest after cloning!
When you use overrides like this, version compatibility checks are
disabled - you get whatever you ask for. This is especially important
if you are working with multiple modules with interdependencies. For
example, tools_opam and rules_ocaml - the former depends on the
latter. If you override both of them to point to local copies, it’s up
to you to make sure the local copies are correctly configured.
|
bazelrc
See Write bazelrc configuration files for more information.
You home bazelrc file is the place to specify configurations you use across multiple Bazel projects. Mine contains:
common --symlink_prefix=.bazel/ common --color=yes common:show --subcommands=True common:show --verbose_failures common:showpp --subcommands=pretty_print common:showpp --verbose_failures test:showt --test_output=all test:showt --keep_going common:q --noshow_progress common:q --noshow_loading_progress common:q --show_result=99 ## ui events: fatal, error, warning, info, progress, debug, ## start, finish, subcommand, stdout, stderr, pass, fail, ## timeout, cancelled or depchecker common:q --ui_event_filters=-info common:q --ui_event_filters=-progress common:q --ui_event_filters=-subcommand common:q --ui_event_filters=-fail # common:q --ui_event_filters=-error # common:q --ui_event_filters=-stdout # common:q --ui_event_filters=-stderr
The show*
configuration groups (see
--config) make it easy to
toggle verbosity for particular build commands, e.g.
$ bazel build mwe/hello:Hello --config=showpp
By default, bazel test
will only print the pass/fail result of
tests, and will stop at the first failure. Passing --config=showt
tells bazel to print a little more information for each test,
including anything written to stdout
, and to keep going even when
tests fail.
The q
(quiet) config group suppresses all Bazel messages except
those written to stdout
and stderr
.
For example, if you run $ bazel build mwe/...
(NB: three dots)
then Bazel will build all the targets in the mwe
package, but it
will only print summary information such as
INFO: Analyzed 55 targets (0 packages loaded, 0 targets configured). INFO: Found 55 targets... INFO: Elapsed time: 0.072s, Critical Path: 0.00s INFO: 1 process: 1 internal. INFO: Build completed successfully, 1 total action
Passing --config=q
sets --show_result=99
, which tells Bazel to
print information about output files. So $ bazel build mwe/...
--config=q
will print information about each target:
$ bazel build mwe/... --config=q Target //mwe/hello_library:hello.exe up-to-date: .bazel/bin/mwe/hello_library/hello.exe Target //mwe/hello_ns_archive:test up-to-date: .bazel/bin/mwe/hello_ns_archive/test Target //mwe/hello_ns_library:libHello up-to-date: .bazel/out/darwin_arm64-fastbuild-ST-e73fda9ac620/bin/mwe/hello_ns_library/__obazl/LibHello__Easy.cmx .bazel/out/darwin_arm64-fastbuild-ST-e73fda9ac620/bin/mwe/hello_ns_library/__obazl/LibHello__Simple.cmx Target //mwe/hello_library:Easy up-to-date: .bazel/bin/mwe/hello_library/__obazl/Easy.cmx ...