diff options
author | Chris Parsons <cparsons@google.com> | 2021-05-06 16:19:36 -0400 |
---|---|---|
committer | Chris Parsons <cparsons@google.com> | 2021-05-10 17:36:03 -0400 |
commit | e886afbac8f7f065090f1e4bc41afa7f131d98c7 (patch) | |
tree | 9292676ee8e3dc70d0651ce8b18491998848e4a0 | |
parent | 4b84cb8e30f2995ac91b1038c69f200dc374014e (diff) | |
download | bazel-e886afbac8f7f065090f1e4bc41afa7f131d98c7.tar.gz |
Fix shared library variants for full_cc_library
1. Add attributes specific to shared/static variants
2. Fix static library macro so that the proxy target "claims ownership"
of all linker inputs owned by the target it is proxying. The result is
that cc_shared_library will correctly identify this proxy target as
the actual root, for purposes of exporting whole archives.
3. Separate whole_archive_deps from other types of deps (to
differentiate between whole_static_libs and static_libs from Soong)
Test: bp2build.sh CI script in conjunction with bp2build changes.
Change-Id: Idff0d78bdd2874fdf8c4fd74df99a45e83432049
-rw-r--r-- | rules/cc_library_static.bzl | 28 | ||||
-rw-r--r-- | rules/full_cc_library.bzl | 42 |
2 files changed, 61 insertions, 9 deletions
diff --git a/rules/cc_library_static.bzl b/rules/cc_library_static.bzl index 78a2d8ee..d9b3c743 100644 --- a/rules/cc_library_static.bzl +++ b/rules/cc_library_static.bzl @@ -8,6 +8,7 @@ def cc_library_static( copts = [], includes = [], native_bridge_supported = False, # TODO: not supported yet. + whole_archive_deps = [], **kwargs): "Bazel macro to correspond with the cc_library_static Soong module." mainlib_name = "%s_mainlib" % name @@ -18,7 +19,8 @@ def cc_library_static( name = mainlib_name, srcs = srcs, hdrs = hdrs, - deps = deps, + # TODO(b/187533117): Handle whole_archive_deps differently from regular static deps. + deps = deps + whole_archive_deps, copts = copts, includes = includes, **kwargs @@ -31,6 +33,27 @@ def cc_library_static( deps = [mainlib_name], ) +# Returns a cloned copy of the given CcInfo object, except that all linker inputs +# with owner `old_owner_label` are recreated and owned by the current target. +# +# This is useful in the "macro with proxy rule" pattern, as some rules upstream +# may expect they are depending directly on a target which generates linker inputs, +# as opposed to a proxy target which is a level of indirection to such a target. +def _claim_ownership(ctx, old_owner_label, ccinfo): + linker_inputs = [] + # This is not ideal, as it flattens a depset. + for old_linker_input in ccinfo.linking_context.linker_inputs.to_list(): + if old_linker_input.owner == old_owner_label: + new_linker_input = cc_common.create_linker_input( + owner = ctx.label, + libraries = depset(direct = old_linker_input.libraries)) + linker_inputs.append(new_linker_input) + else: + linker_inputs.append(old_linker_input) + + linking_context = cc_common.create_linking_context(linker_inputs = depset(direct = linker_inputs)) + return CcInfo(compilation_context = ccinfo.compilation_context, linking_context = linking_context) + def _empty_library_safeguard_impl(ctx): if len(ctx.attr.deps) != 1: fail("the deps attribute should always contain exactly one label") @@ -38,7 +61,8 @@ def _empty_library_safeguard_impl(ctx): main_target = ctx.attr.deps[0] if len(ctx.files.deps) > 0: # This safeguard is a no-op, as a library was generated by the main target. - return [main_target[CcInfo], main_target[DefaultInfo]] + new_cc_info = _claim_ownership(ctx, main_target.label, main_target[CcInfo]) + return [new_cc_info, main_target[DefaultInfo]] # The main library is empty; link a stub and propagate it to match Soong behavior. cc_toolchain = find_cpp_toolchain(ctx) diff --git a/rules/full_cc_library.bzl b/rules/full_cc_library.bzl index 1ea23d21..6e5d000c 100644 --- a/rules/full_cc_library.bzl +++ b/rules/full_cc_library.bzl @@ -3,35 +3,63 @@ load("@rules_cc//examples:experimental_cc_shared_library.bzl", "CcSharedLibraryI def cc_library( name, - # attributes for the static target + # attributes for both targets srcs = [], hdrs = [], deps = [], + whole_archive_deps = [], dynamic_deps = [], copts = [], includes = [], linkopts = [], # attributes for the shared target + dynamic_deps_for_shared = [], + shared_copts = [], + shared_srcs = [], static_deps_for_shared = [], + whole_archive_deps_for_shared = [], user_link_flags = [], version_script = None, + # attributes for the static target + dynamic_deps_for_static = [], + static_copts = [], + static_srcs = [], + static_deps_for_static = [], + whole_archive_deps_for_static = [], **kwargs): static_name = name + "_bp2build_cc_library_static" shared_name = name + "_bp2build_cc_library_shared" + shared_root_name = name + "_bp2build_cc_library_shared_root" _cc_library_proxy( name = name, static = static_name, shared = shared_name, ) + # The static version of the library. cc_library_static( name = static_name, hdrs = hdrs, - srcs = srcs, - copts = copts, + srcs = srcs + static_srcs, + copts = copts + static_copts, + includes = includes, + linkopts = linkopts, + # TODO(b/187533117): Handle whole_archive_deps differently than other deps. + deps = deps + static_deps_for_static + whole_archive_deps + whole_archive_deps_for_static, + # TODO(b/187746106): Handle dynamic_deps_for_static. + ) + + # The static library at the root of the shared library. + # This may be distinct from the static library if, for example, + # the static-variant srcs are different than the shared-variant srcs. + cc_library_static( + name = shared_root_name, + hdrs = hdrs, + srcs = srcs + shared_srcs, + copts = copts + shared_copts, includes = includes, linkopts = linkopts, - deps = deps, + deps = deps + static_deps_for_shared + whole_archive_deps + whole_archive_deps_for_shared, ) additional_linker_inputs = [] @@ -46,10 +74,10 @@ def cc_library( # declare all transitive static deps used by this target. It'd be great # if a shared library could declare a transitive exported static dep # instead of needing to declare each target transitively. - static_deps = ["//:__subpackages__"] + static_deps_for_shared, - dynamic_deps = dynamic_deps, + static_deps = ["//:__subpackages__"] + [shared_root_name], + dynamic_deps = dynamic_deps + dynamic_deps_for_shared, additional_linker_inputs = additional_linker_inputs, - roots = [static_name + "_mainlib"], + roots = [shared_root_name] + whole_archive_deps + whole_archive_deps_for_shared, ) def _cc_library_proxy_impl(ctx): |