From 810a11e77285e97e5a69e6f1be3c8d647286407f Mon Sep 17 00:00:00 2001 From: Googler Date: Fri, 14 Feb 2020 06:58:52 -0800 Subject: [PATCH] C++: Allow libraries to be exported by any target Any library should be exportable by any cc_shared_library target regardless of whether the cc_shared_library target is in the same package or a parent package as long as the library author gives permission. The library author can now do this by writing tags=["exported_by=//foo,//baz"]. PiperOrigin-RevId: 295137965 Change-Id: I4acffd26981fedd6cb0c505e2691da0c70a7b6b0 --- examples/experimental_cc_shared_library.bzl | 31 +++++++++++++++++++-- examples/test_cc_shared_library/BUILD | 1 + examples/test_cc_shared_library2/BUILD | 1 + 3 files changed, 30 insertions(+), 3 deletions(-) diff --git a/examples/experimental_cc_shared_library.bzl b/examples/experimental_cc_shared_library.bzl index 49b9b8e..0ab7ee6 100644 --- a/examples/experimental_cc_shared_library.bzl +++ b/examples/experimental_cc_shared_library.bzl @@ -12,6 +12,7 @@ load("//cc:find_cc_toolchain.bzl", "find_cc_toolchain") GraphNodeInfo = provider( fields = { "children": "Other GraphNodeInfo from dependencies of this target", + "exported_by": "Labels of targets that can export the library of this node", "label": "Label of the target visited", }, ) @@ -259,10 +260,19 @@ def _cc_shared_library_impl(ctx): fail("Trying to export a library already exported by a different shared library: " + str(export.label)) - if not _same_package_or_above(ctx.label, export[GraphNodeInfo].label): + can_be_exported = _same_package_or_above(ctx.label, export.label) + + if not can_be_exported: + for exported_by in export[GraphNodeInfo].exported_by: + target_specified = _is_target_specified(exported_by) + exported_by_label = Label(exported_by) + if _check_if_target_under_path(ctx.label, exported_by_label, target_specified): + can_be_exported = True + break + if not can_be_exported: fail(str(export.label) + " cannot be exported from " + str(ctx.label) + - " because " + str(export.label) + " is not in the same package " + - " or a sub-package") + " because it's not in the same package/subpackage or the library " + + "to be exported doesn't have this cc_shared_library in the exported_by tag.") preloaded_deps_direct_labels = {} preloaded_dep_merged_cc_info = None @@ -348,9 +358,24 @@ def _graph_structure_aspect_impl(target, ctx): if GraphNodeInfo in dep: children.append(dep[GraphNodeInfo]) + exported_by = [] + if hasattr(ctx.rule.attr, "tags"): + for tag in ctx.rule.attr.tags: + if tag.startswith("exported_by=") and len(tag) > 12: + for target in tag[12:].split(","): + # Only absolute labels allowed. Targets in same package + # or subpackage can be exported anyway. + if not target.startswith("//") and not target.startswith("@"): + fail("Labels in exported_by of " + str(target) + + " must be absolute.") + + Label(target) # Checking synthax is ok. + exported_by.append(target) + return [GraphNodeInfo( label = ctx.label, children = children, + exported_by = exported_by, )] graph_structure_aspect = aspect( diff --git a/examples/test_cc_shared_library/BUILD b/examples/test_cc_shared_library/BUILD index 93090c4..a28799c 100644 --- a/examples/test_cc_shared_library/BUILD +++ b/examples/test_cc_shared_library/BUILD @@ -85,6 +85,7 @@ cc_shared_library( exports = [ "bar", "bar2", + "@test_repo//:bar", ], ) diff --git a/examples/test_cc_shared_library2/BUILD b/examples/test_cc_shared_library2/BUILD index 802d60f..1789a5f 100644 --- a/examples/test_cc_shared_library2/BUILD +++ b/examples/test_cc_shared_library2/BUILD @@ -4,5 +4,6 @@ cc_library( name = "bar", srcs = ["bar.cc"], hdrs = ["bar.h"], + tags = ["exported_by=@rules_cc//examples/test_cc_shared_library:bar_so"], visibility = ["//visibility:public"], )