diff options
Diffstat (limited to 'test/link_std_dylib/link_std_dylib_test.bzl')
-rw-r--r-- | test/link_std_dylib/link_std_dylib_test.bzl | 118 |
1 files changed, 118 insertions, 0 deletions
diff --git a/test/link_std_dylib/link_std_dylib_test.bzl b/test/link_std_dylib/link_std_dylib_test.bzl new file mode 100644 index 00000000..f1338086 --- /dev/null +++ b/test/link_std_dylib/link_std_dylib_test.bzl @@ -0,0 +1,118 @@ +"""Analysis tests for experimental_link_std_dylib flag""" + +load("@rules_cc//cc:defs.bzl", "CcInfo") +load("@rules_rust//rust:defs.bzl", "rust_binary", "rust_library") +load("@rules_testing//lib:analysis_test.bzl", "analysis_test", "test_suite") + +# buildifier: disable=bzl-visibility +load("//rust/private:utils.bzl", "is_std_dylib") + +def _test_rust_binary_impl(env, targets): + env.expect.that_action(targets.default_binary.actions[0]) \ + .contains_none_of_flag_values([ + ("--codegen", "prefer-dynamic"), + ]) + + # Make sure with @rules_rust//rust/settings:experimental_link_std_dylib, + # the linker flags are set up correct so that the binary dynamically links + # the stdlib + env.expect.that_action(targets.binary_with_std_dylib.actions[0]) \ + .contains_flag_values([ + ("--codegen", "prefer-dynamic"), + ]) + +def _test_rust_binary(name): + rust_binary( + name = name + "_rust_binary", + srcs = ["main.rs"], + edition = "2021", + tags = ["manual"], + ) + + analysis_test( + name = name, + impl = _test_rust_binary_impl, + targets = { + "binary_with_std_dylib": name + "_rust_binary", + "default_binary": name + "_rust_binary", + }, + attrs = { + "binary_with_std_dylib": { + "@config_settings": { + str(Label("@rules_rust//rust/settings:experimental_link_std_dylib")): True, + }, + }, + }, + ) + +def _export_static_stdlibs_in_cc_info(target): + linker_inputs = target[CcInfo].linking_context.linker_inputs + for linker_input in linker_inputs.to_list(): + for library in linker_input.libraries: + if hasattr(library, "pic_static_library") and library.pic_static_library != None: + basename = library.pic_static_library.basename + if basename.startswith("libstd") and basename.endswith(".a"): + return True + return False + +def _export_libstd_dylib_in_cc_info(target): + linker_inputs = target[CcInfo].linking_context.linker_inputs + for linker_input in linker_inputs.to_list(): + for library in linker_input.libraries: + if hasattr(library, "dynamic_library") and library.dynamic_library != None: + if is_std_dylib(library.dynamic_library): + return True + return False + +def _test_rust_library_impl(env, targets): + # By default, rust_library exports static stdlibs to downstream shared + # and binary targets to statically link + env.expect \ + .that_bool(_export_static_stdlibs_in_cc_info(targets.default_rlib)) \ + .equals(True) + env.expect \ + .that_bool(_export_libstd_dylib_in_cc_info(targets.default_rlib)) \ + .equals(False) + + # With @rules_rust//rust/settings:experimental_link_std_dylib + # rust_library exports dylib std and does not export static stdlibs to + # downstream shared and binary targets to dynamically link + env.expect \ + .that_bool(_export_static_stdlibs_in_cc_info(targets.rlib_with_std_dylib)) \ + .equals(False) + env.expect \ + .that_bool(_export_libstd_dylib_in_cc_info(targets.rlib_with_std_dylib)) \ + .equals(True) + +def _test_rust_library(name): + rust_library( + name = name + "_rust_library", + srcs = ["lib.rs"], + edition = "2021", + tags = ["manual"], + ) + + analysis_test( + name = name, + impl = _test_rust_library_impl, + targets = { + "default_rlib": name + "_rust_library", + "rlib_with_std_dylib": name + "_rust_library", + }, + attrs = { + "rlib_with_std_dylib": { + "@config_settings": { + str(Label("@rules_rust//rust/settings:experimental_link_std_dylib")): True, + }, + }, + }, + ) + +def link_std_dylib_test_suite(name): + test_suite( + name = name, + tests = [ + _test_rust_binary, + _test_rust_library, + ], + ) |