aboutsummaryrefslogtreecommitdiff
path: root/rules/cc/cc_library_shared.bzl
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2022-05-10 06:51:54 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2022-05-10 06:51:54 +0000
commit9850fee71151e8e244e202597d6e1920ee3a71c3 (patch)
tree74393ec5dcc68491e5308c0f4d3bdc3fa1f58fcb /rules/cc/cc_library_shared.bzl
parent479e50d33ff6852449772ace5d54f9658dddf71e (diff)
parent92c1d863d4d44c61c934ddbb4392fcf3527f0639 (diff)
downloadbazel-9850fee71151e8e244e202597d6e1920ee3a71c3.tar.gz
Snap for 8564071 from 92c1d863d4d44c61c934ddbb4392fcf3527f0639 to mainline-conscrypt-releaseaml_con_331413000aml_con_331411000aml_con_331312000aml_con_331115000aml_con_331011010android13-mainline-conscrypt-release
Change-Id: I270f1c56b57254a0f62c75330da5ebaa3bab7fb4
Diffstat (limited to 'rules/cc/cc_library_shared.bzl')
-rw-r--r--rules/cc/cc_library_shared.bzl449
1 files changed, 449 insertions, 0 deletions
diff --git a/rules/cc/cc_library_shared.bzl b/rules/cc/cc_library_shared.bzl
new file mode 100644
index 00000000..b4367e50
--- /dev/null
+++ b/rules/cc/cc_library_shared.bzl
@@ -0,0 +1,449 @@
+"""
+Copyright (C) 2021 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+"""
+
+load(
+ ":cc_library_common.bzl",
+ "add_lists_defaulting_to_none",
+ "disable_crt_link",
+ "parse_sdk_version",
+ "system_dynamic_deps_defaults",
+)
+load(":cc_library_static.bzl", "cc_library_static")
+load(":cc_stub_library.bzl", "CcStubInfo", "cc_stub_gen")
+load(":generate_toc.bzl", "shared_library_toc", _CcTocInfo = "CcTocInfo")
+load(":stl.bzl", "shared_stl_deps")
+load(":stripped_cc_common.bzl", "stripped_shared_library")
+load(":versioned_cc_common.bzl", "versioned_shared_library")
+load("@rules_cc//examples:experimental_cc_shared_library.bzl", "cc_shared_library", _CcSharedLibraryInfo = "CcSharedLibraryInfo")
+load("@rules_cc//cc:find_cc_toolchain.bzl", "find_cpp_toolchain")
+
+CcTocInfo = _CcTocInfo
+CcSharedLibraryInfo = _CcSharedLibraryInfo
+
+def cc_library_shared(
+ name,
+ # Common arguments between shared_root and the shared library
+ features = [],
+ dynamic_deps = [],
+ implementation_dynamic_deps = [],
+ linkopts = [],
+ target_compatible_with = [],
+ # Ultimately _static arguments for shared_root production
+ srcs = [],
+ srcs_c = [],
+ srcs_as = [],
+ copts = [],
+ cppflags = [],
+ conlyflags = [],
+ asflags = [],
+ hdrs = [],
+ implementation_deps = [],
+ deps = [],
+ whole_archive_deps = [],
+ system_dynamic_deps = None,
+ export_includes = [],
+ export_absolute_includes = [],
+ export_system_includes = [],
+ local_includes = [],
+ absolute_includes = [],
+ rtti = False,
+ use_libcrt = True, # FIXME: Unused below?
+ stl = "",
+ cpp_std = "",
+ c_std = "",
+ link_crt = True,
+ additional_linker_inputs = None,
+
+ # Purely _shared arguments
+ strip = {},
+ soname = "",
+
+ # TODO(b/202299295): Handle data attribute.
+ data = [],
+ use_version_lib = False,
+ stubs_symbol_file = None,
+ stubs_versions = [],
+ inject_bssl_hash = False,
+ sdk_version = "",
+ min_sdk_version = "",
+ **kwargs):
+ "Bazel macro to correspond with the cc_library_shared Soong module."
+
+ shared_root_name = name + "_root"
+ unstripped_name = name + "_unstripped"
+ stripped_name = name + "_stripped"
+ toc_name = name + "_toc"
+
+ if system_dynamic_deps == None:
+ system_dynamic_deps = system_dynamic_deps_defaults
+
+ # Force crtbegin and crtend linking unless explicitly disabled (i.e. bionic
+ # libraries do this)
+ if link_crt == False:
+ features = disable_crt_link(features)
+
+ if min_sdk_version:
+ features = features + [
+ "sdk_version_" + parse_sdk_version(min_sdk_version),
+ "-sdk_version_default",
+ ]
+
+ # The static library at the root of the shared library.
+ # This may be distinct from the static version of the library if e.g.
+ # the static-variant srcs are different than the shared-variant srcs.
+ cc_library_static(
+ name = shared_root_name,
+ hdrs = hdrs,
+ srcs = srcs,
+ srcs_c = srcs_c,
+ srcs_as = srcs_as,
+ copts = copts,
+ cppflags = cppflags,
+ conlyflags = conlyflags,
+ asflags = asflags,
+ export_includes = export_includes,
+ export_absolute_includes = export_absolute_includes,
+ export_system_includes = export_system_includes,
+ local_includes = local_includes,
+ absolute_includes = absolute_includes,
+ rtti = rtti,
+ stl = stl,
+ cpp_std = cpp_std,
+ c_std = c_std,
+ dynamic_deps = dynamic_deps,
+ implementation_deps = implementation_deps,
+ implementation_dynamic_deps = implementation_dynamic_deps,
+ system_dynamic_deps = system_dynamic_deps,
+ deps = deps + whole_archive_deps,
+ features = features,
+ use_version_lib = use_version_lib,
+ target_compatible_with = target_compatible_with,
+ )
+
+ stl_static, stl_shared = shared_stl_deps(stl)
+
+ # implementation_deps and deps are to be linked into the shared library via
+ # --no-whole-archive. In order to do so, they need to be dependencies of
+ # a "root" of the cc_shared_library, but may not be roots themselves.
+ # Below we define stub roots (which themselves have no srcs) in order to facilitate
+ # this.
+ imp_deps_stub = name + "_implementation_deps"
+ deps_stub = name + "_deps"
+ native.cc_library(
+ name = imp_deps_stub,
+ deps = implementation_deps + stl_static,
+ target_compatible_with = target_compatible_with,
+ )
+ native.cc_library(
+ name = deps_stub,
+ deps = deps,
+ target_compatible_with = target_compatible_with,
+ )
+
+ shared_dynamic_deps = add_lists_defaulting_to_none(
+ dynamic_deps,
+ system_dynamic_deps,
+ implementation_dynamic_deps,
+ stl_shared,
+ )
+
+ if len(soname) == 0:
+ soname = name + ".so"
+ soname_flag = "-Wl,-soname," + soname
+
+ cc_shared_library(
+ name = unstripped_name,
+ user_link_flags = linkopts + [soname_flag],
+ # b/184806113: Note this is a workaround so users don't have to
+ # 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__"] + [shared_root_name, imp_deps_stub, deps_stub],
+ dynamic_deps = shared_dynamic_deps,
+ additional_linker_inputs = additional_linker_inputs,
+ roots = [shared_root_name, imp_deps_stub, deps_stub] + whole_archive_deps,
+ features = features,
+ target_compatible_with = target_compatible_with,
+ **kwargs
+ )
+
+ hashed_name = name + "_hashed"
+ _bssl_hash_injection(
+ name = hashed_name,
+ src = unstripped_name,
+ inject_bssl_hash = inject_bssl_hash,
+ )
+
+ versioned_name = name + "_versioned"
+ versioned_shared_library(
+ name = versioned_name,
+ src = hashed_name,
+ stamp_build_number = use_version_lib,
+ )
+
+ stripped_shared_library(
+ name = stripped_name,
+ src = versioned_name,
+ target_compatible_with = target_compatible_with,
+ **strip
+ )
+
+ shared_library_toc(
+ name = toc_name,
+ src = stripped_name,
+ target_compatible_with = target_compatible_with,
+ )
+
+ # Emit the stub version of this library (e.g. for libraries that are
+ # provided by the NDK)
+ stub_shared_libraries = []
+ if stubs_symbol_file and len(stubs_versions) > 0:
+ # TODO(b/193663198): This unconditionally creates stubs for every version, but
+ # that's not always true depending on whether this module is available
+ # on the host, ramdisk, vendor ramdisk. We currently don't have
+ # information about the image variant yet, so we'll create stub targets
+ # for all shared libraries with the stubs property for now.
+ #
+ # See: https://cs.android.com/android/platform/superproject/+/master:build/soong/cc/library.go;l=2316-2377;drc=3d3b35c94ed2a3432b2e5e7e969a3a788a7a80b5
+ for version in stubs_versions:
+ stubs_library_name = "_".join([name, version, "stubs"])
+ cc_stub_library_shared(
+ name = stubs_library_name,
+ stubs_symbol_file = stubs_symbol_file,
+ version = version,
+ target_compatible_with = target_compatible_with,
+ features = features,
+ )
+ stub_shared_libraries.append(stubs_library_name)
+
+ _cc_library_shared_proxy(
+ name = name,
+ shared = stripped_name,
+ root = shared_root_name,
+ table_of_contents = toc_name,
+ output_file = soname,
+ target_compatible_with = target_compatible_with,
+ stub_shared_libraries = stub_shared_libraries,
+ )
+
+# cc_stub_library_shared creates a cc_library_shared target, but using stub C source files generated
+# from a library's .map.txt files and ndkstubgen. The top level target returns the same
+# providers as a cc_library_shared, with the addition of a CcStubInfo
+# containing metadata files and versions of the stub library.
+def cc_stub_library_shared(name, stubs_symbol_file, version, target_compatible_with, features):
+ # Call ndkstubgen to generate the stub.c source file from a .map.txt file. These
+ # are accessible in the CcStubInfo provider of this target.
+ cc_stub_gen(
+ name = name + "_files",
+ symbol_file = stubs_symbol_file,
+ version = version,
+ target_compatible_with = target_compatible_with,
+ )
+
+ # The static library at the root of the stub shared library.
+ cc_library_static(
+ name = name + "_root",
+ srcs_c = [name + "_files"], # compile the stub.c file
+ features = disable_crt_link(features) + \
+ [
+ # Enable the stub library compile flags
+ "stub_library",
+ # Disable all include-related features to avoid including any headers
+ # that may cause conflicting type errors with the symbols in the
+ # generated stubs source code.
+ # e.g.
+ # double acos(double); // in header
+ # void acos() {} // in the generated source code
+ # See https://cs.android.com/android/platform/superproject/+/master:build/soong/cc/library.go;l=942-946;drc=d8a72d7dc91b2122b7b10b47b80cf2f7c65f9049
+ "-toolchain_include_directories",
+ "-includes",
+ "-include_paths",
+ ],
+ target_compatible_with = target_compatible_with,
+ stl = "none",
+ system_dynamic_deps = [],
+ )
+
+ # Create a .so for the stub library. This library is self contained, has
+ # no deps, and doesn't link against crt.
+ cc_shared_library(
+ name = name + "_so",
+ roots = [name + "_root"],
+ features = disable_crt_link(features),
+ target_compatible_with = target_compatible_with,
+ )
+
+ # Create a target with CcSharedLibraryInfo and CcStubInfo providers.
+ _cc_stub_library_shared(
+ name = name,
+ stub_target = name + "_files",
+ library_target = name + "_so",
+ )
+
+def _cc_stub_library_shared_impl(ctx):
+ return [
+ ctx.attr.library_target[DefaultInfo],
+ ctx.attr.library_target[CcSharedLibraryInfo],
+ ctx.attr.stub_target[CcStubInfo],
+ ]
+
+_cc_stub_library_shared = rule(
+ implementation = _cc_stub_library_shared_impl,
+ doc = "Top level rule to merge CcStubInfo and CcSharedLibraryInfo into a single target",
+ attrs = {
+ "stub_target": attr.label(mandatory = True),
+ "library_target": attr.label(mandatory = True),
+ },
+)
+
+def _swap_shared_linker_input(ctx, shared_info, new_output):
+ old_library_to_link = shared_info.linker_input.libraries[0]
+
+ cc_toolchain = find_cpp_toolchain(ctx)
+ feature_configuration = cc_common.configure_features(
+ ctx = ctx,
+ cc_toolchain = cc_toolchain,
+ )
+
+ new_library_to_link = cc_common.create_library_to_link(
+ actions = ctx.actions,
+ dynamic_library = new_output,
+ feature_configuration = feature_configuration,
+ cc_toolchain = cc_toolchain,
+ )
+
+ new_linker_input = cc_common.create_linker_input(
+ owner = shared_info.linker_input.owner,
+ libraries = depset([new_library_to_link]),
+ )
+
+ return CcSharedLibraryInfo(
+ dynamic_deps = shared_info.dynamic_deps,
+ exports = shared_info.exports,
+ link_once_static_libs = shared_info.link_once_static_libs,
+ linker_input = new_linker_input,
+ preloaded_deps = shared_info.preloaded_deps,
+ )
+
+CcStubLibrariesInfo = provider(
+ fields = {
+ "infos": "A list of dict, where each dict contains the CcStubInfo, CcSharedLibraryInfo and DefaultInfo of a version of a stub library.",
+ },
+)
+
+def _cc_library_shared_proxy_impl(ctx):
+ root_files = ctx.attr.root[DefaultInfo].files.to_list()
+ shared_files = ctx.attr.shared[DefaultInfo].files.to_list()
+
+ if len(shared_files) != 1:
+ fail("Expected only one shared library file")
+
+ shared_lib = shared_files[0]
+
+ ctx.actions.symlink(
+ output = ctx.outputs.output_file,
+ target_file = shared_lib,
+ )
+
+ files = root_files + [ctx.outputs.output_file, ctx.files.table_of_contents[0]]
+
+ stub_library_infos = []
+ for stub_library in ctx.attr.stub_shared_libraries:
+ providers = {
+ "CcStubInfo": stub_library[CcStubInfo],
+ "CcSharedLibraryInfo": stub_library[CcSharedLibraryInfo],
+ "DefaultInfo": stub_library[DefaultInfo],
+ }
+ stub_library_infos.append(providers)
+
+ return [
+ DefaultInfo(
+ files = depset(direct = files),
+ runfiles = ctx.runfiles(files = [ctx.outputs.output_file]),
+ ),
+ _swap_shared_linker_input(ctx, ctx.attr.shared[CcSharedLibraryInfo], ctx.outputs.output_file),
+ ctx.attr.table_of_contents[CcTocInfo],
+ # Propagate only includes from the root. Do not re-propagate linker inputs.
+ CcInfo(compilation_context = ctx.attr.root[CcInfo].compilation_context),
+ CcStubLibrariesInfo(infos = stub_library_infos),
+ ]
+
+_cc_library_shared_proxy = rule(
+ implementation = _cc_library_shared_proxy_impl,
+ attrs = {
+ "shared": attr.label(mandatory = True, providers = [CcSharedLibraryInfo]),
+ "root": attr.label(mandatory = True, providers = [CcInfo]),
+ "output_file": attr.output(mandatory = True),
+ "table_of_contents": attr.label(
+ mandatory = True,
+ # TODO(b/217908237): reenable allow_single_file
+ # allow_single_file = True,
+ providers = [CcTocInfo],
+ ),
+ "stub_shared_libraries": attr.label_list(providers = [CcStubInfo, CcSharedLibraryInfo]),
+ },
+ fragments = ["cpp"],
+ toolchains = ["@bazel_tools//tools/cpp:toolchain_type"],
+)
+
+def _bssl_hash_injection_impl(ctx):
+ if len(ctx.files.src) != 1:
+ fail("Expected only one shared library file")
+
+ hashed_file = ctx.files.src[0]
+ if ctx.attr.inject_bssl_hash:
+ hashed_file = ctx.actions.declare_file("lib" + ctx.attr.name + ".so")
+ args = ctx.actions.args()
+ args.add_all(["-sha256"])
+ args.add_all(["-in-object", ctx.files.src[0]])
+ args.add_all(["-o", hashed_file])
+
+ ctx.actions.run(
+ inputs = ctx.files.src,
+ outputs = [hashed_file],
+ executable = ctx.executable._bssl_inject_hash,
+ arguments = [args],
+ tools = [ctx.executable._bssl_inject_hash],
+ mnemonic = "BsslInjectHash",
+ )
+
+ return [
+ DefaultInfo(files = depset([hashed_file])),
+ ctx.attr.src[CcSharedLibraryInfo],
+ ]
+
+_bssl_hash_injection = rule(
+ implementation = _bssl_hash_injection_impl,
+ attrs = {
+ "src": attr.label(
+ mandatory = True,
+ # TODO(b/217908237): reenable allow_single_file
+ # allow_single_file = True,
+ providers = [CcSharedLibraryInfo],
+ ),
+ "inject_bssl_hash": attr.bool(
+ default = False,
+ doc = "Whether inject BSSL hash",
+ ),
+ "_bssl_inject_hash": attr.label(
+ cfg = "exec",
+ doc = "The BSSL hash injection tool.",
+ executable = True,
+ default = "//prebuilts/build-tools:linux-x86/bin/bssl_inject_hash",
+ allow_single_file = True,
+ ),
+ },
+)