Skip to content

Commit

Permalink
Propagate linkopts
Browse files Browse the repository at this point in the history
  • Loading branch information
hlopko committed Nov 6, 2019
1 parent ec436b5 commit 1eae40f
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 3 deletions.
10 changes: 7 additions & 3 deletions WORKSPACE
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,14 @@ local_repository(

http_archive(
name = "bazel_skylib",
sha256 = "eb5c57e4c12e68c0c20bc774bfbc60a568e800d025557bc4ea022c6479acc867",
strip_prefix = "bazel-skylib-0.6.0",
url = "https://github.com/bazelbuild/bazel-skylib/archive/0.6.0.tar.gz",
urls = [
"https://mirror.bazel.build/github.com/bazelbuild/bazel-skylib/releases/download/1.0.2/bazel-skylib-1.0.2.tar.gz",
"https://github.com/bazelbuild/bazel-skylib/releases/download/1.0.2/bazel-skylib-1.0.2.tar.gz",
],
sha256 = "97e70364e9249702246c0e9444bccdc4b847bed1eb03c5a3ece4f83dfe6abc44",
)
load("@bazel_skylib//:workspace.bzl", "bazel_skylib_workspace")
bazel_skylib_workspace()

# TODO: Move this to examples/WORKSPACE when recursive repositories are enabled.
load("@io_bazel_rules_rust//rust:repositories.bzl", "rust_repositories")
Expand Down
14 changes: 14 additions & 0 deletions rust/private/rustc.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ DepInfo = provider(
"transitive_dylibs": "depset[File]",
"transitive_staticlibs": "depset[File]",
"transitive_libs": "List[File]: All transitive dependencies, not filtered by type.",
"linkopts": "list[string]",
},
)

Expand Down Expand Up @@ -101,6 +102,7 @@ def collect_deps(deps, toolchain):
transitive_crates = depset()
transitive_dylibs = depset(order = "topological") # dylib link flag ordering matters.
transitive_staticlibs = depset()
linkopts = []
for dep in deps:
if CrateInfo in dep:
# This dependency is a rust_library
Expand All @@ -114,10 +116,20 @@ def collect_deps(deps, toolchain):

# TODO: We could let the user choose how to link, instead of always preferring to link static libraries.
libs = get_libs_for_static_executable(dep)
# TODO: This is changing the order of linker inputs, it shouldn't.
# In more sophisticated scenarios we need to retain the relative
# order of static/shared libraries. Imagine following libs:
# libs = [ liba.a, libb.so, libc.a ]
# Ideally this will get converted into the following linker command
# line:
# -la -lb -lc
# But the current implementation produces:
# -la -lc -b
dylibs = [l for l in libs.to_list() if l.basename.endswith(toolchain.dylib_ext)]
staticlibs = [l for l in libs.to_list() if l.basename.endswith(toolchain.staticlib_ext)]
transitive_dylibs = depset(transitive = [transitive_dylibs, depset(dylibs)])
transitive_staticlibs = depset(transitive = [transitive_staticlibs, depset(staticlibs)])
linkopts.extend(dep[CcInfo].linking_context.user_link_flags)
else:
fail("rust targets can only depend on rust_library, rust_*_library or cc_library targets." + str(dep), "deps")

Expand All @@ -132,6 +144,7 @@ def collect_deps(deps, toolchain):
transitive_dylibs = transitive_dylibs,
transitive_staticlibs = transitive_staticlibs,
transitive_libs = transitive_libs.to_list(),
linkopts = linkopts,
)

def _get_linker_and_args(ctx, rpaths):
Expand Down Expand Up @@ -399,6 +412,7 @@ def add_native_link_flags(args, dep_info):
args.add_all(native_libs, map_each = _get_dirname, uniquify = True, format_each = "-Lnative=%s")
args.add_all(dep_info.transitive_dylibs, map_each = get_lib_name, format_each = "-ldylib=%s")
args.add_all(dep_info.transitive_staticlibs, map_each = get_lib_name, format_each = "-lstatic=%s")
args.add_all(dep_info.linkopts, uniquify = False)

def _get_dirname(file):
return file.dirname
3 changes: 3 additions & 0 deletions test/analysis/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
load(":native_deps_test.bzl", "native_deps_test_suite")

native_deps_test_suite(name = "native_deps_test_suite")
42 changes: 42 additions & 0 deletions test/analysis/native_deps_test.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
load("@rules_cc//cc:defs.bzl", "cc_library")
load("@bazel_skylib//lib:unittest.bzl", "analysistest", "asserts")
load("//rust:rust.bzl", "rust_binary")

def _linkopts_test_impl(ctx):
env = analysistest.begin(ctx)

subject = analysistest.target_under_test(env)
actions = analysistest.target_actions(env)

asserts.true(env, "-lsystem_lib" in actions[0].argv)

return analysistest.end(env)

linkopts_test = analysistest.make(_linkopts_test_impl)

def _linkopts_test():
cc_library(
name = "native",
linkopts = ["-lsystem_lib"],
tags = ["manual"],
)
rust_binary(
name = "main",
deps = [":native"],
srcs = ["main.rs"],
tags = ["manual"],
)
linkopts_test(
name = "linkopts_test",
target_under_test = ":main",
)

def native_deps_test_suite(name):
_linkopts_test()

native.test_suite(
name = name,
tests = [
":linkopts_test",
],
)

0 comments on commit 1eae40f

Please sign in to comment.