rules_rust

Crate Universe

Experimental!

Note: crate_universe is experimental, and may have breaking API changes at any time. These instructions may also change without notice.

What is it?

Crate Universe is akin to a modified version of cargo-raze that can be run as part of a Bazel build. Instead of generating BUILD files in advance with cargo-raze, the BUILD files can be created automatically at build time. It can expose crates gathered from Cargo.toml files like cargo-raze does, and also supports declaring crates directly in BUILD files, for cases where compatibility with Cargo is not required.

Workspace installation

To avoid having to build a Rust binary, pre-made releases are made available.

  1. Find the most up-to-date crate_universe release at https://github.com/bazelbuild/rules_rust/releases.
  2. Copy and paste the text into a file like crate_universe_defaults.bzl in your repo.
  3. Add something like the following to your WORKSPACE.bazel file:
load("//3rdparty/rules_rust:crate_universe_defaults.bzl", "DEFAULT_URL_TEMPLATE", "DEFAULT_SHA256_CHECKSUMS")

load("@rules_rust//crate_universe:defs.bzl", "crate", "crate_universe")

crate_universe(
    name = "crates",
    cargo_toml_files = [
        "//some_crate:Cargo.toml",
        "//some_other:Cargo.toml",
    ],
    resolver_download_url_template = DEFAULT_URL_TEMPLATE,
    resolver_sha256s = DEFAULT_SHA256_CHECKSUMS,
    # leave unset for default multi-platform support
    supported_targets = [
        "x86_64-apple-darwin",
        "x86_64-unknown-linux-gnu",
    ],
    # [package.metadata.raze.xxx] lines in Cargo.toml files are ignored;
    # the overrides need to be declared in the repo rule instead.
    overrides = {
        "example-sys": crate.override(
            extra_build_script_env_vars = {"PATH": "/usr/bin"},
        ),
    },
    # to use a lockfile, uncomment the following line,
    # create an empty file in the location, and then build
    # with REPIN=1 bazel build ...
    #lockfile = "//:crate_universe.lock",
)

load("@crates//:defs.bzl", "pinned_rust_install")

pinned_rust_install()

In the above example, two separate Cargo.toml files have been provided. Multiple Cargo.toml can be provided, and crate_universe will combine them together to ensure each crate uses a common version.

This is similar to a Cargo workspace, and can be used with an existing workspace. But some things to note:

Build file usage

With the crates declared in the workspace, they can now be referenced in BUILD files. For example:

load("@crates//:defs.bzl", "build_crates_from", "crates_from")

cargo_build_script(
    name = "build",
    srcs = ["build.rs"],
    deps = build_crates_from("//some_crate:Cargo.toml"),
)

rust_library(
    name = "some_crate",
    srcs = [
        "lib.rs",
    ],
    deps = crates_from("//some_crate:Cargo.toml") + [":build"]
)

If you prefer, you can also list out each crate individually, eg:

load("@crates//:defs.bzl", "crate")

rust_library(
    name = "some_crate",
    srcs = [
        "lib.rs",
    ],
    deps = [crate("serde"), crate("log"), ":build"]
)

See some more examples and the documentation below for more info.

crate_universe

crate_universe(name, cargo_toml_files, crate_registry_template, iso_date, lockfile, overrides,
               packages, repo_mapping, resolver, resolver_download_url_template, resolver_sha256s,
               rust_toolchain_repository_template, sha256s, supported_targets, version)

A rule for downloading Rust dependencies (crates).

WARNING: This rule experimental and subject to change without warning.

Environment Variables:

ATTRIBUTES

