blob: f1338086d06454a5e0d2ed04d4bc3745da444cf7 [file] [log] [blame]
"""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,
],
)