"""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, ], )