Name Description Type Mandatory Default
name A unique name for this repository. Name required  
cargo_toml_files A list of Cargo manifests (Cargo.toml files). List of labels optional []
crate_registry_template A template for where to download crates from for the default crate registry. This must contain {version} and {crate} templates. String optional “https://crates.io/api/v1/crates/{crate}/{version}/download”
iso_date The iso_date of cargo binary the resolver should use. Note: This can only be set if version is beta or nightly String optional ””
lockfile The path to a file which stores pinned information about the generated dependency graph. this target must be a file and will be updated by the repository rule when the REPIN environment variable is set. If this is not set, dependencies will be re-resolved more often, setting this allows caching resolves, but will error if the cache is stale. Label optional None
overrides Mapping of crate name to specification overrides. See crate.override for more details. Dictionary: String -> String optional {}
packages A list of crate specifications. See crate.spec for more details. List of strings optional []
repo_mapping A dictionary from local repository name to global repository name. This allows controls over workspace dependency resolution for dependencies of this repository.<p>For example, an entry "@foo": "@bar" declares that, for any time this repository depends on @foo (such as a dependency on @foo//some:target, it should actually resolve that dependency within globally-declared @bar (@bar//some:target). Dictionary: String -> String required  
resolver The label of a crate_universe resolver. Resolvers can be built using cargo_bootstrap_repository but if possible, it’s recommended to stick with downloading a resoler via resolver_download_url_template. Label optional None
resolver_download_url_template URL template from which to download the resolver binary. {host_triple} and {extension} will be filled in according to the host platform. String optional “{host_triple}{extension}”
resolver_sha256s Dictionary of host_triple -> sha256 for resolver binary. Dictionary: String -> String optional {“aarch64-apple-darwin”: “{aarch64-apple-darwin–sha256}”, “aarch64-unknown-linux-gnu”: “{aarch64-unknown-linux-gnu–sha256}”, “x86_64-apple-darwin”: “{x86_64-apple-darwin–sha256}”, “x86_64-pc-windows-gnu”: “{x86_64-pc-windows-gnu–sha256}”, “x86_64-unknown-linux-gnu”: “{x86_64-unknown-linux-gnu–sha256}”}
rust_toolchain_repository_template The template to use for finding the host rust_toolchain repository. {version} (eg. ‘1.53.0’), {triple} (eg. ‘x86_64-unknown-linux-gnu’), {system} (eg. ‘darwin’), and {arch} (eg. ‘aarch64’) will be replaced in the string if present. String optional “rust_{system}_{arch}”
sha256s The sha256 checksum of the desired rust artifacts Dictionary: String -> String optional {}
supported_targets A list of supported platform triples to consider when resoliving dependencies. List of strings optional [“aarch64-apple-darwin”, “aarch64-unknown-linux-gnu”, “x86_64-apple-darwin”, “x86_64-pc-windows-msvc”, “x86_64-unknown-freebsd”, “x86_64-unknown-linux-gnu”]
version The version of cargo the resolver should use String optional “1.55.0”

crate.spec

crate.spec(name, semver, features)

A simple crate definition for use in the crate_universe rule.

WARNING: This rule experimental and subject to change without warning.

Example:

load("@rules_rust//crate_universe:defs.bzl", "crate_universe", "crate")

crate_universe(
    name = "spec_example",
    packages = [
        crate.spec(
            name = "lazy_static",
            semver = "=1.4",
        ),
    ],
)

PARAMETERS

Name Description Default Value
name The name of the crate as it would appear in a crate registry. none
semver The desired version (semver) of the crate none
features A list of desired features. None

crate.override

crate.override(extra_bazel_data_deps, extra_bazel_deps, extra_build_script_bazel_data_deps,
               extra_build_script_bazel_deps, extra_build_script_env_vars, extra_rustc_env_vars,
               features_to_remove)

A map of overrides for a particular crate

WARNING: This rule experimental and subject to change without warning.

Example:

load("@rules_rust//crate_universe:defs.bzl", "crate_universe", "crate")

crate_universe(
    name = "override_example",
    # [...]
    overrides = {
        "tokio": crate.override(
            extra_rustc_env_vars = {
                "MY_ENV_VAR": "MY_ENV_VALUE",
            },
            extra_build_script_env_vars = {
                "MY_BUILD_SCRIPT_ENV_VAR": "MY_ENV_VALUE",
            },
            extra_bazel_deps = {
                # Extra dependencies are per target. They are additive.
                "cfg(unix)": ["@somerepo//:foo"],  # cfg() predicate.
                "x86_64-apple-darwin": ["@somerepo//:bar"],  # Specific triple.
                "cfg(all())": ["@somerepo//:baz"],  # Applies to all targets ("regular dependency").
            },
            extra_build_script_bazel_deps = {
                # Extra dependencies are per target. They are additive.
                "cfg(unix)": ["@buildscriptdep//:foo"],
                "x86_64-apple-darwin": ["@buildscriptdep//:bar"],
                "cfg(all())": ["@buildscriptdep//:baz"],
            },
            extra_bazel_data_deps = {
                # ...
            },
            extra_build_script_bazel_data_deps = {
                # ...
            },
        ),
    },
)

PARAMETERS

Name Description Default Value
extra_bazel_data_deps Targets to add to the data attribute of the generated target (eg: rust_library.data). None
extra_bazel_deps Targets to add to the deps attribute of the generated target (eg: rust_library.deps). None
extra_build_script_bazel_data_deps Targets to add to the data attribute of the generated cargo_build_script target. None
extra_build_script_bazel_deps Targets to add to the deps attribute of the generated cargo_build_script target. None
extra_build_script_env_vars Environment variables to add to the build_script_env attribute of the generated cargo_build_script target. None
extra_rustc_env_vars Environment variables to add to the rustc_env attribute for the generated target (eg: rust_library.rustc_env). None
features_to_remove A list of features to remove from a generated target. []