rules_rust

repository·main·Indexed 21 days ago

https://github.com/bazelbuild/rules_rust

Bazel rules for building Rust projects, providing integration of the Rust toolchain into Bazel build pipelines. Includes crate_universe for generating Bazel build targets from Cargo, support for vendoring dependencies via crates_vendor, cross-compilation with LLVM and sysroots, and tools for managing target-specific compiler optimizations.

Tokens
22.6K
Snippets
72
Records
108
Agent score
73%

What's inside rules_rust

  1. Available Rust rules in rules_rust

    main

    The rules_rust repository provides a comprehensive suite of rules for managing Rust development within Bazel. These are categorized into standard build rules, toolchain/linting rules, Cargo compatibility, and 3rd party integrations.

    Standard Rules

    • Standard Build Rules: Use defs.md for rules to build and test libraries and binaries.
    • Documentation: Use rust_doc.md for generating and testing Rust documentation.
    • Linting & Formatting: Use rust_clippy.md for running clippy and rust_fmt.md for running rustfmt.
    • Cargo Compatibility: Use cargo.md for rules dedicated to Cargo compatibility, such as handling build.rs scripts.
    • External Dependencies: Use crate_universe.md for rules that generate Bazel targets for external crate dependencies.

    Experimental Rules

    • IDE Support: Use rust_analyzer.md to generate rust-project.json files for rust-analyzer support.

    3rd Party Rules

    • C++ Bindings: Use rust_bindgen.md for generating C++ bindings.
    • Protobuf/gRPC: Use rust_prost.md for generating Protobuf and gRPC stubs using prost.
    • Python Bindings: Use rust_pyo3.md for PyO3 integration.
    • WebAssembly: Use rust_wasm_bindgen.md for generating WebAssembly bindings.
  2. Use Rust Bindgen Rules to generate Rust bindings for C/C++

    main

    The rust_bindgen rules allow you to use bindgen to automatically generate Rust bindings for C and some C++ libraries within a Bazel workspace. This is useful for interfacing Rust code with existing C/C++ dependencies.

    For detailed documentation and advanced configuration, refer to the official rules_rust documentation: https://bazelbuild.github.io/rules_rust/rust_bindgen.html

  3. How coverage works with `rust_test` and the `crate` attribute

    main

    When a rust_test target uses the crate attribute, the library source code is compiled directly into the test binary. In this mode, Rules Rust automatically determines if the underlying crate should be instrumented. This means library code compiled into the test binary will produce coverage data automatically, without requiring the --instrument_test_targets flag.

    Note: Because the entire crate (including #[cfg(test)] code) is compiled as a single unit, test-specific code within the crate will also be instrumented. This differs from the standard Bazel convention where test code is typically only instrumented when --instrument_test_targets is explicitly set.

  4. How workspace splitting works in rust-analyzer setup

    main

    By default, rules_rust treats the entire project as a single workspace. For large monorepos where indexing the whole graph is too slow, you can use per-package workspaces.

    Using per-package workspaces: Run setup with the --per-package-workspaces flag. This scopes discovery to the saved file's package and its dependencies. rust-analyzer will reload when you jump to a different package.

    Caveat: Because it is scoped, _dependents_ of the package you are currently working on are not indexed. This means "find usages" might miss callers located in other packages.

    To switch back to a single workspace, re-run setup without the flag.

  5. Identify stable `rules_rust` APIs

    main

    To ensure your build remains stable across rules_rust updates, only rely on APIs explicitly covered by the backwards compatibility policy.

    Stable APIs:

    • //rust (anything directly accessible from this file)
    • //cargo
    • Incompatible build settings (the behavior of a flag cannot change in a backwards incompatible way).

    Unstable/Private APIs (Not guaranteed to be stable):

    • Any path containing private/ (e.g., //**/private/...)
    • All starlark symbols and targets not explicitly mentioned as stable.
    • //crate_universe, //examples, //extensions, //ffi, //nix, //test, //tools, and //util.
    • Experimental build settings.
    • Any package not explicitly listed as stable in the compatibility policy.
  6. Configure a custom Prost toolchain

    main

    Because Prost requires specific toolchain definitions to avoid dependency mismatches, you should define a custom toolchain. It is recommended to place this in a dedicated directory like tools/prost_toolchain/BUILD.bazel.

    The toolchain definition requires:

    • rust_library_group for prost_runtime and tonic_runtime.
    • rust_prost_toolchain to link the plugins (protoc-gen-prost, protoc-gen-tonic), the proto compiler, and the runtimes.
    • A toolchain rule that maps the implementation to the @rules_rust_prost//:toolchain_type.
    load("@rules_rust_prost//:defs.bzl", "rust_prost_toolchain")
    load("@rules_rust//rust:defs.bzl", "rust_library_group")
    
    rust_library_group(
        name = "prost_runtime",
        deps = ["@crates//prost"],
    )
    
    rust_library_group(
        name = "tonic_runtime",
        deps = [
            ":prost_runtime",
            "@crates//tonic",
        ],
    )
    
    rust_prost_toolchain(
        name = "prost_toolchain_impl",
        prost_plugin = "@crates//protoc-gen-prost__protoc-gen-prost",
        prost_runtime = ":prost_runtime",
        prost_types = "@crates//prost-types",
        proto_compiler = "@protobuf//:protoc",
        tonic_plugin = "@crates//protoc-gen-tonic__protoc-gen-tonic",
        tonic_runtime = ":tonic_runtime",
    )
    
    toolchain(
        name = "prost_toolchain",
        toolchain = "prost_toolchain_impl",
        toolchain_type = "@rules_rust_prost//:toolchain_type",
    )
  7. Control Rust instrumentation with `--instrumentation_filter`

    main

    Rules Rust respects Bazel's standard --instrumentation_filter flag. Only targets whose labels match the provided regex are compiled with -Cinstrument-coverage. This allows you to include or exclude specific parts of your workspace from the instrumentation process.

    # Restrict instrumentation to workspace targets (recommended for vendored deps)
    coverage --instrumentation_filter=^//
    
    # Include workspace targets but exclude third_party
    coverage --instrumentation_filter=^//,-^//third_party
  8. Understand `rules_rust` versioning and compatibility

    main

    The project follows SemVer 2.0.0.

    • Minor and Patch releases: Guaranteed to contain only backwards compatible changes.
    • Backwards Compatible Change: A change where a build that was green, correct, and using stable APIs/supported Bazel versions remains green and correct without requiring modifications to your project source, BUILD files, bzl files, rust_toolchain definitions, platform definitions, or build settings.
    • Pre-1.0 Versions: All minor version releases before version 1.0 may be backwards incompatible (though they must still follow the migration process, with a reduced 2-week migration window).
    • HEAD vs. Releases: There are no compatibility guarantees between a released version and the rules_rust state at HEAD.