Skip to content

Commit da4de3b

Browse files
authored
Add runtime_libs as rust compile action inputs (#3741)
The current handling of `static_runtime_lib`/`dynamic_runtime_lib` is broken because it never adds these libs to the action. I think it assumes they are coming from `cc_toolchain.all_files` but that's not necessarily a safe assumption; when these libs are built from source there's no reason to force all actions to depend on both of them via the toolchain files if we may not end up using them. (We hit this scenario in https://github.com/cerisier/toolchains_llvm_bootstrapped)
1 parent aa6e74e commit da4de3b

File tree

6 files changed

+169
-21
lines changed

6 files changed

+169
-21
lines changed

rust/private/rustc.bzl

Lines changed: 15 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -727,10 +727,18 @@ def collect_inputs(
727727
if linker_script:
728728
nolinkstamp_compile_direct_inputs.append(linker_script)
729729

730+
if crate_info.type in ["dylib", "cdylib"]:
731+
# For shared libraries we want to link C++ runtime library dynamically
732+
# (for example libstdc++.so or libc++.so).
733+
runtime_libs = cc_toolchain.dynamic_runtime_lib(feature_configuration = feature_configuration)
734+
else:
735+
runtime_libs = cc_toolchain.static_runtime_lib(feature_configuration = feature_configuration)
736+
730737
nolinkstamp_compile_inputs = depset(
731738
nolinkstamp_compile_direct_inputs +
732739
additional_transitive_inputs,
733740
transitive = [
741+
runtime_libs,
734742
linker_depset,
735743
crate_info.srcs,
736744
transitive_crate_outputs,
@@ -2270,36 +2278,22 @@ def _add_native_link_flags(args, dep_info, linkstamp_outs, ambiguous_libs, crate
22702278

22712279
args.add_all(make_link_flags_args, map_each = make_link_flags)
22722280

2273-
args.add_all(linkstamp_outs, before_each = "-C", format_each = "link-args=%s")
2281+
args.add_all(linkstamp_outs, format_each = "-Clink-args=%s")
22742282

22752283
if crate_type in ["dylib", "cdylib"]:
22762284
# For shared libraries we want to link C++ runtime library dynamically
22772285
# (for example libstdc++.so or libc++.so).
2278-
args.add_all(
2279-
cc_toolchain.dynamic_runtime_lib(feature_configuration = feature_configuration),
2280-
map_each = _get_dirname,
2281-
format_each = "-Lnative=%s",
2282-
)
2286+
runtime_libs = cc_toolchain.dynamic_runtime_lib(feature_configuration = feature_configuration)
2287+
args.add_all(runtime_libs, map_each = _get_dirname, format_each = "-Lnative=%s")
22832288
if include_link_flags:
2284-
args.add_all(
2285-
cc_toolchain.dynamic_runtime_lib(feature_configuration = feature_configuration),
2286-
map_each = get_lib_name,
2287-
format_each = "-ldylib=%s",
2288-
)
2289+
args.add_all(runtime_libs, map_each = get_lib_name, format_each = "-ldylib=%s")
22892290
else:
22902291
# For all other crate types we want to link C++ runtime library statically
22912292
# (for example libstdc++.a or libc++.a).
2292-
args.add_all(
2293-
cc_toolchain.static_runtime_lib(feature_configuration = feature_configuration),
2294-
map_each = _get_dirname,
2295-
format_each = "-Lnative=%s",
2296-
)
2293+
runtime_libs = cc_toolchain.static_runtime_lib(feature_configuration = feature_configuration)
2294+
args.add_all(runtime_libs, map_each = _get_dirname, format_each = "-Lnative=%s")
22972295
if include_link_flags:
2298-
args.add_all(
2299-
cc_toolchain.static_runtime_lib(feature_configuration = feature_configuration),
2300-
map_each = get_lib_name,
2301-
format_each = "-lstatic=%s",
2302-
)
2296+
args.add_all(runtime_libs, map_each = get_lib_name, format_each = "-lstatic=%s")
23032297

23042298
def _get_dirname(file):
23052299
"""A helper function for `_add_native_link_flags`.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
load(":cc_toolchain_runtime_lib_test.bzl", "runtime_libs_test")
2+
3+
runtime_libs_test(name = "runtime_libs_test")
Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
"""
2+
Tests for handling of cc_toolchain's static_runtime_lib/dynamic_runtime_lib.
3+
"""
4+
5+
load("@bazel_skylib//lib:unittest.bzl", "analysistest", "asserts")
6+
load("@rules_cc//cc:cc_toolchain_config_lib.bzl", "feature")
7+
load("@rules_cc//cc:defs.bzl", "cc_toolchain")
8+
load("@rules_cc//cc/common:cc_common.bzl", "cc_common")
9+
load("//rust:defs.bzl", "rust_shared_library", "rust_static_library")
10+
11+
def _test_cc_config_impl(ctx):
12+
config_info = cc_common.create_cc_toolchain_config_info(
13+
ctx = ctx,
14+
toolchain_identifier = "test-cc-toolchain",
15+
host_system_name = "unknown",
16+
target_system_name = "unknown",
17+
target_cpu = "unknown",
18+
target_libc = "unknown",
19+
compiler = "unknown",
20+
abi_version = "unknown",
21+
abi_libc_version = "unknown",
22+
features = [
23+
feature(name = "static_link_cpp_runtimes", enabled = True),
24+
],
25+
)
26+
return config_info
27+
28+
test_cc_config = rule(
29+
implementation = _test_cc_config_impl,
30+
provides = [CcToolchainConfigInfo],
31+
)
32+
33+
def _with_extra_toolchain_transition_impl(_settings, attr):
34+
return {"//command_line_option:extra_toolchains": [attr.extra_toolchain]}
35+
36+
with_extra_toolchain_transition = transition(
37+
implementation = _with_extra_toolchain_transition_impl,
38+
inputs = [],
39+
outputs = ["//command_line_option:extra_toolchains"],
40+
)
41+
42+
DepActionsInfo = provider(
43+
"Contains information about dependencies actions.",
44+
fields = {"actions": "List[Action]"},
45+
)
46+
47+
def _with_extra_toolchain_impl(ctx):
48+
return [
49+
DepActionsInfo(actions = ctx.attr.target[0].actions),
50+
]
51+
52+
with_extra_toolchain = rule(
53+
implementation = _with_extra_toolchain_impl,
54+
attrs = {
55+
"extra_toolchain": attr.label(),
56+
"target": attr.label(cfg = with_extra_toolchain_transition),
57+
},
58+
)
59+
60+
def _inputs_analysis_test_impl(ctx):
61+
env = analysistest.begin(ctx)
62+
tut = analysistest.target_under_test(env)
63+
action = tut[DepActionsInfo].actions[0]
64+
asserts.equals(env, action.mnemonic, "Rustc")
65+
inputs = action.inputs.to_list()
66+
for expected in ctx.attr.expected_inputs:
67+
asserts.true(
68+
env,
69+
any([input.path.endswith("/" + expected) for input in inputs]),
70+
"error: expected '{}' to be in inputs: '{}'".format(expected, inputs),
71+
)
72+
73+
return analysistest.end(env)
74+
75+
inputs_analysis_test = analysistest.make(
76+
impl = _inputs_analysis_test_impl,
77+
doc = """An analysistest to examine the inputs of a library target.""",
78+
attrs = {
79+
"expected_inputs": attr.string_list(),
80+
},
81+
)
82+
83+
def runtime_libs_test(name):
84+
"""Produces test shared and static library targets that are set up to use a custom cc_toolchain with custom runtime libs.
85+
86+
Args:
87+
name: The name of the test target.
88+
"""
89+
90+
test_cc_config(
91+
name = "%s/cc_toolchain_config" % name,
92+
)
93+
cc_toolchain(
94+
name = "%s/test_cc_toolchain_impl" % name,
95+
all_files = ":empty",
96+
compiler_files = ":empty",
97+
dwp_files = ":empty",
98+
linker_files = ":empty",
99+
objcopy_files = ":empty",
100+
strip_files = ":empty",
101+
supports_param_files = 0,
102+
toolchain_config = ":%s/cc_toolchain_config" % name,
103+
toolchain_identifier = "dummy_wasm32_cc",
104+
static_runtime_lib = ":dummy.a",
105+
dynamic_runtime_lib = ":dummy.so",
106+
)
107+
native.toolchain(
108+
name = "%s/test_cc_toolchain" % name,
109+
toolchain = ":%s/test_cc_toolchain_impl" % name,
110+
toolchain_type = "@bazel_tools//tools/cpp:toolchain_type",
111+
)
112+
113+
rust_shared_library(
114+
name = "%s/__shared_library" % name,
115+
edition = "2018",
116+
srcs = ["lib.rs"],
117+
tags = ["manual", "nobuild"],
118+
)
119+
120+
with_extra_toolchain(
121+
name = "%s/_shared_library" % name,
122+
extra_toolchain = ":%s/test_cc_toolchain" % name,
123+
target = "%s/__shared_library" % name,
124+
tags = ["manual"],
125+
)
126+
127+
inputs_analysis_test(
128+
name = "%s/shared_library" % name,
129+
target_under_test = "%s/_shared_library" % name,
130+
expected_inputs = ["dummy.so"],
131+
)
132+
133+
rust_static_library(
134+
name = "%s/__static_library" % name,
135+
edition = "2018",
136+
srcs = ["lib.rs"],
137+
tags = ["manual", "nobuild"],
138+
)
139+
140+
with_extra_toolchain(
141+
name = "%s/_static_library" % name,
142+
extra_toolchain = ":%s/test_cc_toolchain" % name,
143+
target = "%s/__static_library" % name,
144+
tags = ["manual"],
145+
)
146+
147+
inputs_analysis_test(
148+
name = "%s/static_library" % name,
149+
target_under_test = "%s/_static_library" % name,
150+
expected_inputs = ["dummy.a"],
151+
)

test/unit/cc_toolchain_runtime_lib/dummy.a

Whitespace-only changes.

test/unit/cc_toolchain_runtime_lib/dummy.so

Whitespace-only changes.

test/unit/cc_toolchain_runtime_lib/empty

Whitespace-only changes.

0 commit comments

Comments
 (0)