Skip to content

Commit

Permalink
rustc: add support for alwayslink library dependencies
Browse files Browse the repository at this point in the history
This follows up on the previous commit's refactoring and actually adds
alwayslink support.

Fixes #325.
  • Loading branch information
durin42 committed Feb 26, 2021
1 parent 6c7911b commit 93ff654
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 14 deletions.
48 changes: 38 additions & 10 deletions rust/private/rustc.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -821,16 +821,37 @@ def _get_crate_dirname(crate):
"""
return crate.output.dirname

def _make_link_flags(lib):
args = []
f = get_preferred_artifact(lib)
if lib.alwayslink:
pass # TODO
elif lib.static_library or lib.pic_static_library:
args.append("-lstatic=%s" % get_lib_name(f))
def _portable_link_flags(lib):
if lib.static_library or lib.pic_static_library:
return ["-lstatic=%s" % get_lib_name(get_preferred_artifact(lib))]
elif _is_dylib(lib):
args.append("-ldylib=%s" % get_lib_name(f))
return args
return ["-ldylib=%s" % get_lib_name(get_preferred_artifact(lib))]
return []

def _make_link_flags_windows(lib):
if lib.alwayslink:
return ["-C", "link-arg=/WHOLEARCHIVE:%s" % get_preferred_artifact(lib).path]
return _portable_link_flags(lib)

def _make_link_flags_darwin(lib):
if lib.alwayslink:
return [
"-C",
("link-arg=-Wl,-force_load,%s" % get_preferred_artifact(lib).path),
]
return _portable_link_flags(lib)

def _make_link_flags_default(lib):
if lib.alwayslink:
return [
"-C",
"link-arg=-Wl,--whole-archive",
"-C",
("link-arg=%s" % get_preferred_artifact(lib).path),
"-C",
"link-arg=-Wl,--no-whole-archive",
]
return _portable_link_flags(lib)

def _preferred_artifact_dirname(lib):
return get_preferred_artifact(lib).dirname
Expand All @@ -852,7 +873,14 @@ def _add_native_link_flags(args, dep_info, crate_type, toolchain, cc_toolchain,
if crate_type in ["lib", "rlib"]:
return

args.add_all(dep_info.transitive_noncrates, map_each = _make_link_flags)
if "windows" in toolchain.os:
make_link_flags = _make_link_flags_windows
elif toolchain.os.startswith("mac") or toolchain.os.startswith("darwin"):
make_link_flags = _make_link_flags_darwin
else:
make_link_flags = _make_link_flags_default

args.add_all(dep_info.transitive_noncrates, map_each = make_link_flags)

if crate_type in ["dylib", "cdylib"]:
# For shared libraries we want to link C++ runtime library dynamically
Expand Down
27 changes: 23 additions & 4 deletions test/unit/native_deps/native_deps_test.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -104,24 +104,43 @@ def _bin_has_native_libs_test_impl(ctx):
return analysistest.end(env)

def _extract_linker_args(argv):
return [a for a in argv if a.startswith("link-arg=-Wl") or a.startswith("link-arg=-l") or a.startswith("-l")]
return [a for a in argv if a.startswith("link-arg=-Wl") or a.startswith("link-arg=-l") or a.startswith("-l") or a.endswith(".lo") or a.endswith(".o")]

def _bin_has_native_dep_and_alwayslink_test_impl(ctx):
env = analysistest.begin(ctx)
tut = analysistest.target_under_test(env)
actions = analysistest.target_actions(env)
action = actions[0]

# BUG: this should mention the alwayslink library, but doesn't
asserts.equals(env, _extract_linker_args(action.argv), ["-lstatic=native_dep"])
if ctx.target_platform_has_constraint(ctx.attr._macos_constraint[platform_common.ConstraintValueInfo]):
want = [
"-lstatic=native_dep",
"link-arg=-Wl,-force_load,bazel-out/darwin-fastbuild/bin/test/unit/native_deps/libalwayslink.lo",
]
elif ctx.target_platform_has_constraint(ctx.attr._windows_constraint[platform_common.ConstraintValueInfo]):
want = [
"-lstatic=native_dep",
"link-arg=/WHOLEARCHIVE:bazel-out/x64_windows-fastbuild/bin/test/unit/native_deps/libalwayslink.lo",
]
else:
want = [
"-lstatic=native_dep",
"link-arg=-Wl,--whole-archive",
"link-arg=bazel-out/k8-fastbuild/bin/test/unit/native_deps/libalwayslink.lo",
"link-arg=-Wl,--no-whole-archive",
]
asserts.equals(env, want, _extract_linker_args(action.argv))
return analysistest.end(env)

rlib_has_no_native_libs_test = analysistest.make(_rlib_has_no_native_libs_test_impl)
staticlib_has_native_libs_test = analysistest.make(_staticlib_has_native_libs_test_impl)
cdylib_has_native_libs_test = analysistest.make(_cdylib_has_native_libs_test_impl)
proc_macro_has_native_libs_test = analysistest.make(_proc_macro_has_native_libs_test_impl)
bin_has_native_libs_test = analysistest.make(_bin_has_native_libs_test_impl)
bin_has_native_dep_and_alwayslink_test = analysistest.make(_bin_has_native_dep_and_alwayslink_test_impl)
bin_has_native_dep_and_alwayslink_test = analysistest.make(_bin_has_native_dep_and_alwayslink_test_impl, attrs = {
"_macos_constraint": attr.label(default = Label("@platforms//os:macos")),
"_windows_constraint": attr.label(default = Label("@platforms//os:windows")),
})

def _native_dep_test():
rust_library(
Expand Down

0 comments on commit 93ff654

Please sign in to comment.