Skip to content

Commit

Permalink
Use crate_name to also match crate_root. (#2824)
Browse files Browse the repository at this point in the history
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
     )
```
  • Loading branch information
UebelAndre authored Sep 3, 2024
1 parent ef8ac18 commit 73b1594
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 5 deletions.
6 changes: 3 additions & 3 deletions rust/private/rust.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -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)
Expand Down
9 changes: 7 additions & 2 deletions rust/private/utils.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -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).
Expand All @@ -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"]
Expand Down
1 change: 1 addition & 0 deletions test/unit/crate_name/add.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

30 changes: 30 additions & 0 deletions test/unit/crate_name/crate_name_test.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -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"],
Expand All @@ -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"],
Expand Down
1 change: 1 addition & 0 deletions test/unit/crate_name/smain.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
fn main() {}
16 changes: 16 additions & 0 deletions test/unit/crate_name/stest.rs
Original file line number Diff line number Diff line change
@@ -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);
}
}

0 comments on commit 73b1594

Please sign in to comment.