bazelbuild / rules_rust

Rust rules for Bazel
https://bazelbuild.github.io/rules_rust/
Apache License 2.0
654 stars 413 forks source link

crates_vendor produces a defs.bzl file that fails when included as part of a bzlmod submodule #2661

Open tel opened 4 months ago

tel commented 4 months ago

When generating a crates universe using crates_vendor a defs.bzl file is created to define all of the downloaded http_archive targets. Here's an example target that's generated.

maybe(
    http_archive,
    name = "vendor__once_cell-1.19.0",
    sha256 = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92",
    type = "tar.gz",
    urls = ["https://static.crates.io/crates/once_cell/1.19.0/download"],
    strip_prefix = "once_cell-1.19.0",
    build_file = Label("@//third-party/bazel:BUILD.once_cell-1.19.0.bazel"),
)

This works fine as long as the path @//third-party/bazel is correct. This path becomes incorrect, however, if the module that makes use of this crates_vendor target happens to get included via bzlmod. Now, the absolute path @// is unknown from within the included module.

In the top-level module, this leads to the creation of an unparseable MODULE.bazel.lock file which includes labels like

"vendor__windows_x86_64_msvc-0.52.5": {
  "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl",
  "ruleClassName": "http_archive",
  "attributes": {
    "sha256": "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0",
    "type": "tar.gz",
    "urls": [
      "https://static.crates.io/crates/windows_x86_64_msvc/0.52.5/download"
    ],
    "strip_prefix": "windows_x86_64_msvc-0.52.5",
    "build_file": "@@[unknown repo '' requested from @@cxx.rs~]//third-party/bazel:BUILD.windows_x86_64_msvc-0.52.5.bazel"
  }
},

The fix is simple, if manual, we can replace those labels in the defs.bzl file with ones that reference the local top-level repo, i.e. replace the @// with // instead. However, it's unclear if this is correct. Why are these @// paths being generated? Is it valid to make this substitution?

Here's a quick reproduction of the error.

https://github.com/tel/cxx_bzlmod_repro

AmeliasCode commented 2 months ago

That file is generated by this template: https://github.com/bazelbuild/rules_rust/blob/a5fd6951c9eaaaf9569ec3fb7b058fd94af6bff5/crate_universe/src/rendering/templates/vendor_module.j2#L26

This uses the crates_module_label function defined here: https://github.com/bazelbuild/rules_rust/blob/a5fd6951c9eaaaf9569ec3fb7b058fd94af6bff5/crate_universe/src/rendering/template_engine.rs#L96-L98

This uses the crates_module_template to determine the output. That is defined here: https://github.com/bazelbuild/rules_rust/blob/a5fd6951c9eaaaf9569ec3fb7b058fd94af6bff5/crate_universe/private/crates_vendor.bzl#L221

@UebelAndre would simply updating that line be enough? Label() should give the absolute path to the object as seen from crates_vendor.bzl, so @ doesn't seem like it should be there?