ocaml ├── WORKSPACE.bazel ... ├── toolchain │ ├── adapters │ │ ├── linux │ │ │ └── BUILD.bazel │ │ └── macos │ │ └── BUILD.bazel │ ├── binding_constraints │ │ ├── linux │ │ │ └── BUILD.bazel │ │ └── macos │ │ └── BUILD.bazel │ └── platform_constraints │ ├── bazel │ │ └── BUILD.bazel │ ├── build │ │ └── BUILD.bazel │ └── target │ └── BUILD.bazel
toolchains Last updated June 30, 2022
Hosts:
-
bazelhost - where Bazel runs. Bazel vernacular: "host"
-
buildhost - where the build tools run. Bazel vernacular: "exec"
-
targethost - platform targeted by build tools. Bazel vernacular: "target"
toolchain modeling
-
binding constraints: a set of constraints that, when satisfied, bind a toolchain adapter to
ctx.toolchains[<toolchain type>]
. Toolchain binding contraints are expressed using the built-intoolchain
rule, by listingconstraint_values
defined by platform constraints. -
toolchain adapter: a rule (defined by the ruleset author) that models the OCaml toolchain expected by
rules_ocaml
. The attributes of the rule represent the elements of the toolchain (e.g. compiler). Developers use the toolchain adapter rule to "adapt" their particular toolchain to the OCaml toolchain model. E.g. by setting thecompiler
attribute to point to a compiler. -
platform constraints: a set of
constraint_setting
andconstraint_value
targets used by binding constraints and platform definitions. -
platform definition - collection of
constraint_values
that are set toTrue
when the platform definition is passed on the command line using--host_platform
or--platforms
.
Only the toolchain adapter rule (that is, the OCaml toolchain model)
is defined by rules_ocaml
. It’s up to the devloper to provide:
-
toolchain adapter targets that bind toolchain files to the toolchain model;
-
platform constraints and definitions
-
targets using the
toolchain
rule to express binding constraints
The OBazl toolsuite provides a tool that automatically generates all of this for OPAM toolchains. The generated code has the following structure:
For example:
-
@ocaml//toolchain/platform_constraints/target:target
is aconstraint_setting
with twoconstraint_value
s:-
@ocaml//toolchain/platform_constraints/target:local
-
@ocaml//toolchain/platform_constraints/target:vm
-
-
@ocaml//toolchain/binding_constraints/macos:macos_x86_64
is atoolchain
rule target:
toolchain(
name = "macos_x86_64", (1)
toolchain = "@ocaml//toolchain/adapters/macos:x86_64", (2)
toolchain_type = "@rules_ocaml//toolchain:type",
exec_compatible_with = [ (3)
"@platforms//os:macos",
"@platforms//cpu:x86_64",
],
target_compatible_with = [ (4)
"@platforms//os:macos",
"@platforms//cpu:x86_64",
],
visibility = ["//visibility:public"],
)
1 | In this case buildhost == targethost, so we need not list both in the name |
2 | This toolchain adapter will be selected if all the constraints are satisfied. |
3 | meaning, "the toolchain adapter listed in the toolchain attribute
may be selected to run on the buildhost ("exec") if these two
@platforms constraints are satisfied for the buildhost". |
4 | meaning, "the toolchain adapter listed in the toolchain attribute
may be selected (to run on the buildhost) if these two
@platforms constraints are satisfied for the target host". |
Constraints in the @platforms workspace are predefined by Bazel.
|
A cross-platform toolchain binding might look like this (toy example):
toolchain(
name = "macos_x86_64__macos_arm", (1)
toolchain = "@ocaml//toolchain/adapters/macos:x86_64__arm",
toolchain_type = "@rules_ocaml//toolchain:type",
exec_compatible_with = [ (2)
"@platforms//os:macos",
"@platforms//cpu:x86_64",
],
target_compatible_with = [ (3)
"@platforms//os:linux",
"@platforms//cpu:arm",
],
visibility = ["//visibility:public"],
)
1 | Naming convention: <buildhost>__<targethost> |
2 | Buildhost where tools run is macos on x86_64 |
3 | Target host is linux on arm |
The platform definitions are in @opam//tc/host/build
and
@opam//tc/host/target
.
For example:
platform(name = "macos_x86_64",
constraint_values = [
"@platforms//os:macos",
"@platforms//cpu:x86_64"
])