bazel_dep(name = "coswitch", version = "1.0.0")
User Guide: @coswitch
The OBazl rules for OCaml can be used with both system and local OPAM switches:
-
"system" switches are installed in the OPAM "root", which is usually
$HOME/.opam
. -
local switches are installed in the project directory, in a subdirectory usually named
_opam
. See OPAM Local Switches for more information.
Support for OPAM integration is provided by rule ocaml_import
, which
makes precompiled artifacts available to Bazel build actions. To
import an (installed) OPAM package, all that is needed is
-
a
MODULE.bazel
file in the package root directory, that defines the package as a Bazel module and lists its dependencies; -
a
BUILD.bazel
file containing anocaml_import
target that imports the files of the package; -
if the package contains subpackages, a
BUILD.bazel
file for each; and -
a record in a Bazel module registry to make the package accessible via the Bazel module dependency management system.
The @coswitch
module contains a @coswitch//new
target that
automatically generates these files and installs them locally.
Nothing is written to the OPAM switch. All generated files and directories are written to a dedicated directory in $XDG_DATA_HOME or in the .config/ subdirectory of the project (for local OPAM switches). Symlinks are used to expose files in the switch.
|
Installation
In MODULE.bazel
:
This module is not yet registered with the
Bazel Central Registry; until it is, put
the following in .bazelrc
:
common --enable_bzlmod common --registry=https://raw.githubusercontent.com/obazl/registry/main/ common --registry=https://bcr.bazel.build
Usage
The @coswitch
Bazel module provides the following bazel run
targets:
-
@coswitch//new
- generates an OBazl coswitch corresponding to the current switch, or a switch passed via-s
or--switch
.
The generated coswitch contains one Bazel module for each package in
the switch. Build target labels follow this schema: for packages,
@<pkg>//lib/<pkg>
; for segmented subpackages,
@<pkg>//lib/<seg1>/<seg2>
. For example:
-
yojson
⇒@yojson//lib/yojson
-
mtime.clock.os
⇒@mtime//lib/clock/os
Coswitches
Coswitch registries
bazel run @coswitch//new
generates a Bazel module registry for the
packages in the switch. For system switches it is located at
$XDG_DATA_HOME/obazl/registry/<switch>
Usually $XDG_DATA_HOME
is $HOME/.local
, so for example the registry for switch 5.1.0
would be at:
$HOME/.local/obazl/registry/5.1.0
For local switches, the registry is located at
<root>/.config/obazl/registry
; note that the switch name is omitted
from the path. So with a local opam switch, regardless of compiler
version, the registry would be at
<root>/.config/obazl/registry
Bazel registries contain a bazel_registry.json
file in the registry
root directory; for local registries like the coswitch registry, this
file controls resolution of module labels (like @yojson
) to
directories on the local file system. It will contain an entry like the following:
"module_base_path": "/path/to/coswitch/root"
The bazel_registry.json
file in non-local registries (such as the official
Bazel
Central Registry) will not contain a "module_base_path" entry,
because registry entries will contain information required to retrieve
the module source from the network.
Registry records
Each Bazel module must be registered by adding a registry record to a bzlmod registry. Such records have the form described by Index registry.
For coswitch registries: for example, the record for yojson
in shared coswitch
5.1.0~rc2
will have the following form:
<$HOME>/.local/share/obazl/registry/5.1.0~rc2/modules/yojson ├── 0.0.0 │ ├── MODULE.bazel │ └── source.json └── metadata.json
The same, in a local registry:
<projroot>/.config/obazl/registry/modules/yojson ├── 0.0.0 │ ├── MODULE.bazel │ └── source.json └── metadata.json
In both cases, source.json
will look like this:
{
"type": "local_path",
"path": "yojson"
}
Here local_path
tells Bazel that the source location is to be resolved by
appending the path
string to the module_base_path
field of the
bazel_registry.json
file in the registry root.
For non-local registries, the source.json
file will look like the following:
{ "url": "...", "integrity": "...", "strip_prefix": "...", }
Registering coswitch registries
Registries other than the
Bazel
Central Registry (a/k/a BCR) must be registered with Bazel to take effect; this
can be done by adding a --registry
directive to any bazelrc file; for example:
common --registry=<protocol>:///path/to/registry
OBazl modules (such as @coswitch
itself) have not yet been added to
the BCR; until they are, they can be used by adding the following to a
bazelrc file:
common --registry=https://raw.githubusercontent.com/obazl/registry/main/
OBazl convention is to register coswitch registries by adding something
like the following to <projroot>/.config/coswitch_registry.bazelrc
:
common --registry=file:///<home>/<uid>/.local/share/obazl/registry/5.1.0~rc2
and to load this by adding the following to <projroot>/.bazelrc
:
try-import .config/coswitch_registry.bazelrc
Finally, if you have used --registry
directives, you must also add the BCR:
common --registry=https://bcr.bazel.build
Module resolution
When Bazel encounters a bazel_dep
directive in a MODULE.bazel
file, it searches the registered repositories for the corresponding
registry record.
record for the yojson
package in switch 5.1.0
would be:
The --registry
directive
Once the registry has been generated, you must direct Bazel to use it for module lookups. The OBazl convention is to write the registry directive to <root>/.config/coswitch_registry.bazelrc
, and to add try-import .config/coswitch_registry.bazelrc
to the root .bazelrc
file. The @coswitch//new
command will overwrite .config/coswitch_registry.bazelrc
with the path to the generated registry. An example is:
common --registry=file:///<home>/<uid>/.local/share/obazl/registry/5.0.0