Skip to content

Commit

Permalink
Migrate rules_rust to the new Starlark C++ toolchain API (bazelbuild#133
Browse files Browse the repository at this point in the history
)

This is needed for rules_rust to be forward compatible with Bazel 0.20.
Tracking issues for migration:

* bazelbuild/bazel#6380
* bazelbuild/bazel#6434

Fixes bazelbuild#131.
  • Loading branch information
hlopko committed Oct 22, 2018
1 parent f8ad072 commit e7e5d6f
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 20 deletions.
10 changes: 10 additions & 0 deletions WORKSPACE
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,13 @@ http_archive(
"https://github.com/bazelbuild/bazel-toolchains/archive/cdea5b8675914d0a354d89f108de5d28e54e0edc.tar.gz",
],
)

http_archive(
name = "bazel_skylib",
url = "https://github.com/bazelbuild/bazel-skylib/archive/0.5.0.tar.gz",
sha256 = "b5f6abe419da897b7901f90cbab08af958b97a8f3575b0d3dd062ac7ce78541f",
strip_prefix = "bazel-skylib-0.5.0"
)

load(":workspace.bzl", "bazel_version")
bazel_version(name = "bazel_version")
5 changes: 5 additions & 0 deletions rust/private/rust.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,7 @@ _rust_common_attrs = {
],
single_file = True,
),
"_cc_toolchain": attr.label(default = "@bazel_tools//tools/cpp:current_cc_toolchain"),
}

