A collection of OCaml, ReasonML, and BuckleScript rules and tools for Bazel.
Note: this is alpha software! I'm building it to properly integrate a ReasonML application into a bigger project that builds with Bazel.
This projet relies on two prerequisites:
nix
, the purely functional package manager, which is used for installing the ReasonML tooling (refmt
specifically),opam
,yarn
andnode
in an hermetic-ish fashion. At least you don't need to handle those yourself :)bazel
, naturally.
If you just cloned this repo and you have both those tools installed, feel free
to start with a bazel build //...
to get everything warmed up.
The examples works a separate workspace so you will need to run bazel build //...
there as well if you wish to play around with them.
WARNING: because this rules handle all of their dependencies hermetically, a clean install takes a good ~10 minutes on an early 2015 Macbook Pro.
Contents
Begin by adding the following to your WORKSPACE
:
workspace(name = "retool")
###
### Reason Rules!
###
rules_reason_version = "f8b956b147bfcf22c90480e7ebea32e6769c1fe0" # HEAD
http_archive(
name = "com_github_ostera_rules_reason",
sha256 = "",
strip_prefix = "rules_reason-%s" % (rules_reason_version,),
urls = ["https://github.com/ostera/rules_reason/archive/%s.zip" % (rules_reason_version,)],
)
###
### Nix Repositories
###
load(
"@com_github_ostera_rules_reason//reason/repositories:nix.bzl",
"nix_repositories",
)
nix_repositories(
nix_sha256 = "28121f6eb3d6c5b4c1fc9f716953ce8b0a793b841d0e9de095977b3ade06f92d",
nix_version = "20a78f74f8ac70d1099ff0d214cd00b25820da03",
)
###
### Register Reason Toolchain
###
load(
"@com_github_ostera_rules_reason//reason:def.bzl",
"reason_register_toolchains",
)
reason_register_toolchains(
bs_sha256 = "db3f37eb27bc1653c3045e97adaa83e800dff55ce093d78ddfe85e85165e2125",
bs_version = "939ef1e1e874c80ff9df74b16dab1dbe2e2df289",
nixpkgs_revision = "d91a8a6ece07f5a6df82aa5dc02030d9c6724c27",
nixpkgs_sha256 = "0c5291bcf7d909cc4b18a24effef03f717d6374de377f91324725c646d494857",
)
################################################################################
#
# Declare dependencies
#
################################################################################
load(
"//3rdparty:load.bzl",
"declare_dependencies"
)
declare_dependencies()
Use reason_module
to compile a group of .re
and .rei
files into their
corresponding .ml
and .mli
counterparts.
Further consume these outputs with ocaml_module
, bs_module
,
ocaml_bytecode_binary
, or ocaml_native_binary
.
You can use bs_module
to turn any ML source target into Javascript, this
includes the outputs from a reason_module
rule too.
Unfortunately bsc
requires a bsconfig.json
file at the place where you call
it. This means that you need to have that file at the root of your project.
# BUILD file at //...
filegroup(
name = "bsconfig",
srcs = ["bsconfig.json"],
)
# BUILD file somewhere in your sources!
reason_module(
name = "srcs.re",
srcs = glob(["*.re"]),
)
bs_module(
name = "srcs.js",
config = ["//:bsconfig"],
srcs = [":srcs.re"],
deps = [":deps"],
)
You can use ocaml_native_binary
and ocaml_bytecode_binary
to compile your
ML sources into native or bytecode binaries, and yes you can use your
reason_module
targets as sources!
# BUILD file somewhere in your sources!
reason_module(
name = "srcs",
srcs = glob(["*.re"]),
)
ocaml_native_binary(
name = "native",
srcs = [":srcs"],
)
ocaml_bytecode_binary(
name = "bytecode",
srcs = [":srcs"],
)
In no particular order:
- DevFlow: Top-Level
- DevFlow: Dependencies
- DevFlow: Generating Merlin and pointing IDEs to the right places
- Rules:
*_test
- DevFlow: Auto-rebuild
- Rules:
node_binary
- < your suggestion here! >
This compiles down ReasonML code into a representation that is friendly for BuckleScript or the default Ocaml compiler.
Which one will it be compatible with is determined by how you write your ReasonML code.
Name | Type | Default value | ||
name | string | mandatory value | ||
A unique name for this rule. | ||||
srcs | string_list | mandatory value | ||
The sources of this library. The name of the sources will be preserved, and the outputs will replace the Other |
||||
toolchain | label |
|
||
The toolchain to use when building this rule. It should include both |
Example:
# //my_app/BUILD
load(
"@com_github_ostera_rules_reason//reason:def.bzl",
"reason_module",
)
reason_module(
name = "my_app",
srcs = glob(["*.re", "*.rei"])
visibility = ["//my_app:__subpackages__"],
)
Compile Ocaml code into Javascript.
Name | Type | Default value | ||
name | string | mandatory value | ||
A unique name for this rule. | ||||
config | label | mandatory value | ||
The The file must be located at the root of your WORKSPACE. Currently looking to work around this. |
||||
srcs | string_list | mandatory value | ||
The ML sources of this library. The name of the sources will be preserved, and the outputs will replace the Other |
||||
deps | label_list |
|
||
Dependencies of this library, must include BsModuleInfo providers. |
||||
toolchain | label |
|
||
The toolchain to use when building this rule. It should include both |
Example:
load(
"@com_github_ostera_rules_reason//reason:def.bzl",
"reason_module",
"bs_module"
)
reason_module(
name = "my_app",
srcs = glob(["*.re", "*.rei"]),
)
bs_module(
visibility = ["//examples/app:__subpackages__"],
name = "my_app.js",
config = "//:bs_config",
srcs = [ ":my_app" ],
deps = [ "//examples/some/dependency" ],
)
Compile ML code into bytecode or native binaries. For bytecode binaries it will copmile them including the runtime, rather than separately. This is something that I'd like to change in the future.
Name | Type | Default value | ||
name | string | mandatory value | ||
A unique name for this rule, used as the name of the output binary | ||||
srcs | string_list | mandatory value | ||
The ML sources of this library. | ||||
deps | label_list |
|
||
Dependencies of this library, must include ReasonModuleInfo providers. |
||||
toolchain | label |
|
||
The toolchain to use when building this rule. It should include both |
Example:
load(
"@com_github_ostera_rules_reason//reason:def.bzl",
"reason_module",
"ocaml_native_binary",
)
# BUILD file somewhere in your sources!
reason_module(
name = "srcs",
srcs = glob(["*.re"]),
)
# replace native with bytecode in the rule name and you get a bytecode binary
ocaml_native_binary(
name = "my_bin_name",
srcs = [":srcs"],
)
There is a ToolchainInfo that describes the fields required throughout the build rules to successfully compile from ReasonML down to Javascript.
Feel free to register your own toolchain or use the default toolchain that will be managed completely within Bazel.
Name | Type |
bsc | File |
The BuckleScript compiler file. | |
refmt | File |
The ReasonML Formatter file. | |
bs_stdlib | Filegroup |
A Filegroup with all the source and compiled files for the BuckleScript standard library that will be used for compiling Ocaml into Javascript | |
ocamlc | File |
The Ocaml bytecode compiler. | |
ocamlopt | File |
The Ocaml native compiler. | |
ocamldep | File |
The Ocaml dependency tool. | |
ocamlrun | File |
The Ocaml bytecode interpreter. | |
ocaml_stdlib | Filegroup |
A Filegroup with Ocaml standard library. |
There are 2 providers included, that will carry information for the different stages of the build process.
This provider is the output of the reason_module
rule, and it represents a
compilation unit from ReasonML to Ocaml.
Name | Type |
name | string |
The name of your the colletion of files | |
srcs | depset(File) |
A depset of all the ReasonML files that will be compiled to ML |
|
outs | depset(File) |
A depset of all the target ML files that will be generated |
This provider is the output of the bs_module
rule, and it represents a
compilation unit from Ocaml to Javascript.
Name | Type |
name | string |
The name of your the colletion of files | |
srcs | depset(File) |
A depset of all the Ocaml files that will be compiled to Javascript |
|
outs | depset(File) |
A depset of all the target ML and Js files that will be generated |
|
deps | depset(File) |
A depset of all the BuckleScript modules files that the srcs depend
on |
This provider is the output of the bs_module
rule, and it represents a
compilation unit from Ocaml to Javascript.
Name | Type |
name | string |
The name of your the colletion of files | |
srcs | depset(File) |
A depset of all the Ocaml files that will to be compiled. |
|
outs | depset(File) |
A depset of all the target binary files. |
|
deps | depset(File) |
A depset of all the Ocaml modules files that the srcs depend
on |
|
target | "native" | "bytecode" |
Whether this module is being compiled natively or as bytecode. |