diff --git a/rust/private/rust.bzl b/rust/private/rust.bzl index f6653251d3..8dbb2648d9 100644 --- a/rust/private/rust.bzl +++ b/rust/private/rust.bzl @@ -61,14 +61,14 @@ def _assert_correct_dep_mapping(ctx): ), ) -def _determine_lib_name(name, crate_type, toolchain, lib_hash = ""): +def _determine_lib_name(name, crate_type, toolchain, lib_hash = None): """See https://github.com/bazelbuild/rules_rust/issues/405 Args: name (str): The name of the current target crate_type (str): The `crate_type` toolchain (rust_toolchain): The current `rust_toolchain` - lib_hash (str, optional): The hashed crate root path. Defaults to "". + lib_hash (str, optional): The hashed crate root path Returns: str: A unique library name @@ -97,10 +97,10 @@ def _determine_lib_name(name, crate_type, toolchain, lib_hash = ""): if toolchain.target_arch == "wasm32" and crate_type == "cdylib": prefix = "" - return "{prefix}{name}-{lib_hash}{extension}".format( + return "{prefix}{name}{lib_hash}{extension}".format( prefix = prefix, name = name, - lib_hash = lib_hash, + lib_hash = "-" + lib_hash if lib_hash else "", extension = extension, ) @@ -239,8 +239,15 @@ def _rust_library_common(ctx, crate_type): toolchain = find_toolchain(ctx) - # Determine unique hash for this rlib - output_hash = determine_output_hash(crate_root) + # Determine unique hash for this rlib. + # Note that we don't include a hash for `cdylib` since they are meant to be consumed externally and having a + # deterministic name is important since it ends up embedded in the executable. This is problematic when one needs + # to include the library with a specific filename into a larger application. + # (see https://github.com/bazelbuild/rules_rust/issues/405#issuecomment-993089889 for more details) + if crate_type != "cdylib": + output_hash = determine_output_hash(crate_root) + else: + output_hash = None crate_name = crate_name_from_attr(ctx.attr) rust_lib_name = _determine_lib_name( diff --git a/test/unit/cdylib_name/BUILD.bazel b/test/unit/cdylib_name/BUILD.bazel new file mode 100644 index 0000000000..112a7dad79 --- /dev/null +++ b/test/unit/cdylib_name/BUILD.bazel @@ -0,0 +1,4 @@ +load(":cdylib_name_analysis_test.bzl", "cdylib_name_analysis_test_suite") + +############################ UNIT TESTS ############################# +cdylib_name_analysis_test_suite(name = "cdylib_name_analysis_test_suite") diff --git a/test/unit/cdylib_name/cdylib_name_analysis_test.bzl b/test/unit/cdylib_name/cdylib_name_analysis_test.bzl new file mode 100644 index 0000000000..bbb571cdbb --- /dev/null +++ b/test/unit/cdylib_name/cdylib_name_analysis_test.bzl @@ -0,0 +1,46 @@ +"""Analysis tests for the name we assign to cdylib libraries.""" + +load("@bazel_skylib//lib:unittest.bzl", "analysistest", "asserts") +load("//rust:defs.bzl", "rust_shared_library") + +def _cdylib_name_test_impl(ctx): + env = analysistest.begin(ctx) + target = analysistest.target_under_test(env) + + # We're expecting the `.dylib`/`.so` to be the only file on Unix and Windows to + # contain a pair of `.dll` and `.lib` files. + files = target[DefaultInfo].files.to_list() + if len(files) == 1: + asserts.true(env, files[0].extension in ("so", "dylib")) + if files[0].extension == "so": + asserts.equals(env, files[0].basename, "libsomething.so") + elif files[0].extension == "dylib": + asserts.equals(env, files[0].basename, "libsomething.dylib") + elif len(files) == 2: + asserts.equals(env, files[0].basename, "something.dll") + asserts.equals(env, files[1].basename, "something.lib") + + return analysistest.end(env) + +cdylib_name_test = analysistest.make(_cdylib_name_test_impl) + +def cdylib_name_analysis_test_suite(name): + """Analysis tests for the name we assign to cdylib libraries. + + Args: + name: the test suite name + """ + rust_shared_library( + name = "something", + srcs = ["lib.rs"], + ) + + cdylib_name_test( + name = "cdylib_name_test", + target_under_test = ":something", + ) + + native.test_suite( + name = name, + tests = [":cdylib_name_test"], + ) diff --git a/test/unit/cdylib_name/lib.rs b/test/unit/cdylib_name/lib.rs new file mode 100644 index 0000000000..417c1bafd1 --- /dev/null +++ b/test/unit/cdylib_name/lib.rs @@ -0,0 +1,4 @@ +#[no_mangle] +pub extern "C" fn say_hello() { + println!("Hello"); +}