_rust_library_attrs = {
Expand All @@ -202,6 +203,7 @@ rust_library = rule(
_rust_library_impl,
attrs = dict(_rust_common_attrs.items() +
_rust_library_attrs.items()),
fragments = ["cpp"],
host_fragments = ["cpp"],
toolchains = ["@io_bazel_rules_rust//rust:toolchain"],
)
Expand Down Expand Up @@ -318,6 +320,7 @@ rust_binary = rule(
_rust_binary_impl,
attrs = _rust_common_attrs,
executable = True,
fragments = ["cpp"],
host_fragments = ["cpp"],
toolchains = ["@io_bazel_rules_rust//rust:toolchain"],
)
Expand Down Expand Up @@ -449,6 +452,7 @@ rust_test = rule(
_rust_test_impl,
attrs = _rust_common_attrs,
executable = True,
fragments = ["cpp"],
host_fragments = ["cpp"],
test = True,
toolchains = ["@io_bazel_rules_rust//rust:toolchain"],
Expand Down Expand Up @@ -618,6 +622,7 @@ rust_benchmark = rule(
_rust_benchmark_impl,
attrs = _rust_common_attrs,
executable = True,
fragments = ["cpp"],
host_fragments = ["cpp"],
toolchains = ["@io_bazel_rules_rust//rust:toolchain"],
)
Expand Down
65 changes: 45 additions & 20 deletions rust/private/rustc.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,16 @@
# limitations under the License.

load(":private/utils.bzl", "find_toolchain", "relative_path")
load(
"@bazel_tools//tools/build_defs/cc:action_names.bzl",
"CPP_LINK_EXECUTABLE_ACTION_NAME",
)
load(
"@bazel_tools//tools/cpp:toolchain_utils.bzl",
"find_cpp_toolchain",
)
load("@bazel_skylib//lib:versions.bzl", "versions")
load("@bazel_version//:def.bzl", "BAZEL_VERSION")

CrateInfo = provider(
fields = {
Expand Down Expand Up @@ -178,20 +188,37 @@ def rustc_compile_action(
if ctx.file.out_dir_tar:
compile_inputs.append(ctx.file.out_dir_tar)

# Paths to cc (for linker) and ar
cpp_fragment = ctx.host_fragments.cpp
cc = cpp_fragment.compiler_executable
ar = cpp_fragment.ar_executable
rpaths = _compute_rpaths(toolchain, output_dir, depinfo)

# Currently, the CROSSTOOL config for darwin sets ar to "libtool". Because
# rust uses ar-specific flags, use /usr/bin/ar in this case.
# TODO(dzc): This is not ideal. Remove this workaround once ar_executable
# always points to an ar binary.
ar_str = "%s" % ar
if ar_str.find("libtool", 0) != -1:
ar = "/usr/bin/ar"
if versions.is_at_least("0.18.0", BAZEL_VERSION):
user_link_flags = ctx.fragments.cpp.linkopts
else:
user_link_flags = depset(ctx.fragments.cpp.linkopts)

rpaths = _compute_rpaths(toolchain, output_dir, depinfo)
# Paths to cc (for linker) and ar
cpp_fragment = ctx.host_fragments.cpp
cc_toolchain = find_cpp_toolchain(ctx)
feature_configuration = cc_common.configure_features(
cc_toolchain = cc_toolchain,
requested_features = ctx.features,
unsupported_features = ctx.disabled_features,
)
ld = cc_common.get_tool_for_action(
feature_configuration = feature_configuration,
action_name = CPP_LINK_EXECUTABLE_ACTION_NAME,
)
link_variables = cc_common.create_link_variables(
feature_configuration = feature_configuration,
cc_toolchain = cc_toolchain,
is_linking_dynamic_library = False,
runtime_library_search_directories = rpaths,
user_link_flags = user_link_flags,
)
link_options = cc_common.get_memory_inefficient_command_line(
feature_configuration = feature_configuration,
action_name = CPP_LINK_EXECUTABLE_ACTION_NAME,
variables = link_variables,
)

# Construct features flags
features_flags = _get_features_flags(ctx.attr.crate_features)
Expand Down Expand Up @@ -222,17 +249,15 @@ def rustc_compile_action(
# Mangle symbols to disambiguate crates with the same name
"--codegen metadata=%s" % extra_filename,
"--codegen extra-filename='%s'" % extra_filename,
"--codegen ar=%s" % ar,
"--codegen linker=%s" % cc,
"--codegen link-args='%s'" % " ".join(cpp_fragment.link_options),
"--codegen linker=%s" % ld,
"--codegen link-args='%s'" % " ".join(link_options),
"--remap-path-prefix {}={}".format("$(pwd)", "__bazel_redacted_pwd"),
"--out-dir",
output_dir,
"--emit=dep-info,link",
"--color always",
"--target=" + toolchain.target_triple,
] +
["--codegen link-arg='-Wl,-rpath={}'".format(rpath) for rpath in rpaths] +
features_flags +
rust_flags +
depinfo.link_search_flags +
Expand Down Expand Up @@ -268,18 +293,18 @@ def _compute_rpaths(toolchain, output_dir, depinfo):
for runtime linking of shared libraries.
"""
if not depinfo.transitive_dylibs:
return []
return depset([])
if toolchain.os != "linux":
fail("Runtime linking is not supported on {}, but found {}".format(
toolchain.os,
depinfo.transitive_dylibs,
))

# Multiple dylibs can be present in the same directory, so deduplicate them.
return [
"$ORIGIN/" + relative_path(output_dir, lib_dir)
return depset([
relative_path(output_dir, lib_dir)
for lib_dir in _get_dir_names(depinfo.transitive_dylibs)
]
])

def _get_features_flags(features):
"""
Expand Down
12 changes: 12 additions & 0 deletions workspace.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
load("@bazel_skylib//lib:versions.bzl", "versions")

def _store_bazel_version(repository_ctx):
bazel_version = versions.get();
if versions.is_at_most("0.17.0", bazel_version):
fail("Bazel %s is too old to use with rules_rust, please use at least Bazel 0.17.1, preferably newer." % bazel_version)
repository_ctx.file("BUILD", "exports_files(['def.bzl'])")
repository_ctx.file("def.bzl", "BAZEL_VERSION='" + bazel_version + "'")

bazel_version = repository_rule(
implementation = _store_bazel_version,
)

0 comments on commit e7e5d6f

Please sign in to comment.