Avoid double building `cargo_build_script.data` targets (#2826)

Before this change targets passed to `cargo_build_script.data` would get
built multiple times (once per configuration)
```
% bazel cquery 'filter(//test/cargo_build_script/location_expansion:target_data.txt, deps(//test/cargo_build_script/location_expansion:build_rs))'
//test/cargo_build_script/location_expansion:target_data.txt (be33641)
//test/cargo_build_script/location_expansion:target_data.txt (a1c326f)
```
We can see that this is the exec (`a1c326f`) and target (`be33641`)
configurations.
```
% bazel config a1c326f be33641
INFO: Displaying diff between configs a1c326f and be33641
Displaying diff between configs a1c326f and be33641
FragmentOptions com.google.devtools.build.lib.analysis.PlatformOptions {
  platforms: [@@internal_platforms_do_not_use//host:host], [@@bazel_tools//tools:host_platform]
}
FragmentOptions com.google.devtools.build.lib.analysis.config.CoreOptions {
  compilation_mode: opt, fastbuild
  is exec configuration: true, false
  platform_suffix: exec, null
}
FragmentOptions com.google.devtools.build.lib.rules.android.AndroidConfiguration$Options {
  fat_apk_cpu: [], [armeabi-v7a]
}
FragmentOptions com.google.devtools.build.lib.rules.cpp.CppOptions {
  copt: [-g0], []
  cxxopt: [-g0], []
  strip: always, sometimes
}
FragmentOptions com.google.devtools.build.lib.rules.java.JavaOptions {
  java_runtime_version: remotejdk_11, local_jdk
  jvmopt: [-XX:ErrorFile=/dev/stderr], []
}
```

This is caused by `data` being passed to the underlying rust binary in
`cargo_build_script_wrapper.bzl`.

The fix for this ends up requiring some gymnastics as many existing uses
of `cargo_build_script` rely on `data` files being available within the
runfiles of `cargo_build_script.script`. This change accounts for that
by creating a wrapper rule for the build script that symlinks the
`cfg=exec` Rust binary (which is the actual [Cargo build
script](https://doc.rust-lang.org/cargo/reference/build-scripts.html))
and updating the `cargo_build_script` rule to consume it as
`cfg=target`. Within the `cargo_build_script` rule this means the script
target and it's `data` attribute files will be in `cfg=target` but the
binary itself will have been built for `cfg=exec` and will be runnable
on the exec platform.

We see after this change that data targets only appear once now
```
% bazel cquery 'filter(//test/cargo_build_script/location_expansion:target_data.txt, deps(//test/cargo_build_script/location_expansion:build_rs))'
//test/cargo_build_script/location_expansion:target_data.txt (be33641)
```
3 files changed
tree: 923778212b32b1be3d71b02b18db85d462637e59
  1. .bazelci/
  2. .bcr/
  3. .github/
  4. bindgen/
  5. cargo/
  6. crate_universe/
  7. docs/
  8. examples/
  9. ffi/
  10. nix/
  11. proto/
  12. rust/
  13. test/
  14. tools/
  15. util/
  16. wasm_bindgen/
  17. .bazelignore
  18. .bazelrc
  19. .clang-format
  20. .envrc
  21. .gitattributes
  22. .gitignore
  23. .prettierrc.toml
  24. .rustfmt.toml
  25. ARCHITECTURE.md
  26. AUTHORS
  27. BUILD.bazel
  28. buildifier
  29. CODEOWNERS
  30. COMPATIBILITY.md
  31. CONTRIBUTING.md
  32. CONTRIBUTORS
  33. LICENSE.txt
  34. MODULE.bazel
  35. README.md
  36. version.bzl
  37. WORKSPACE.bazel
README.md

Rust Rules

  • Postsubmit Build status

Overview

This repository provides rules for building Rust projects with Bazel.

Community

General discussions and announcements take place in the GitHub Discussions, but there are additional places where community members gather to discuss rules_rust.

Documentation

Please refer to the full documentation.