Skip to content

Commit 4da6858

Browse files
krasimirggUebelAndrehlopko
authored
Use library paths instead of -Lnative/-lstatic when linking native dependencies (#841)
* update static library naming mixed rust+cc deps Fixes static library naming issues that cause the build of a rust_binary that depends on a cc_library that itself depends on a rust_library to fail. Consider a rust_binary that depends on a cc_library that itself depends on a rust_library: ``` . ├── bin.rs ├── BUILD └── lib.rs ``` ```rust // bin.rs fn main() { println!("hi"); } ``` ```rust // lib.rs: empty ``` ```bazel load("@rules_rust//rust:defs.bzl", "rust_benchmark", "rust_binary", "rust_library") rust_library( name = "rust_lib", srcs = ["lib.rs"], ) cc_library( name = "cc_lib", srcs = [], deps = [":rust_lib"], ) rust_binary( name = "bin", srcs = ["bin.rs"], deps = [":cc_lib"], ) ``` Running `bazel build //project:bin` runs into linker errors like: ``` /usr/bin/ld.gold: error: cannot find -lrust_lib /usr/bin/ld.gold: error: cannot find -lrustc_std_workspace_alloc-1ff59d4f23b10626 ``` This is because the linker expects the static library corresponding to `-lname` to be named `libname.a`. Also Bazel CC link actions get confused by static library names that have multiple dots, e.g., end in "libcrate.rlib.a", so updated the scripts to produce them as "libcrate-rlib.a" instead. * don't pass panic_abort if panic_unwind is present Fixes an issue that causes the build of a rust_binary that depends on a cc_library that depends on a rust_library to fail. Consider a rust_binary that depends on a cc_library that itself depends on a rust_library: ``` . ├── bin.rs ├── BUILD └── lib.rs ``` ```rust // bin.rs fn main() { println!("hi"); } ``` ```rust // lib.rs: empty ``` ```bazel load("@rules_rust//rust:defs.bzl", "rust_benchmark", "rust_binary", "rust_library") rust_library( name = "rust_lib", srcs = ["lib.rs"], ) cc_library( name = "cc_lib", srcs = [], deps = [":rust_lib"], ) rust_binary( name = "bin", srcs = ["bin.rs"], deps = [":cc_lib"], ) ``` Running `bazel build //project:bin` runs into linker errors like: /usr/bin/ld.gold: error: bazel-out/k8-fastbuild/bin/external/rust_linux_x86_64/lib/rustlib/x86_64-unknown-linux-gnu/lib/libpanic_unwind-5f5ff14665a8d5c5-rlib.a(panic_unwind-5f5ff14665a8d5c5.panic_unwind.p9ngf95o-cgu.0.rcgu.o): multiple definition of '__rust_panic_cleanup' /usr/bin/ld.gold: bazel-out/k8-fastbuild/bin/external/rust_linux_x86_64/lib/rustlib/x86_64-unknown-linux-gnu/lib/libpanic_abort-c6166278e71d9daf-rlib.a(panic_abort-c6166278e71d9daf.panic_abort.4p8k2zko-cgu.0.rcgu.o): previous definition here That's because we're passing both panic_unwind and panic_abort to the linker. The standard library by default depends on panic_unwind. This updates the rules to prefer panic_unwind. It would be nice to have an option for the user to pick the panic runtime similarly to how it could be done upstream: https://rustc-dev-guide.rust-lang.org/panic-implementation.html#step-2-the-panic-runtime * rename test/unit/stdlib_ordering to /test/unit/stdlib I'll add a additional test case there. * add tests * restrict test assert to only rlibs and libs This should address the Windows buildbot failure. * move panic_{unwind,abort} filtering to _make_libstd_and_allocator_ccinfo * remove `-rlib` postfix from the names of static library symlinks * move _make_dota to utils * remove postfix argument docstring * when linking, emit the path to a native lib instead of -lnativelibname * fix native_deps_test for mac and windows * don't emit `-Lnative=package` for native libraries * Bring back `-Lnative` for dynamic libs They are needed to compile the examples. * also handle dylibs via `-Clink-arg` * Put back -ldylib for dylibs Trying out to build them with -Clink-arg produces test binaries that fail to find the dynamic library at runtime, e.g; https://buildkite.com/bazel/rules-rust-rustlang/builds/3850#d19409bc-a30a-4944-9f81-e5da5e9d06a6 /var/lib/buildkite-agent/.cache/bazel/_bazel_buildkite-agent/ec321eb2cc2d0f8f91b676b6d4c66c29/sandbox/linux-sandbox/1458/execroot/rules_rust/bazel-out/k8-fastbuild/bin/external/examples/ffi/rust_calling_c/matrix_dylib_test.launcher.runfiles/rules_rust/external/examples/ffi/rust_calling_c/matrix_dylib_test: error while loading shared libraries: bazel-out/k8-fastbuild/bin/_solib_k8/_U@examples_S_Sffi_Srust_Ucalling_Uc_Sc_Cnative_Umatrix_Uso___Uexternal_Sexamples_Sffi_Srust_Ucalling_Uc_Sc/libnative_matrix_so.so: cannot open shared object file: No such file or directory Added a TODO to investigate. Co-authored-by: UebelAndre <github@uebelandre.com> Co-authored-by: Marcel Hlopko <hlopko@google.com>
1 parent ac7378f commit 4da6858

File tree

2 files changed

+37
-22
lines changed

2 files changed

+37
-22
lines changed

rust/private/rustc.bzl

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -837,9 +837,14 @@ def _get_crate_dirname(crate):
837837

838838
def _portable_link_flags(lib):
839839
if lib.static_library or lib.pic_static_library:
840-
return ["-lstatic=%s" % get_lib_name(get_preferred_artifact(lib))]
840+
return ["-C", "link-arg=%s" % get_preferred_artifact(lib).path]
841841
elif _is_dylib(lib):
842-
return ["-ldylib=%s" % get_lib_name(get_preferred_artifact(lib))]
842+
# TODO: Consider switching dylibs to use -Clink-arg as above.
843+
return [
844+
"-Lnative=%s" % get_preferred_artifact(lib).dirname,
845+
"-ldylib=%s" % get_lib_name(get_preferred_artifact(lib)),
846+
]
847+
843848
return []
844849

845850
def _make_link_flags_windows(linker_input):
@@ -894,8 +899,6 @@ def _add_native_link_flags(args, dep_info, crate_type, toolchain, cc_toolchain,
894899
feature_configuration (FeatureConfiguration): feature configuration to use with cc_toolchain
895900
896901
"""
897-
args.add_all(dep_info.transitive_noncrates, map_each = _libraries_dirnames, uniquify = True, format_each = "-Lnative=%s")
898-
899902
if crate_type in ["lib", "rlib"]:
900903
return
901904

test/unit/native_deps/native_deps_test.bzl

Lines changed: 30 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,12 @@ 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")
66
load("//test/unit:common.bzl", "assert_argv_contains", "assert_argv_contains_not", "assert_argv_contains_prefix_suffix")
77

8+
def _native_dep_lib_name(ctx):
9+
if ctx.target_platform_has_constraint(ctx.attr._windows_constraint[platform_common.ConstraintValueInfo]):
10+
return "native_dep.lib"
11+
else:
12+
return "libnative_dep.a"
13+
814
def _lib_has_no_native_libs_test_impl(ctx):
915
env = analysistest.begin(ctx)
1016
tut = analysistest.target_under_test(env)
@@ -22,7 +28,6 @@ def _rlib_has_no_native_libs_test_impl(ctx):
2228
actions = analysistest.target_actions(env)
2329
action = actions[0]
2430
assert_argv_contains(env, action, "--crate-type=rlib")
25-
assert_argv_contains_prefix_suffix(env, action, "-Lnative=", "/native_deps")
2631
assert_argv_contains_not(env, action, "-lstatic=native_dep")
2732
assert_argv_contains_not(env, action, "-ldylib=native_dep")
2833
return analysistest.end(env)
@@ -32,7 +37,6 @@ def _dylib_has_native_libs_test_impl(ctx):
3237
tut = analysistest.target_under_test(env)
3338
actions = analysistest.target_actions(env)
3439
action = actions[0]
35-
assert_argv_contains_prefix_suffix(env, action, "-Lnative=", "/native_deps")
3640
assert_argv_contains(env, action, "--crate-type=dylib")
3741
assert_argv_contains(env, action, "-lstatic=native_dep")
3842
return analysistest.end(env)
@@ -42,19 +46,17 @@ def _cdylib_has_native_libs_test_impl(ctx):
4246
tut = analysistest.target_under_test(env)
4347
actions = analysistest.target_actions(env)
4448
action = actions[0]
45-
assert_argv_contains_prefix_suffix(env, action, "-Lnative=", "/native_deps")
4649
assert_argv_contains(env, action, "--crate-type=cdylib")
47-
assert_argv_contains(env, action, "-lstatic=native_dep")
50+
assert_argv_contains_prefix_suffix(env, action, "link-arg=", "/native_deps/" + _native_dep_lib_name(ctx))
4851
return analysistest.end(env)
4952

5053
def _staticlib_has_native_libs_test_impl(ctx):
5154
env = analysistest.begin(ctx)
5255
tut = analysistest.target_under_test(env)
5356
actions = analysistest.target_actions(env)
5457
action = actions[0]
55-
assert_argv_contains_prefix_suffix(env, action, "-Lnative=", "/native_deps")
5658
assert_argv_contains(env, action, "--crate-type=staticlib")
57-
assert_argv_contains(env, action, "-lstatic=native_dep")
59+
assert_argv_contains_prefix_suffix(env, action, "link-arg=", "/native_deps/" + _native_dep_lib_name(ctx))
5860
return analysistest.end(env)
5961

6062
def _proc_macro_has_native_libs_test_impl(ctx):
@@ -63,18 +65,16 @@ def _proc_macro_has_native_libs_test_impl(ctx):
6365
actions = analysistest.target_actions(env)
6466
asserts.equals(env, 1, len(actions))
6567
action = actions[0]
66-
assert_argv_contains_prefix_suffix(env, action, "-Lnative=", "/native_deps")
6768
assert_argv_contains(env, action, "--crate-type=proc-macro")
68-
assert_argv_contains(env, action, "-lstatic=native_dep")
69+
assert_argv_contains_prefix_suffix(env, action, "link-arg=", "/native_deps/" + _native_dep_lib_name(ctx))
6970
return analysistest.end(env)
7071

7172
def _bin_has_native_libs_test_impl(ctx):
7273
env = analysistest.begin(ctx)
7374
tut = analysistest.target_under_test(env)
7475
actions = analysistest.target_actions(env)
7576
action = actions[0]
76-
assert_argv_contains_prefix_suffix(env, action, "-Lnative=", "/native_deps")
77-
assert_argv_contains(env, action, "-lstatic=native_dep")
77+
assert_argv_contains_prefix_suffix(env, action, "link-arg=", "/native_deps/" + _native_dep_lib_name(ctx))
7878
return analysistest.end(env)
7979

8080
def _extract_linker_args(argv):
@@ -88,17 +88,17 @@ def _bin_has_native_dep_and_alwayslink_test_impl(ctx):
8888

8989
if ctx.target_platform_has_constraint(ctx.attr._macos_constraint[platform_common.ConstraintValueInfo]):
9090
want = [
91-
"-lstatic=native_dep",
91+
"link-arg=bazel-out/darwin-fastbuild/bin/test/unit/native_deps/libnative_dep.a",
9292
"link-arg=-Wl,-force_load,bazel-out/darwin-fastbuild/bin/test/unit/native_deps/libalwayslink.lo",
9393
]
9494
elif ctx.target_platform_has_constraint(ctx.attr._windows_constraint[platform_common.ConstraintValueInfo]):
9595
want = [
96-
"-lstatic=native_dep",
96+
"link-arg=bazel-out/x64_windows-fastbuild/bin/test/unit/native_deps/native_dep.lib",
9797
"link-arg=/WHOLEARCHIVE:bazel-out/x64_windows-fastbuild/bin/test/unit/native_deps/alwayslink.lo.lib",
9898
]
9999
else:
100100
want = [
101-
"-lstatic=native_dep",
101+
"link-arg=bazel-out/k8-fastbuild/bin/test/unit/native_deps/libnative_dep.a",
102102
"link-arg=-Wl,--whole-archive",
103103
"link-arg=bazel-out/k8-fastbuild/bin/test/unit/native_deps/libalwayslink.lo",
104104
"link-arg=-Wl,--no-whole-archive",
@@ -124,7 +124,7 @@ def _cdylib_has_native_dep_and_alwayslink_test_impl(ctx):
124124
]
125125
else:
126126
want = [
127-
"-lstatic=native_dep",
127+
"link-arg=bazel-out/k8-fastbuild/bin/test/unit/native_deps/libnative_dep.a",
128128
"link-arg=-Wl,--whole-archive",
129129
"link-arg=bazel-out/k8-fastbuild/bin/test/unit/native_deps/libalwayslink.lo",
130130
"link-arg=-Wl,--no-whole-archive",
@@ -133,10 +133,22 @@ def _cdylib_has_native_dep_and_alwayslink_test_impl(ctx):
133133
return analysistest.end(env)
134134

135135
rlib_has_no_native_libs_test = analysistest.make(_rlib_has_no_native_libs_test_impl)
136-
staticlib_has_native_libs_test = analysistest.make(_staticlib_has_native_libs_test_impl)
137-
cdylib_has_native_libs_test = analysistest.make(_cdylib_has_native_libs_test_impl)
138-
proc_macro_has_native_libs_test = analysistest.make(_proc_macro_has_native_libs_test_impl)
139-
bin_has_native_libs_test = analysistest.make(_bin_has_native_libs_test_impl)
136+
staticlib_has_native_libs_test = analysistest.make(_staticlib_has_native_libs_test_impl, attrs = {
137+
"_macos_constraint": attr.label(default = Label("@platforms//os:macos")),
138+
"_windows_constraint": attr.label(default = Label("@platforms//os:windows")),
139+
})
140+
cdylib_has_native_libs_test = analysistest.make(_cdylib_has_native_libs_test_impl, attrs = {
141+
"_macos_constraint": attr.label(default = Label("@platforms//os:macos")),
142+
"_windows_constraint": attr.label(default = Label("@platforms//os:windows")),
143+
})
144+
proc_macro_has_native_libs_test = analysistest.make(_proc_macro_has_native_libs_test_impl, attrs = {
145+
"_macos_constraint": attr.label(default = Label("@platforms//os:macos")),
146+
"_windows_constraint": attr.label(default = Label("@platforms//os:windows")),
147+
})
148+
bin_has_native_libs_test = analysistest.make(_bin_has_native_libs_test_impl, attrs = {
149+
"_macos_constraint": attr.label(default = Label("@platforms//os:macos")),
150+
"_windows_constraint": attr.label(default = Label("@platforms//os:windows")),
151+
})
140152
bin_has_native_dep_and_alwayslink_test = analysistest.make(_bin_has_native_dep_and_alwayslink_test_impl, attrs = {
141153
"_macos_constraint": attr.label(default = Label("@platforms//os:macos")),
142154
"_windows_constraint": attr.label(default = Label("@platforms//os:windows")),

0 commit comments

Comments
 (0)