blob: a0ae6fe5193e903b78f1a3952965502ef1df60d0 [file] [log] [blame]
"""Unittests for rust linkstamp support."""
load("@bazel_skylib//lib:unittest.bzl", "analysistest", "asserts")
load("@rules_cc//cc:defs.bzl", "cc_library")
load("//rust:defs.bzl", "rust_binary", "rust_common", "rust_library", "rust_test")
load("//test/unit:common.bzl", "assert_action_mnemonic")
def _is_running_on_linux(ctx):
return ctx.target_platform_has_constraint(ctx.attr._linux[platform_common.ConstraintValueInfo])
def _supports_linkstamps_test(ctx):
env = analysistest.begin(ctx)
tut = analysistest.target_under_test(env)
if not _is_running_on_linux(ctx):
# Skipping linkstamps tests on an unsupported (non-Linux) platform
return analysistest.end(env)
linkstamp_action = tut.actions[0]
assert_action_mnemonic(env, linkstamp_action, "CppLinkstampCompile")
linkstamp_out = linkstamp_action.outputs.to_list()[0]
asserts.equals(env, linkstamp_out.basename, "linkstamp.o")
tut_out = tut.files.to_list()[0]
is_test = tut[rust_common.crate_info].is_test
workspace_prefix = "" if ctx.workspace_name == "rules_rust" else "/external/rules_rust"
# Rust compilation outputs coming from a test are put in test-{hash} directory
# which we need to remove in order to obtain the linkstamp file path.
dirname = "/".join(tut_out.dirname.split("/")[:-1]) if is_test else tut_out.dirname
expected_linkstamp_path = dirname + "/_objs/" + tut_out.basename + workspace_prefix + "/test/unit/linkstamps/linkstamp.o"
asserts.equals(
env,
linkstamp_out.path,
expected_linkstamp_path,
"Expected linkstamp output '{actual_path}' to match '{expected_path}'".format(
actual_path = linkstamp_out.path,
expected_path = expected_linkstamp_path,
),
)
rustc_action = tut.actions[1]
assert_action_mnemonic(env, rustc_action, "Rustc")
rustc_inputs = rustc_action.inputs.to_list()
asserts.true(
env,
linkstamp_out in rustc_inputs,
"Expected linkstamp output '{output}' to be among the binary inputs '{inputs}'".format(
output = linkstamp_out,
inputs = rustc_inputs,
),
)
return analysistest.end(env)
supports_linkstamps_test = analysistest.make(
_supports_linkstamps_test,
attrs = {
"_linux": attr.label(default = Label("@platforms//os:linux")),
},
)
def _linkstamps_test():
# Native linkstamps are only supported by the builtin Linux C++ toolchain. Ideally,
# we would be able to inspect the feature_configuration of the target to see if
# it has the "linkstamp" feature, but there is no way to get that feature
# configuration.
cc_library(
name = "cc_lib_with_linkstamp",
linkstamp = select({
"//rust/platform:linux": "linkstamp.cc",
"//conditions:default": None,
}),
)
rust_binary(
name = "some_rust_binary",
srcs = ["foo.rs"],
edition = "2018",
deps = [":cc_lib_with_linkstamp"],
)
supports_linkstamps_test(
name = "rust_binary_supports_linkstamps_test",
target_under_test = ":some_rust_binary",
)
rust_library(
name = "some_rust_library_with_linkstamp_transitively",
srcs = ["foo.rs"],
edition = "2018",
deps = [":cc_lib_with_linkstamp"],
)
rust_binary(
name = "some_rust_binary_with_linkstamp_transitively",
srcs = ["foo.rs"],
edition = "2018",
deps = [":some_rust_library_with_linkstamp_transitively"],
)
supports_linkstamps_test(
name = "rust_binary_with_linkstamp_transitively",
target_under_test = ":some_rust_binary_with_linkstamp_transitively",
)
cc_library(
name = "cc_lib_with_linkstamp_transitively",
deps = [":cc_lib_with_linkstamp"],
)
rust_binary(
name = "some_rust_binary_with_multiple_paths_to_a_linkstamp",
srcs = ["foo.rs"],
edition = "2018",
deps = [":cc_lib_with_linkstamp", ":cc_lib_with_linkstamp_transitively"],
)
supports_linkstamps_test(
name = "rust_binary_supports_duplicated_linkstamps",
target_under_test = ":some_rust_binary_with_multiple_paths_to_a_linkstamp",
)
rust_test(
name = "some_rust_test1",
srcs = ["foo.rs"],
edition = "2018",
deps = [":cc_lib_with_linkstamp"],
)
supports_linkstamps_test(
name = "rust_test_supports_linkstamps_test1",
target_under_test = ":some_rust_test1",
)
rust_test(
name = "some_rust_test2",
srcs = ["foo.rs"],
edition = "2018",
deps = [":cc_lib_with_linkstamp"],
)
supports_linkstamps_test(
name = "rust_test_supports_linkstamps_test2",
target_under_test = ":some_rust_test2",
)
def linkstamps_test_suite(name):
"""Entry-point macro called from the BUILD file.
Args:
name: Name of the macro.
"""
# Older versions of Bazel do not support Starlark linkstamps.
if not hasattr(cc_common, "register_linkstamp_compile_action"):
# buildifier: disable=print
print("Skipping linkstamps tests since this Bazel version does not support Starlark linkstamps.")
return
_linkstamps_test()
native.test_suite(
name = name,
tests = [
":rust_binary_supports_linkstamps_test",
":rust_binary_supports_duplicated_linkstamps",
":rust_test_supports_linkstamps_test1",
":rust_test_supports_linkstamps_test2",
],
)