Skip to content

Commit 51f8e30

Browse files
authored
"sandwich" rlibs between native deps in linker order (#1333)
"sandwich" rlibs between two sections of native dependencies in linker order
1 parent df35490 commit 51f8e30

File tree

2 files changed

+22
-0
lines changed

2 files changed

+22
-0
lines changed

rust/private/rustc.bzl

+18
Original file line numberDiff line numberDiff line change
@@ -1301,8 +1301,26 @@ def _portable_link_flags(lib, use_pic, ambiguous_libs, experimental_use_whole_ar
13011301
modifiers = ""
13021302
if experimental_use_whole_archive_for_native_deps:
13031303
modifiers = ":+whole-archive"
1304+
1305+
# To ensure appropriate linker library argument order, in the presence
1306+
# of both native libraries that depend on rlibs and rlibs that depend
1307+
# on native libraries, we use an approach where we "sandwich" the
1308+
# rust libraries between two similar sections of all of native
1309+
# libraries:
1310+
# n1 n2 ... r1 r2 ... n1 n2 ...
1311+
# A B C
1312+
# This way any dependency from a native library to a rust library
1313+
# is resolved from A to B, and any dependency from a rust library to
1314+
# a native one is resolved from B to C.
1315+
# The question of resolving dependencies from a native library from A
1316+
# to any rust library is addressed in a different place, where we
1317+
# create symlinks to the rlibs, pretending they are native libraries,
1318+
# and adding references to these symlinks in the native section A.
1319+
# We rely in the behavior of -Clink-arg to put the linker args
1320+
# at the end of the linker invocation constructed by rustc.
13041321
return [
13051322
"-lstatic%s=%s" % (modifiers, get_lib_name(artifact)),
1323+
"-Clink-arg=-l%s" % get_lib_name(artifact),
13061324
]
13071325
elif _is_dylib(lib):
13081326
return [

test/unit/native_deps/native_deps_test.bzl

+4
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ def _cdylib_has_native_libs_test_impl(ctx):
3030
assert_argv_contains_prefix_suffix(env, action, "-Lnative=", "/native_deps")
3131
assert_argv_contains(env, action, "--crate-type=cdylib")
3232
assert_argv_contains(env, action, "-lstatic=native_dep")
33+
assert_argv_contains(env, action, "-Clink-arg=-lnative_dep")
3334
assert_argv_contains_prefix(env, action, "--codegen=linker=")
3435
return analysistest.end(env)
3536

@@ -40,6 +41,7 @@ def _staticlib_has_native_libs_test_impl(ctx):
4041
assert_argv_contains_prefix_suffix(env, action, "-Lnative=", "/native_deps")
4142
assert_argv_contains(env, action, "--crate-type=staticlib")
4243
assert_argv_contains(env, action, "-lstatic=native_dep")
44+
assert_argv_contains(env, action, "-Clink-arg=-lnative_dep")
4345
assert_argv_contains_prefix(env, action, "--codegen=linker=")
4446
return analysistest.end(env)
4547

@@ -51,6 +53,7 @@ def _proc_macro_has_native_libs_test_impl(ctx):
5153
assert_argv_contains_prefix_suffix(env, action, "-Lnative=", "/native_deps")
5254
assert_argv_contains(env, action, "--crate-type=proc-macro")
5355
assert_argv_contains(env, action, "-lstatic=native_dep")
56+
assert_argv_contains(env, action, "-Clink-arg=-lnative_dep")
5457
assert_argv_contains_prefix(env, action, "--codegen=linker=")
5558
return analysistest.end(env)
5659

@@ -60,6 +63,7 @@ def _bin_has_native_libs_test_impl(ctx):
6063
action = tut.actions[0]
6164
assert_argv_contains_prefix_suffix(env, action, "-Lnative=", "/native_deps")
6265
assert_argv_contains(env, action, "-lstatic=native_dep")
66+
assert_argv_contains(env, action, "-Clink-arg=-lnative_dep")
6367
assert_argv_contains_prefix(env, action, "--codegen=linker=")
6468
return analysistest.end(env)
6569

0 commit comments

Comments
 (0)