From b3cc7e4d5d0ba64064ec2311aab00c1bffb49526 Mon Sep 17 00:00:00 2001 From: Marco Farrugia Date: Mon, 1 Apr 2019 11:42:11 -0400 Subject: [PATCH] #190, #200 :: Migrate to new cc provider. (#209) * #190, #200 :: Migrate to new cc provider. * re-replace dep.cc.libs --- bindgen/bindgen.bzl | 25 ++++++++++++-------- rust/private/legacy_cc_starlark_api_shim.bzl | 24 +++++++++++++++++++ rust/private/rustc.bzl | 13 ++++++---- 3 files changed, 47 insertions(+), 15 deletions(-) create mode 100644 rust/private/legacy_cc_starlark_api_shim.bzl diff --git a/bindgen/bindgen.bzl b/bindgen/bindgen.bzl index f0d6fb7246..cde7d21654 100644 --- a/bindgen/bindgen.bzl +++ b/bindgen/bindgen.bzl @@ -13,6 +13,7 @@ # limitations under the License. load("@io_bazel_rules_rust//rust:rust.bzl", "rust_library") +load("@io_bazel_rules_rust//rust:private/legacy_cc_starlark_api_shim.bzl", "get_libs_for_static_executable") def rust_bindgen_library( name, @@ -44,7 +45,7 @@ def _rust_bindgen_impl(ctx): # nb. We can't grab the cc_library`s direct headers, so a header must be provided. cc_lib = ctx.attr.cc_lib header = ctx.file.header - if header not in cc_lib.cc.transitive_headers: + if header not in cc_lib[CcInfo].compilation_context.headers: fail("Header {} is not in {}'s transitive headers.".format(ctx.attr.header, cc_lib), "header") toolchain = ctx.toolchains["@io_bazel_rules_rust//bindgen:bindgen_toolchain"] @@ -68,10 +69,10 @@ def _rust_bindgen_impl(ctx): output = ctx.outputs.out # libclang should only have 1 output file - libclang_dir = libclang.cc.libs.to_list()[0].dirname - include_directories = cc_lib.cc.include_directories - quote_include_directories = cc_lib.cc.quote_include_directories - system_include_directories = cc_lib.cc.system_include_directories + libclang_dir = get_libs_for_static_executable(libclang).to_list()[0].dirname + include_directories = cc_lib[CcInfo].compilation_context.includes.to_list() + quote_include_directories = cc_lib[CcInfo].compilation_context.quote_includes.to_list() + system_include_directories = cc_lib[CcInfo].compilation_context.system_includes.to_list() # Vanilla usage of bindgen produces formatted output, here we do the same if we have `rustfmt` in our toolchain. if rustfmt_bin: @@ -92,7 +93,11 @@ def _rust_bindgen_impl(ctx): executable = bindgen_bin, inputs = depset( [header], - transitive = [cc_lib.cc.transitive_headers, libclang.cc.libs, libstdcxx.cc.libs], + transitive = [ + cc_lib[CcInfo].compilation_context.headers, + get_libs_for_static_executable(libclang), + get_libs_for_static_executable(libstdcxx), + ], ), outputs = [unformatted_output], mnemonic = "RustBindgen", @@ -102,7 +107,7 @@ def _rust_bindgen_impl(ctx): "CLANG_PATH": clang_bin.path, # Bindgen loads libclang at runtime, which also needs libstdc++, so we setup LD_LIBRARY_PATH "LIBCLANG_PATH": libclang_dir, - "LD_LIBRARY_PATH": ":".join([f.dirname for f in libstdcxx.cc.libs]), + "LD_LIBRARY_PATH": ":".join([f.dirname for f in get_libs_for_static_executable(libstdcxx)]), }, arguments = [args], tools = [clang_bin], @@ -126,7 +131,7 @@ rust_bindgen = rule( ), "cc_lib": attr.label( doc = "The cc_library that contains the .h file. This is used to find the transitive includes.", - providers = ["cc"], + providers = [CcInfo], ), "bindgen_flags": attr.string_list( doc = "Flags to pass directly to the bindgen executable. See https://rust-lang.github.io/rust-bindgen/ for details.", @@ -173,12 +178,12 @@ rust_bindgen_toolchain = rule( "libclang": attr.label( doc = "A cc_library that provides bindgen's runtime dependency on libclang.", cfg = "host", - providers = ["cc"], + providers = [CcInfo], ), "libstdcxx": attr.label( doc = "A cc_library that satisfies libclang's libstdc++ dependency.", cfg = "host", - providers = ["cc"], + providers = [CcInfo], ), }, ) diff --git a/rust/private/legacy_cc_starlark_api_shim.bzl b/rust/private/legacy_cc_starlark_api_shim.bzl new file mode 100644 index 0000000000..b0470a2088 --- /dev/null +++ b/rust/private/legacy_cc_starlark_api_shim.bzl @@ -0,0 +1,24 @@ +""" +Part of --incompatible_disable_legacy_cc_provider migration (https://github.com/bazelbuild/bazel/issues/7036) +""" + +def get_libs_for_static_executable(dep): + """ + This replaces dep.cc.libs, which found the libraries + used for linking a static executable. + + Args: + dep: A cc_library target. + Returns: + A depset[File] + """ + libraries_to_link = dep[CcInfo].linking_context.libraries_to_link + return depset([_get_preferred_artifact(lib) for lib in libraries_to_link]) + +def _get_preferred_artifact(library_to_link): + return ( + library_to_link.static_library or + library_to_link.pic_static_library or + library_to_link.interface_library or + library_to_link.dynamic_library + ) diff --git a/rust/private/rustc.bzl b/rust/private/rustc.bzl index e243f1bf3d..7a8b900db7 100644 --- a/rust/private/rustc.bzl +++ b/rust/private/rustc.bzl @@ -13,6 +13,7 @@ # limitations under the License. load("@io_bazel_rules_rust//rust:private/utils.bzl", "relative_path") +load("@io_bazel_rules_rust//rust:private/legacy_cc_starlark_api_shim.bzl", "get_libs_for_static_executable") load( "@bazel_tools//tools/build_defs/cc:action_names.bzl", "CPP_LINK_EXECUTABLE_ACTION_NAME", @@ -106,10 +107,13 @@ def collect_deps(deps, toolchain): transitive_crates = depset(transitive = [transitive_crates, dep[DepInfo].transitive_crates]) transitive_dylibs = depset(transitive = [transitive_dylibs, dep[DepInfo].transitive_dylibs]) transitive_staticlibs = depset(transitive = [transitive_staticlibs, dep[DepInfo].transitive_staticlibs]) - elif hasattr(dep, "cc"): + elif CcInfo in dep: # This dependency is a cc_library - dylibs = [l for l in dep.cc.libs.to_list() if l.basename.endswith(toolchain.dylib_ext)] - staticlibs = [l for l in dep.cc.libs.to_list() if l.basename.endswith(toolchain.staticlib_ext)] + + # 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) + 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)]) else: @@ -182,8 +186,7 @@ def rustc_compile_action( toolchain, ) - linker_script = getattr(ctx.file, "linker_script") if hasattr(ctx.file, "linker_script") \ - else None + linker_script = getattr(ctx.file, "linker_script") if hasattr(ctx.file, "linker_script") else None compile_inputs = depset( crate_info.srcs +