diff options
author | Alex Márquez Pérez Muñíz Díaz Puras Thaureaux <alexmarquez@google.com> | 2023-04-17 22:03:49 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2023-04-17 22:03:49 +0000 |
commit | 5278fa37aeb44b86238870876186b25aead6bb85 (patch) | |
tree | 40e7aa99bfdc0134e45fb187fc768393cc4b6dd3 | |
parent | 8cfa27a8ba0254670dd358f462e6e199c4622850 (diff) | |
parent | 4a81e6727e185e046025a91fd60db4964c882d0b (diff) | |
download | bazel-5278fa37aeb44b86238870876186b25aead6bb85.tar.gz |
Merge "cc_prebuilt_library_{shared,static}: macros->rules" am: 8bbd1f3b30 am: 4a81e6727e
Original change: https://android-review.googlesource.com/c/platform/build/bazel/+/2507235
Change-Id: I99b71e4d6715f0ca741ee8f1a7970126e08952d1
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
-rw-r--r-- | rules/cc/cc_library_common.bzl | 19 | ||||
-rw-r--r-- | rules/cc/cc_prebuilt_library_shared.bzl | 45 | ||||
-rw-r--r-- | rules/cc/cc_prebuilt_library_shared_test.bzl | 83 | ||||
-rw-r--r-- | rules/cc/cc_prebuilt_library_static.bzl | 49 | ||||
-rw-r--r-- | rules/cc/cc_prebuilt_library_static_test.bzl | 150 |
5 files changed, 307 insertions, 39 deletions
diff --git a/rules/cc/cc_library_common.bzl b/rules/cc/cc_library_common.bzl index bd861c50..afd5d978 100644 --- a/rules/cc/cc_library_common.bzl +++ b/rules/cc/cc_library_common.bzl @@ -402,3 +402,22 @@ def create_cc_androidmk_provider(*, static_deps, whole_archive_deps, dynamic_dep local_whole_static_libs = local_whole_static_libs, local_shared_libs = local_shared_libs, ) + +def create_cc_prebuilt_library_info(ctx, lib_to_link): + "Create the CcInfo for a prebuilt_library_{shared,static}" + + compilation_context = cc_common.create_compilation_context( + includes = depset(get_includes_paths(ctx, ctx.attr.export_includes)), + system_includes = depset(get_includes_paths(ctx, ctx.attr.export_system_includes)), + ) + linker_input = cc_common.create_linker_input( + owner = ctx.label, + libraries = depset(direct = [lib_to_link] if lib_to_link != None else []), + ) + linking_context = cc_common.create_linking_context( + linker_inputs = depset(direct = [linker_input]), + ) + return CcInfo( + compilation_context = compilation_context, + linking_context = linking_context, + ) diff --git a/rules/cc/cc_prebuilt_library_shared.bzl b/rules/cc/cc_prebuilt_library_shared.bzl index d713a928..25144f86 100644 --- a/rules/cc/cc_prebuilt_library_shared.bzl +++ b/rules/cc/cc_prebuilt_library_shared.bzl @@ -12,16 +12,39 @@ # See the License for the specific language governing permissions and # limitations under the License. -def cc_prebuilt_library_shared( - name, - shared_library, - alwayslink = None, - **kwargs): - "Bazel macro to correspond with the *_cc_prebuilt_library_shared Soong module types" +load("@bazel_tools//tools/cpp:toolchain_utils.bzl", "find_cpp_toolchain") +load(":cc_library_common.bzl", "create_cc_prebuilt_library_info") - native.cc_import( - name = name, - shared_library = shared_library, - alwayslink = alwayslink, - **kwargs +def _cc_prebuilt_library_shared_impl(ctx): + lib = ctx.file.shared_library + files = ctx.attr.shared_library.files if lib != None else None + cc_toolchain = find_cpp_toolchain(ctx) + feature_configuration = cc_common.configure_features( + ctx = ctx, + cc_toolchain = cc_toolchain, ) + cc_info = create_cc_prebuilt_library_info( + ctx, + cc_common.create_library_to_link( + actions = ctx.actions, + dynamic_library = lib, + feature_configuration = feature_configuration, + cc_toolchain = cc_toolchain, + ) if lib != None else None, + ) + return [DefaultInfo(files = files), cc_info] + +cc_prebuilt_library_shared = rule( + implementation = _cc_prebuilt_library_shared_impl, + attrs = dict( + shared_library = attr.label( + providers = [CcInfo], + allow_single_file = True, + ), + export_includes = attr.string_list(), + export_system_includes = attr.string_list(), + ), + toolchains = ["@bazel_tools//tools/cpp:toolchain_type"], + fragments = ["cpp"], + provides = [CcInfo], +) diff --git a/rules/cc/cc_prebuilt_library_shared_test.bzl b/rules/cc/cc_prebuilt_library_shared_test.bzl index 79084a0a..8fe63f85 100644 --- a/rules/cc/cc_prebuilt_library_shared_test.bzl +++ b/rules/cc/cc_prebuilt_library_shared_test.bzl @@ -16,30 +16,56 @@ limitations under the License. load("@bazel_skylib//lib:unittest.bzl", "analysistest", "asserts") load("//build/bazel/rules/cc:cc_prebuilt_library_shared.bzl", "cc_prebuilt_library_shared") +load("//build/bazel/rules/test_common:paths.bzl", "get_output_and_package_dir_based_path") + +_fake_expected_lib = "{[()]}" def _cc_prebuilt_library_shared_test_impl(ctx): env = analysistest.begin(ctx) target = analysistest.target_under_test(env) expected_lib = ctx.attr.expected_lib - cc_info = target[CcInfo] + compilation_context = cc_info.compilation_context linker_inputs = cc_info.linking_context.linker_inputs.to_list() libs_to_link = [] for lib in linker_inputs: libs_to_link += lib.libraries - asserts.true( - env, - expected_lib in [lib.dynamic_library.basename for lib in libs_to_link], - "\nExpected the target to include the shared library %s; but instead got:\n\t%s\n" % (expected_lib, libs_to_link), - ) + if expected_lib == _fake_expected_lib: + asserts.true( + env, + len(libs_to_link) == 0, + "\nExpected the shared library to be empty, but instead got:\n\t%s\n" % str(libs_to_link), + ) + else: + asserts.true( + env, + expected_lib in [lib.dynamic_library.basename for lib in libs_to_link], + "\nExpected the target to include the shared library %s; but instead got:\n\t%s\n" % (expected_lib, libs_to_link), + ) + + # Checking for the expected {,system_}includes + assert_template = "\nExpected the %s for " + expected_lib + " to be:\n\t%s\n, but instead got:\n\t%s\n" + expand_paths = lambda paths: [get_output_and_package_dir_based_path(env, p) for p in paths] + expected_includes = expand_paths(ctx.attr.expected_includes) + expected_system_includes = expand_paths(ctx.attr.expected_system_includes) + + includes = compilation_context.includes.to_list() + for include in expected_includes: + asserts.true(env, include in includes, assert_template % ("includes", expected_includes, includes)) + + system_includes = compilation_context.system_includes.to_list() + for include in expected_system_includes: + asserts.true(env, include in system_includes, assert_template % ("system_includes", expected_system_includes, system_includes)) return analysistest.end(env) _cc_prebuilt_library_shared_test = analysistest.make( _cc_prebuilt_library_shared_test_impl, attrs = dict( - expected_lib = attr.string(mandatory = True), + expected_lib = attr.string(default = _fake_expected_lib), + expected_includes = attr.string_list(), + expected_system_includes = attr.string_list(), ), ) @@ -53,11 +79,52 @@ def _cc_prebuilt_library_shared_simple(): shared_library = lib, tags = ["manual"], ) + _cc_prebuilt_library_shared_test( + name = test_name, + target_under_test = name, + expected_lib = lib, + ) + return test_name + +def _cc_prebuilt_library_shared_default_library_field(): + name = "_cc_prebuilt_library_shared_default_library_field" + test_name = name + "_test" + lib = None + + cc_prebuilt_library_shared( + name = name, + shared_library = lib, + tags = ["manual"], + ) + _cc_prebuilt_library_shared_test( + name = test_name, + target_under_test = name, + expected_lib = lib, # We expect the default of _fake_expected_lib + ) + + return test_name + +def _cc_prebuilt_library_shared_has_all_includes(): + name = "_cc_prebuilt_library_shared_has_all_includes" + test_name = name + "_test" + lib = "libfoo.so" + includes = ["includes"] + system_includes = ["system_includes"] + + cc_prebuilt_library_shared( + name = name, + shared_library = lib, + export_includes = includes, + export_system_includes = system_includes, + tags = ["manual"], + ) _cc_prebuilt_library_shared_test( name = test_name, target_under_test = name, expected_lib = lib, + expected_includes = includes, + expected_system_includes = system_includes, ) return test_name @@ -67,5 +134,7 @@ def cc_prebuilt_library_shared_test_suite(name): name = name, tests = [ _cc_prebuilt_library_shared_simple(), + _cc_prebuilt_library_shared_default_library_field(), + _cc_prebuilt_library_shared_has_all_includes(), ], ) diff --git a/rules/cc/cc_prebuilt_library_static.bzl b/rules/cc/cc_prebuilt_library_static.bzl index 1981fbf7..1d84adac 100644 --- a/rules/cc/cc_prebuilt_library_static.bzl +++ b/rules/cc/cc_prebuilt_library_static.bzl @@ -12,18 +12,41 @@ # See the License for the specific language governing permissions and # limitations under the License. -def cc_prebuilt_library_static( - name, - static_library, - export_includes = [], # @unused - export_system_includes = [], # @unused - **kwargs): - "Bazel macro to correspond with the *_cc_prebuilt_library_static Soong module types" +load("@bazel_tools//tools/cpp:toolchain_utils.bzl", "find_cpp_toolchain") +load(":cc_library_common.bzl", "create_cc_prebuilt_library_info") - # TODO: Handle includes similarly to cc_library_static - # e.g. includes = ["clang-r416183b/prebuilt_include/llvm/lib/Fuzzer"], - native.cc_import( - name = name, - static_library = static_library, - **kwargs +def _cc_prebuilt_library_static_impl(ctx): + lib = ctx.file.static_library + files = ctx.attr.static_library.files if lib != None else None + cc_toolchain = find_cpp_toolchain(ctx) + feature_configuration = cc_common.configure_features( + ctx = ctx, + cc_toolchain = cc_toolchain, ) + cc_info = create_cc_prebuilt_library_info( + ctx, + cc_common.create_library_to_link( + actions = ctx.actions, + static_library = lib, + alwayslink = ctx.attr.alwayslink, + feature_configuration = feature_configuration, + cc_toolchain = cc_toolchain, + ) if lib != None else None, + ) + return [DefaultInfo(files = files), cc_info] + +cc_prebuilt_library_static = rule( + implementation = _cc_prebuilt_library_static_impl, + attrs = dict( + static_library = attr.label( + providers = [CcInfo], + allow_single_file = True, + ), + alwayslink = attr.bool(default = False), + export_includes = attr.string_list(), + export_system_includes = attr.string_list(), + ), + toolchains = ["@bazel_tools//tools/cpp:toolchain_type"], + fragments = ["cpp"], + provides = [CcInfo], +) diff --git a/rules/cc/cc_prebuilt_library_static_test.bzl b/rules/cc/cc_prebuilt_library_static_test.bzl index 5a386e4c..326e1953 100644 --- a/rules/cc/cc_prebuilt_library_static_test.bzl +++ b/rules/cc/cc_prebuilt_library_static_test.bzl @@ -1,5 +1,5 @@ """ -Copyright (C) 2022 The Android Open Source Project +Copyright (C) 2023 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. @@ -16,59 +16,193 @@ limitations under the License. load("@bazel_skylib//lib:unittest.bzl", "analysistest", "asserts") load("//build/bazel/rules/cc:cc_prebuilt_library_static.bzl", "cc_prebuilt_library_static") +load("//build/bazel/rules/test_common:paths.bzl", "get_output_and_package_dir_based_path") + +_fake_expected_lib = "{[()]}" def _cc_prebuilt_library_static_alwayslink_test_impl(ctx): env = analysistest.begin(ctx) target = analysistest.target_under_test(env) expected_lib = ctx.attr.expected_lib + alwayslink = ctx.attr.alwayslink cc_info = target[CcInfo] linker_inputs = cc_info.linking_context.linker_inputs.to_list() libs_to_link = [] for l in linker_inputs: libs_to_link += l.libraries + has_lib = False has_alwayslink = False libs = {} for lib_to_link in libs_to_link: lib = lib_to_link.static_library.basename libs[lib_to_link.static_library] = lib_to_link.alwayslink if lib == expected_lib: + has_lib = True has_alwayslink = lib_to_link.alwayslink if has_alwayslink: break - asserts.true(env, has_alwayslink, "\nExpected to find the static library `%s` unconditionally in the linker_input, with alwayslink set:\n\t%s" % (expected_lib, str(libs))) + asserts.true( + env, + has_lib, + "\nExpected to find the static library `%s` in the linker_input:\n\t%s" % (expected_lib, str(libs)), + ) + asserts.equals( + env, + has_alwayslink, + alwayslink, + "\nExpected to find the static library `%s` unconditionally in the linker_input, with alwayslink set to %s:\n\t%s" % (expected_lib, alwayslink, str(libs)), + ) return analysistest.end(env) _cc_prebuilt_library_static_alwayslink_test = analysistest.make( _cc_prebuilt_library_static_alwayslink_test_impl, - attrs = {"expected_lib": attr.string()}, + attrs = { + "expected_lib": attr.string(), + "alwayslink": attr.bool(), + }, ) -def _cc_prebuilt_library_static_given_alwayslink_lib(): - name = "_cc_prebuilt_library_static_given_alwayslink_lib" +def _cc_prebuilt_library_static_alwayslink_lib(alwayslink): + name = "_cc_prebuilt_library_static_alwayslink_lib_" + str(alwayslink) test_name = name + "_test" lib = "libfoo.a" cc_prebuilt_library_static( name = name, static_library = lib, - alwayslink = True, + alwayslink = alwayslink, tags = ["manual"], ) - _cc_prebuilt_library_static_alwayslink_test( name = test_name, target_under_test = name, expected_lib = lib, + alwayslink = alwayslink, ) return test_name +def _cc_prebuilt_library_static_test_impl(ctx): + env = analysistest.begin(ctx) + target = analysistest.target_under_test(env) + expected_lib = ctx.attr.expected_lib + cc_info = target[CcInfo] + compilation_context = cc_info.compilation_context + linker_inputs = cc_info.linking_context.linker_inputs.to_list() + libs_to_link = [] + for lib in linker_inputs: + libs_to_link += lib.libraries + + if expected_lib == _fake_expected_lib: + asserts.true( + env, + len(libs_to_link) == 0, + "\nExpected the static library to be empty, but instead got:\n\t%s\n" % str(libs_to_link), + ) + else: + asserts.true( + env, + expected_lib in [lib.static_library.basename for lib in libs_to_link], + "\nExpected the target to include the static library %s; but instead got:\n\t%s\n" % (expected_lib, libs_to_link), + ) + + # Checking for the expected {,system_}includes + assert_template = "\nExpected the %s for " + expected_lib + " to be:\n\t%s\n, but instead got:\n\t%s\n" + expand_paths = lambda paths: [get_output_and_package_dir_based_path(env, p) for p in paths] + expected_includes = expand_paths(ctx.attr.expected_includes) + expected_system_includes = expand_paths(ctx.attr.expected_system_includes) + + includes = compilation_context.includes.to_list() + for include in expected_includes: + asserts.true(env, include in includes, assert_template % ("includes", expected_includes, includes)) + + system_includes = compilation_context.system_includes.to_list() + for include in expected_system_includes: + asserts.true(env, include in system_includes, assert_template % ("system_includes", expected_system_includes, system_includes)) + + return analysistest.end(env) + +_cc_prebuilt_library_static_test = analysistest.make( + _cc_prebuilt_library_static_test_impl, + attrs = dict( + expected_lib = attr.string(default = _fake_expected_lib), + expected_includes = attr.string_list(), + expected_system_includes = attr.string_list(), + ), +) + +def _cc_prebuilt_library_static_simple(): + name = "_cc_prebuilt_library_static_simple" + test_name = name + "_test" + lib = "libfoo.a" + + cc_prebuilt_library_static( + name = name, + static_library = lib, + tags = ["manual"], + ) + _cc_prebuilt_library_static_test( + name = test_name, + target_under_test = name, + expected_lib = lib, + ) + + return test_name + +def _cc_prebuilt_library_static_None(): + name = "_cc_prebuilt_library_static_None" + test_name = name + "_test" + lib = None + + cc_prebuilt_library_static( + name = name, + static_library = lib, + tags = ["manual"], + ) + _cc_prebuilt_library_static_test( + name = test_name, + target_under_test = name, + expected_lib = lib, # We expect the default of _fake_expected_lib + ) + + return test_name + +def _cc_prebuilt_library_static_has_all_includes(): + name = "_cc_prebuilt_library_static_has_all_includes" + test_name = name + "_test" + lib = "libfoo.a" + includes = ["includes"] + system_includes = ["system_includes"] + + cc_prebuilt_library_static( + name = name, + static_library = lib, + export_includes = includes, + export_system_includes = system_includes, + tags = ["manual"], + ) + _cc_prebuilt_library_static_test( + name = test_name, + target_under_test = name, + expected_lib = lib, + expected_includes = includes, + expected_system_includes = system_includes, + ) + + return test_name + +# TODO: Test that is alwayslink = alse + def cc_prebuilt_library_static_test_suite(name): native.test_suite( name = name, tests = [ - _cc_prebuilt_library_static_given_alwayslink_lib(), + _cc_prebuilt_library_static_simple(), + _cc_prebuilt_library_static_None(), + _cc_prebuilt_library_static_alwayslink_lib(True), + _cc_prebuilt_library_static_alwayslink_lib(False), + _cc_prebuilt_library_static_has_all_includes(), ], ) |