Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions rs/toolchains/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ bzl_library(
":toolchain_utils",
"//rs/platforms:triples",
"//rs/private:bpf_linker_repository",
"@bazel_skylib//lib:versions",
"@default_rust_toolchains//rustc:component_labels.bzl",
"@rules_rust//rust:bzl_lib",
"@rules_rust//rust/platform:bzl_lib",
Expand Down
22 changes: 20 additions & 2 deletions rs/toolchains/declare_rustc_toolchains.bzl
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"""Definitions for declaring Rust compiler toolchains."""

load("@bazel_skylib//lib:versions.bzl", "versions")
load("@default_rust_toolchains//rustc:component_labels.bzl", "rust_toolchain_component_label")
load("@rules_rust//rust:rust_toolchain.bzl", "rust_toolchain")
load("@rules_rust//rust/platform:triple.bzl", _parse_triple = "triple")
Expand All @@ -20,6 +21,23 @@ def _rustc_flags_to_select(rustc_flags_by_triple):
{"//conditions:default": []},
)

def _default_rustc_flags(version):
# Rust >= 1.90 defaults to self-contained LLD for x86_64-unknown-linux-gnu.
# When linking via Bazel C++ toolchain wrappers (e.g. cc_wrapper.sh), rustc
# fails to recognize the wrapper as a C compiler driver and attempts to invoke
# its bundled gcc-ld/rust-lld, failing in hermetic/sandboxed environments where
# the undeclared linker is not in the sandbox, or overriding the C++ toolchain's
# configured linker. Disabling the LLD linker feature leaves linking entirely to
# the Bazel C++ toolchain.
# Prior to 1.90, rustc did not default to LLD and the -Clinker-features option did not exist.
if _channel(version) == "stable" and not versions.is_at_least("1.90.0", version):
return []

return select({
"@rules_rs//rs/platforms/config:x86_64-unknown-linux-gnu": ["-Clinker-features=-lld"],
"//conditions:default": [],
})

def _component(component, triple, default):
component = component.get(triple) if type(component) == "dict" else component
return component or rust_toolchain_component_label(default)
Expand Down Expand Up @@ -193,8 +211,8 @@ def declare_rustc_toolchains(
"//conditions:default": [],
}),
default_edition = edition,
extra_exec_rustc_flags = _rustc_flags_to_select(extra_exec_rustc_flags),
extra_rustc_flags = _rustc_flags_to_select(extra_rustc_flags),
extra_exec_rustc_flags = _default_rustc_flags(version) + _rustc_flags_to_select(extra_exec_rustc_flags),
extra_rustc_flags = _default_rustc_flags(version) + _rustc_flags_to_select(extra_rustc_flags),
exec_triple = triple,
target_triple = select(target_triple_select),
visibility = ["//visibility:public"],
Expand Down
18 changes: 18 additions & 0 deletions test/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ load("@workspace_default_features//:data.bzl", workspace_default_features_dep_da
load("@workspace_hyphen_dep_aliases//:defs.bzl", workspace_hyphen_dep_aliases_aliases = "aliases")
load("@workspace_renamed_path_dep_aliases//:defs.bzl", workspace_renamed_path_dep_aliases_aliases = "aliases")
load("//:rustdoc_musl_unwind_test.bzl", "rustdoc_musl_unwind_link_flags_test")
load("//:self_contained_linker_test.bzl", "self_contained_linker_aarch64_test", "self_contained_linker_x86_64_test")
load("//:target_triple_constraints_test.bzl", "target_triple_constraints_test")
load("//:verify_aliases.bzl", "verify_alias", "verify_alias_absent", "verify_crate_feature_absent", "verify_crate_feature_present", "verify_dep_absent", "verify_dep_present", "verify_dev_dep_absent")
load("//:workspace_lints_test.bzl", "inherited_workspace_lints_test", "opted_out_workspace_lints_test", "package_lints_test")
Expand All @@ -36,6 +37,23 @@ sh_test(
}),
)

rust_binary(
name = "self_contained_linker_sample_bin",
srcs = ["main.rs"],
edition = "2021",
tags = ["manual"],
)

self_contained_linker_x86_64_test(
name = "self_contained_linker_x86_64_test",
target_under_test = ":self_contained_linker_sample_bin",
)

self_contained_linker_aarch64_test(
name = "self_contained_linker_aarch64_test",
target_under_test = ":self_contained_linker_sample_bin",
)

cc_library(
name = "rustdoc_musl_unwind_cc",
srcs = ["rustdoc_musl_unwind.cc"],
Expand Down
51 changes: 51 additions & 0 deletions test/self_contained_linker_test.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
"""Analysis test verifying that Linux x86_64 targets disable self-contained LLD via -Clinker-features=-lld."""

load("@bazel_skylib//lib:unittest.bzl", "analysistest", "asserts")

def _get_action_by_mnemonic(env, tut, mnemonic):
actions = [action for action in tut.actions if action.mnemonic == mnemonic]
asserts.equals(
env,
1,
len(actions),
"Expected exactly one {} action, got {}".format(mnemonic, [action.mnemonic for action in tut.actions]),
)
return actions[0]

def _self_contained_linker_x86_64_test_impl(ctx):
env = analysistest.begin(ctx)
tut = analysistest.target_under_test(env)
action = _get_action_by_mnemonic(env, tut, "Rustc")

asserts.true(
env,
"-Clinker-features=-lld" in action.argv,
"Expected '-Clinker-features=-lld' in Rustc action argv for x86_64-unknown-linux-gnu, but it was missing: {}".format(action.argv),
)
return analysistest.end(env)

def _self_contained_linker_aarch64_test_impl(ctx):
env = analysistest.begin(ctx)
tut = analysistest.target_under_test(env)
action = _get_action_by_mnemonic(env, tut, "Rustc")

asserts.false(
env,
"-Clinker-features=-lld" in action.argv,
"Did not expect '-Clinker-features=-lld' in Rustc action argv for aarch64-unknown-linux-gnu: {}".format(action.argv),
)
return analysistest.end(env)

self_contained_linker_x86_64_test = analysistest.make(
_self_contained_linker_x86_64_test_impl,
config_settings = {
"//command_line_option:platforms": str(Label("@rules_rs//rs/platforms:x86_64-unknown-linux-gnu")),
},
)

self_contained_linker_aarch64_test = analysistest.make(
_self_contained_linker_aarch64_test_impl,
config_settings = {
"//command_line_option:platforms": str(Label("@rules_rs//rs/platforms:aarch64-unknown-linux-gnu")),
},
)
Loading