From 73b159426e7c8bea1051638c8def482865a66025 Mon Sep 17 00:00:00 2001 From: UebelAndre Date: Tue, 3 Sep 2024 03:36:40 -0700 Subject: [PATCH] Use `crate_name` to also match `crate_root`. (#2824) This allows targets to have special names that do not match their sources while still ensuring a root is found. I've encountered this when creating macros where I have a Rust target that is a side-effect and not the named target itself. E.g. ```starlark load("@rules_rust//rust:defs.bzl", "rust_binary") load("//control/private:control.bzl", _control_binary = "control_binary") def control_binary( name, # ... **kwargs): rust_binary( name = name + "_bin", # ... **kwargs ) _control_binary( name = name, bin = name + "_bin", # ... **kwargs ) ``` Being able to specify `crate_name` will both ensure the binary is compiled with a cleaner name for the runtime and be able to do the nominal `crate_root` matching. The diff after this PR achieves the desired behavior. ```diff --- before/defs.bzl 2024-08-31 12:41:24 +++ after/defs.bzl 2024-08-31 12:42:09 @@ -8,6 +8,7 @@ rust_binary( name = name + "_bin", + crate_name = name, # ... **kwargs ) ``` --- rust/private/rust.bzl | 6 ++--- rust/private/utils.bzl | 9 +++++-- test/unit/crate_name/add.rs | 1 + test/unit/crate_name/crate_name_test.bzl | 30 ++++++++++++++++++++++++ test/unit/crate_name/smain.rs | 1 + test/unit/crate_name/stest.rs | 16 +++++++++++++ 6 files changed, 58 insertions(+), 5 deletions(-) create mode 100644 test/unit/crate_name/add.rs create mode 100644 test/unit/crate_name/smain.rs create mode 100644 test/unit/crate_name/stest.rs diff --git a/rust/private/rust.bzl b/rust/private/rust.bzl index 838c925fe1..c3bc47c757 100644 --- a/rust/private/rust.bzl +++ b/rust/private/rust.bzl @@ -148,7 +148,7 @@ def _rust_library_common(ctx, crate_type): crate_root = getattr(ctx.file, "crate_root", None) if not crate_root: - crate_root = crate_root_src(ctx.attr.name, ctx.files.srcs, crate_type) + crate_root = crate_root_src(ctx.attr.name, ctx.attr.crate_name, ctx.files.srcs, crate_type) srcs, crate_root = transform_sources(ctx, ctx.files.srcs, crate_root) # Determine unique hash for this rlib. @@ -228,7 +228,7 @@ def _rust_binary_impl(ctx): crate_root = getattr(ctx.file, "crate_root", None) if not crate_root: - crate_root = crate_root_src(ctx.attr.name, ctx.files.srcs, ctx.attr.crate_type) + crate_root = crate_root_src(ctx.attr.name, ctx.attr.crate_name, ctx.files.srcs, ctx.attr.crate_type) srcs, crate_root = transform_sources(ctx, ctx.files.srcs, crate_root) providers = rustc_compile_action( @@ -365,7 +365,7 @@ def _rust_test_impl(ctx): if not crate_root: crate_root_type = "lib" if ctx.attr.use_libtest_harness else "bin" - crate_root = crate_root_src(ctx.attr.name, ctx.files.srcs, crate_root_type) + crate_root = crate_root_src(ctx.attr.name, ctx.attr.crate_name, ctx.files.srcs, crate_root_type) srcs, crate_root = transform_sources(ctx, ctx.files.srcs, crate_root) output_hash = determine_output_hash(crate_root, ctx.label) diff --git a/rust/private/utils.bzl b/rust/private/utils.bzl index 0056bfa964..c7be25838a 100644 --- a/rust/private/utils.bzl +++ b/rust/private/utils.bzl @@ -708,11 +708,12 @@ def can_build_metadata(toolchain, ctx, crate_type): ctx.attr._process_wrapper and \ crate_type in ("rlib", "lib") -def crate_root_src(name, srcs, crate_type): +def crate_root_src(name, crate_name, srcs, crate_type): """Determines the source file for the crate root, should it not be specified in `attr.crate_root`. Args: name (str): The name of the target. + crate_name (str): The target's `crate_name` attribute. srcs (list): A list of all sources for the target Crate. crate_type (str): The type of this crate ("bin", "lib", "rlib", "cdylib", etc). @@ -723,10 +724,14 @@ def crate_root_src(name, srcs, crate_type): """ default_crate_root_filename = "main.rs" if crate_type == "bin" else "lib.rs" + if not crate_name: + crate_name = name + crate_root = ( (srcs[0] if len(srcs) == 1 else None) or _shortest_src_with_basename(srcs, default_crate_root_filename) or - _shortest_src_with_basename(srcs, name + ".rs") + _shortest_src_with_basename(srcs, name + ".rs") or + _shortest_src_with_basename(srcs, crate_name + ".rs") ) if not crate_root: file_names = [default_crate_root_filename, name + ".rs"] diff --git a/test/unit/crate_name/add.rs b/test/unit/crate_name/add.rs new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/test/unit/crate_name/add.rs @@ -0,0 +1 @@ + diff --git a/test/unit/crate_name/crate_name_test.bzl b/test/unit/crate_name/crate_name_test.bzl index e960e89c53..b884577c86 100644 --- a/test/unit/crate_name/crate_name_test.bzl +++ b/test/unit/crate_name/crate_name_test.bzl @@ -126,6 +126,16 @@ def _crate_name_test(): edition = "2018", ) + rust_binary( + name = "custom_bin_target_name", + crate_name = "smain", + srcs = [ + "smain.rs", + "add.rs", + ], + edition = "2018", + ) + rust_test( name = "default/crate-name-test", srcs = ["main.rs"], @@ -139,12 +149,32 @@ def _crate_name_test(): edition = "2018", ) + rust_test( + name = "custom_named_test", + crate_name = "stest", + srcs = [ + "stest.rs", + "add.rs", + ], + edition = "2018", + ) + rust_library( name = "slib", srcs = ["slib.rs"], edition = "2018", ) + rust_library( + name = "custom_lib_target_name", + crate_name = "slib", + srcs = [ + "slib.rs", + "add.rs", + ], + edition = "2018", + ) + rust_shared_library( name = "shared_lib", srcs = ["lib.rs"], diff --git a/test/unit/crate_name/smain.rs b/test/unit/crate_name/smain.rs new file mode 100644 index 0000000000..f328e4d9d0 --- /dev/null +++ b/test/unit/crate_name/smain.rs @@ -0,0 +1 @@ +fn main() {} diff --git a/test/unit/crate_name/stest.rs b/test/unit/crate_name/stest.rs new file mode 100644 index 0000000000..9e31c22697 --- /dev/null +++ b/test/unit/crate_name/stest.rs @@ -0,0 +1,16 @@ +//! https://doc.rust-lang.org/rust-by-example/testing/unit_testing.html + +pub fn add(a: i32, b: i32) -> i32 { + a + b +} + +#[cfg(test)] +mod tests { + // Note this useful idiom: importing names from outer (for mod tests) scope. + use super::*; + + #[test] + fn test_add() { + assert_eq!(add(1, 2), 3); + } +}