Migrate rules_rust to the new Starlark C++ toolchain API (#133)
This is needed for rules_rust to be forward compatible with Bazel 0.20.
Tracking issues for migration:
* https://github.com/bazelbuild/bazel/issues/6380
* https://github.com/bazelbuild/bazel/issues/6434
Fixes #131.
diff --git a/WORKSPACE b/WORKSPACE
index cd69e6f..8e259c5 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -59,3 +59,13 @@
"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")
diff --git a/rust/private/rust.bzl b/rust/private/rust.bzl
index e05f105..952b67e 100644
--- a/rust/private/rust.bzl
+++ b/rust/private/rust.bzl
@@ -192,6 +192,7 @@
],
single_file = True,
),
+ "_cc_toolchain": attr.label(default = "@bazel_tools//tools/cpp:current_cc_toolchain"),
}
_rust_library_attrs = {
@@ -202,6 +203,7 @@
_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"],
)
@@ -318,6 +320,7 @@
_rust_binary_impl,
attrs = _rust_common_attrs,
executable = True,
+ fragments = ["cpp"],
host_fragments = ["cpp"],
toolchains = ["@io_bazel_rules_rust//rust:toolchain"],
)
@@ -449,6 +452,7 @@
_rust_test_impl,
attrs = _rust_common_attrs,
executable = True,
+ fragments = ["cpp"],
host_fragments = ["cpp"],
test = True,
toolchains = ["@io_bazel_rules_rust//rust:toolchain"],
@@ -618,6 +622,7 @@
_rust_benchmark_impl,
attrs = _rust_common_attrs,
executable = True,
+ fragments = ["cpp"],
host_fragments = ["cpp"],
toolchains = ["@io_bazel_rules_rust//rust:toolchain"],
)
diff --git a/rust/private/rustc.bzl b/rust/private/rustc.bzl
index 80acea5..0bd7c44 100644
--- a/rust/private/rustc.bzl
+++ b/rust/private/rustc.bzl
@@ -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 = {
@@ -178,20 +188,37 @@
if ctx.file.out_dir_tar:
compile_inputs.append(ctx.file.out_dir_tar)
+ rpaths = _compute_rpaths(toolchain, output_dir, depinfo)
+
+ 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)
+
# Paths to cc (for linker) and ar
cpp_fragment = ctx.host_fragments.cpp
- cc = cpp_fragment.compiler_executable
- ar = cpp_fragment.ar_executable
-
- # 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"
-
- rpaths = _compute_rpaths(toolchain, output_dir, depinfo)
+ 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)
@@ -222,9 +249,8 @@
# 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,
@@ -232,7 +258,6 @@
"--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 +
@@ -268,7 +293,7 @@
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,
@@ -276,10 +301,10 @@
))
# 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):
"""
diff --git a/workspace.bzl b/workspace.bzl
new file mode 100644
index 0000000..773a41d
--- /dev/null
+++ b/workspace.bzl
@@ -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,
+)