Skip to content

Commit d49fb5b

Browse files
authored
propagate linkopts from (transitive) native dependencies (#849)
* propagate linkopts from (transitive) native dependencies * check the order of linkopts; use tut.actions
1 parent 5b5fb05 commit d49fb5b

File tree

2 files changed

+72
-3
lines changed

2 files changed

+72
-3
lines changed

rust/private/rustc.bzl

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,14 @@ def get_linker_and_args(ctx, cc_toolchain, feature_configuration, rpaths):
201201
- (dict): Environment variables to be set for given action.
202202
"""
203203
user_link_flags = get_cc_user_link_flags(ctx)
204+
205+
# Add linkopt's from dependencies. This includes linkopts from transitive
206+
# dependencies since they get merged up.
207+
for dep in ctx.attr.deps:
208+
if CcInfo in dep and dep[CcInfo].linking_context:
209+
for linker_input in dep[CcInfo].linking_context.linker_inputs.to_list():
210+
for flag in linker_input.user_link_flags:
211+
user_link_flags.append(flag)
204212
link_variables = cc_common.create_link_variables(
205213
feature_configuration = feature_configuration,
206214
cc_toolchain = cc_toolchain,

test/unit/native_deps/native_deps_test.bzl

Lines changed: 64 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
load("@bazel_skylib//lib:unittest.bzl", "analysistest", "asserts")
44
load("@rules_cc//cc:defs.bzl", "cc_library")
55
load("//rust:defs.bzl", "rust_binary", "rust_library", "rust_proc_macro", "rust_shared_library", "rust_static_library")
6-
load("//test/unit:common.bzl", "assert_argv_contains", "assert_argv_contains_not", "assert_argv_contains_prefix_suffix")
6+
load("//test/unit:common.bzl", "assert_argv_contains", "assert_argv_contains_not", "assert_argv_contains_prefix_suffix", "assert_list_contains_adjacent_elements")
77

88
def _native_dep_lib_name(ctx):
99
if ctx.target_platform_has_constraint(ctx.attr._windows_constraint[platform_common.ConstraintValueInfo]):
@@ -78,7 +78,13 @@ def _bin_has_native_libs_test_impl(ctx):
7878
return analysistest.end(env)
7979

8080
def _extract_linker_args(argv):
81-
return [a for a in argv if a.startswith("link-arg=") or a.startswith("link-arg=-l") or a.startswith("-l") or a.endswith(".lo") or a.endswith(".o")]
81+
return [a for a in argv if (
82+
a.startswith("link-arg=") or
83+
a.startswith("link-args=") or
84+
a.startswith("-l") or
85+
a.endswith(".lo") or
86+
a.endswith(".o")
87+
)]
8288

8389
def _bin_has_native_dep_and_alwayslink_test_impl(ctx):
8490
env = analysistest.begin(ctx)
@@ -103,7 +109,12 @@ def _bin_has_native_dep_and_alwayslink_test_impl(ctx):
103109
"link-arg=bazel-out/k8-fastbuild/bin/test/unit/native_deps/libalwayslink.lo",
104110
"link-arg=-Wl,--no-whole-archive",
105111
]
106-
asserts.equals(env, want, _extract_linker_args(action.argv))
112+
individual_link_args = [
113+
arg
114+
for arg in _extract_linker_args(action.argv)
115+
if arg.startswith("link-arg=")
116+
]
117+
asserts.equals(env, want, individual_link_args)
107118
return analysistest.end(env)
108119

109120
def _cdylib_has_native_dep_and_alwayslink_test_impl(ctx):
@@ -243,13 +254,62 @@ def _native_dep_test():
243254
target_under_test = ":cdylib_has_native_dep_and_alwayslink",
244255
)
245256

257+
def _linkopts_propagate_test_impl(ctx):
258+
env = analysistest.begin(ctx)
259+
tut = analysistest.target_under_test(env)
260+
action = tut.actions[0]
261+
262+
# Ensure linkopts from direct (-Llinkoptdep1) and transitive
263+
# (-Llinkoptdep2) dependencies are propagated.
264+
# Consistently with cc rules, dependency linkopts take precedence over
265+
# dependent linkopts (i.e. dependency linkopts appear later in the command
266+
# line).
267+
linkopt_args = [
268+
arg
269+
for arg in _extract_linker_args(action.argv)
270+
if arg.startswith("link-args")
271+
][0].split(" ")
272+
assert_list_contains_adjacent_elements(
273+
env,
274+
linkopt_args,
275+
["-Llinkoptdep1", "-Llinkoptdep2"],
276+
)
277+
return analysistest.end(env)
278+
279+
linkopts_propagate_test = analysistest.make(_linkopts_propagate_test_impl)
280+
281+
def _linkopts_test():
282+
rust_binary(
283+
name = "linkopts_rust_bin",
284+
srcs = ["bin_using_native_dep.rs"],
285+
deps = [":linkopts_native_dep_a"],
286+
)
287+
288+
cc_library(
289+
name = "linkopts_native_dep_a",
290+
srcs = ["native_dep.cc"],
291+
linkopts = ["-Llinkoptdep1"],
292+
deps = [":linkopts_native_dep_b"],
293+
)
294+
295+
cc_library(
296+
name = "linkopts_native_dep_b",
297+
linkopts = ["-Llinkoptdep2"],
298+
)
299+
300+
linkopts_propagate_test(
301+
name = "native_linkopts_propagate_test",
302+
target_under_test = ":linkopts_rust_bin",
303+
)
304+
246305
def native_deps_test_suite(name):
247306
"""Entry-point macro called from the BUILD file.
248307
249308
Args:
250309
name: Name of the macro.
251310
"""
252311
_native_dep_test()
312+
_linkopts_test()
253313

254314
native.test_suite(
255315
name = name,
@@ -261,5 +321,6 @@ def native_deps_test_suite(name):
261321
":bin_has_native_libs_test",
262322
":bin_has_native_dep_and_alwayslink_test",
263323
":cdylib_has_native_dep_and_alwayslink_test",
324+
":native_linkopts_propagate_test",
264325
],
265326
)

0 commit comments

Comments
 (0)