diff --git a/.bazelci/presubmit.yml b/.bazelci/presubmit.yml index 6ade36b543..7642ff7448 100644 --- a/.bazelci/presubmit.yml +++ b/.bazelci/presubmit.yml @@ -717,6 +717,14 @@ tasks: working_directory: examples/bzlmod/hello_world_no_cargo build_targets: - "//..." + bzlmod_override_targets: + name: Override Targets bzlmod + platform: ubuntu2004 + working_directory: examples/bzlmod/override_target + build_targets: + - "//..." + test_targets: + - "//..." compile_one_dependency: name: --compile_one_dependency flag platform: ubuntu2004 diff --git a/crate_universe/extension.bzl b/crate_universe/extension.bzl index d181309e3f..509401d5fb 100644 --- a/crate_universe/extension.bzl +++ b/crate_universe/extension.bzl @@ -296,6 +296,31 @@ def _crate_impl(module_ctx): if annotation_dict.pop("gen_all_binaries"): annotation_dict["gen_binaries"] = True annotation_dict["gen_build_script"] = _OPT_BOOL_VALUES[annotation_dict["gen_build_script"]] + + # Process the override targets for the annotation. + # In the non-bzlmod approach, this is given as a dict + # with the possible keys "`proc_macro`, `build_script`, `lib`, `bin`". + # With the tag-based approach used in Bzlmod, we run into an issue + # where there is no dict type that takes a string as a key and a Label as the value. + # To work around this, we split the override option into four, and reconstruct the + # dictionary here during processing + annotation_dict["override_targets"] = dict() + replacement = annotation_dict.pop("override_target_lib") + if replacement: + annotation_dict["override_targets"]["lib"] = str(replacement) + + replacement = annotation_dict.pop("override_target_proc_macro") + if replacement: + annotation_dict["override_targets"]["proc_macro"] = str(replacement) + + replacement = annotation_dict.pop("override_target_build_script") + if replacement: + annotation_dict["override_targets"]["build_script"] = str(replacement) + + replacement = annotation_dict.pop("override_target_bin") + if replacement: + annotation_dict["override_targets"]["bin"] = str(replacement) + annotation = _crate_universe_crate.annotation(**{ k: v for k, v in annotation_dict.items() @@ -483,6 +508,18 @@ _annotation = tag_class( shallow_since = attr.string( doc = "An optional timestamp used for crates originating from a git repository instead of a crate registry. This flag optimizes fetching the source code.", ), + override_target_lib = attr.label( + doc = "An optional alternate taget to use when something depends on this crate to allow the parent repo to provide its own version of this dependency.", + ), + override_target_proc_macro = attr.label( + doc = "An optional alternate taget to use when something depends on this crate to allow the parent repo to provide its own version of this dependency.", + ), + override_target_build_script = attr.label( + doc = "An optional alternate taget to use when something depends on this crate to allow the parent repo to provide its own version of this dependency.", + ), + override_target_bin = attr.label( + doc = "An optional alternate taget to use when something depends on this crate to allow the parent repo to provide its own version of this dependency.", + ), ), ) diff --git a/examples/bzlmod/override_target/.bazelrc b/examples/bzlmod/override_target/.bazelrc new file mode 100644 index 0000000000..f9d474e02f --- /dev/null +++ b/examples/bzlmod/override_target/.bazelrc @@ -0,0 +1,12 @@ +# Required on windows +common --enable_platform_specific_config +startup --windows_enable_symlinks +build:windows --enable_runfiles + +build --experimental_enable_bzlmod + +# This isn't currently the defaut in Bazel, but we enable it to test we'll be ready if/when it flips. +build --incompatible_disallow_empty_glob + +# Required for cargo_build_script support before Bazel 7 +build --incompatible_merge_fixed_and_default_shell_env diff --git a/examples/bzlmod/override_target/.gitignore b/examples/bzlmod/override_target/.gitignore new file mode 100644 index 0000000000..a6ef824c1f --- /dev/null +++ b/examples/bzlmod/override_target/.gitignore @@ -0,0 +1 @@ +/bazel-* diff --git a/examples/bzlmod/override_target/BUILD.bazel b/examples/bzlmod/override_target/BUILD.bazel new file mode 100644 index 0000000000..c6c4df667e --- /dev/null +++ b/examples/bzlmod/override_target/BUILD.bazel @@ -0,0 +1,23 @@ +load("@rules_rust//rust:defs.bzl", "rust_library", "rust_test") + +rust_library( + name = "override_targets_example", + srcs = glob(["src/*.rs"]), + edition = "2018", + deps = [ + "@override_test//:foo", + ], +) + +rust_library( + name = "foo", + srcs = ["foo.rs"], + edition = "2018", + visibility = ["//visibility:public"], +) + +rust_test( + name = "unit_test", + crate = ":override_targets_example", + edition = "2018", +) diff --git a/examples/bzlmod/override_target/Cargo.lock b/examples/bzlmod/override_target/Cargo.lock new file mode 100644 index 0000000000..a629a0898f --- /dev/null +++ b/examples/bzlmod/override_target/Cargo.lock @@ -0,0 +1,16 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "foo" +version = "0.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7dbb6acfeff1d490fba693a402456f76b344fea77a5e7cae43b5970c3332b8f" + +[[package]] +name = "override_targets" +version = "0.0.0" +dependencies = [ + "foo", +] diff --git a/examples/bzlmod/override_target/Cargo.toml b/examples/bzlmod/override_target/Cargo.toml new file mode 100644 index 0000000000..997c3f2bd0 --- /dev/null +++ b/examples/bzlmod/override_target/Cargo.toml @@ -0,0 +1,12 @@ +[workspace] +[package] +name = "override_targets" +version = "0.0.0" +edition = "2021" +publish = false + +[lib] +path = "/dev/null" + +[dependencies.foo] +version = "0.0.0" diff --git a/examples/bzlmod/override_target/MODULE.bazel b/examples/bzlmod/override_target/MODULE.bazel new file mode 100644 index 0000000000..06a5c6948b --- /dev/null +++ b/examples/bzlmod/override_target/MODULE.bazel @@ -0,0 +1,44 @@ +"""bazelbuild/rules_rust - bzlmod example""" + +module( + name = "override_target_example_with_bzlmod", + version = "0.0.0", +) + +bazel_dep(name = "platforms", version = "0.0.8") +bazel_dep( + name = "bazel_skylib", + version = "1.5.0", +) +bazel_dep( + name = "rules_rust", + version = "0.0.0", +) +local_path_override( + module_name = "rules_rust", + path = "../../..", +) + +rust = use_extension("@rules_rust//rust:extensions.bzl", "rust") +rust.toolchain(edition = "2021") +use_repo( + rust, + "rust_toolchains", +) + +register_toolchains("@rust_toolchains//:all") + +crate = use_extension( + "@rules_rust//crate_universe:extension.bzl", + "crate", +) +crate.from_cargo( + name = "override_test", + cargo_lockfile = "//:Cargo.lock", + manifests = ["//:Cargo.toml"], +) +crate.annotation( + crate = "foo", + override_target_lib = "@//:foo", +) +use_repo(crate, "override_test") diff --git a/examples/bzlmod/override_target/WORKSPACE.bazel b/examples/bzlmod/override_target/WORKSPACE.bazel new file mode 100644 index 0000000000..b543b79e9e --- /dev/null +++ b/examples/bzlmod/override_target/WORKSPACE.bazel @@ -0,0 +1 @@ +# Intentionally blank; using bzlmod diff --git a/examples/bzlmod/override_target/WORKSPACE.bzlmod b/examples/bzlmod/override_target/WORKSPACE.bzlmod new file mode 100644 index 0000000000..8e081c0b59 --- /dev/null +++ b/examples/bzlmod/override_target/WORKSPACE.bzlmod @@ -0,0 +1 @@ +# Intentionally blank; enable strict mode for bzlmod diff --git a/examples/bzlmod/override_target/foo.rs b/examples/bzlmod/override_target/foo.rs new file mode 100644 index 0000000000..c3e5fb063d --- /dev/null +++ b/examples/bzlmod/override_target/foo.rs @@ -0,0 +1 @@ +pub const THE_ANSWER: u32 = 42; diff --git a/examples/bzlmod/override_target/src/lib.rs b/examples/bzlmod/override_target/src/lib.rs new file mode 100644 index 0000000000..3334c92b6c --- /dev/null +++ b/examples/bzlmod/override_target/src/lib.rs @@ -0,0 +1,6 @@ +mod test { + #[test] + pub fn test() { + assert_eq!(foo::THE_ANSWER, 42); + } +}