1*7594170eSAndroid Build Coastguard Worker# Copyright (C) 2022 The Android Open Source Project 2*7594170eSAndroid Build Coastguard Worker# 3*7594170eSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License"); 4*7594170eSAndroid Build Coastguard Worker# you may not use this file except in compliance with the License. 5*7594170eSAndroid Build Coastguard Worker# You may obtain a copy of the License at 6*7594170eSAndroid Build Coastguard Worker# 7*7594170eSAndroid Build Coastguard Worker# http://www.apache.org/licenses/LICENSE-2.0 8*7594170eSAndroid Build Coastguard Worker# 9*7594170eSAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software 10*7594170eSAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS, 11*7594170eSAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*7594170eSAndroid Build Coastguard Worker# See the License for the specific language governing permissions and 13*7594170eSAndroid Build Coastguard Worker# limitations under the License. 14*7594170eSAndroid Build Coastguard Worker 15*7594170eSAndroid Build Coastguard Workerload("@bazel_skylib//lib:paths.bzl", "paths") 16*7594170eSAndroid Build Coastguard Workerload("@bazel_skylib//rules:common_settings.bzl", "BuildSettingInfo") 17*7594170eSAndroid Build Coastguard Workerload( 18*7594170eSAndroid Build Coastguard Worker "@bazel_tools//tools/build_defs/cc:action_names.bzl", 19*7594170eSAndroid Build Coastguard Worker "CPP_COMPILE_ACTION_NAME", 20*7594170eSAndroid Build Coastguard Worker "C_COMPILE_ACTION_NAME", 21*7594170eSAndroid Build Coastguard Worker) 22*7594170eSAndroid Build Coastguard Workerload("@soong_injection//api_levels:platform_versions.bzl", "platform_versions") 23*7594170eSAndroid Build Coastguard Workerload("//build/bazel/platforms:platform_utils.bzl", "platforms") 24*7594170eSAndroid Build Coastguard Workerload( 25*7594170eSAndroid Build Coastguard Worker "//build/bazel/rules/cc:cc_library_common.bzl", 26*7594170eSAndroid Build Coastguard Worker "build_compilation_flags", 27*7594170eSAndroid Build Coastguard Worker "get_non_header_srcs", 28*7594170eSAndroid Build Coastguard Worker "is_bionic_lib", 29*7594170eSAndroid Build Coastguard Worker "is_bootstrap_lib", 30*7594170eSAndroid Build Coastguard Worker "parse_apex_sdk_version", 31*7594170eSAndroid Build Coastguard Worker) 32*7594170eSAndroid Build Coastguard Workerload("//build/bazel/rules/cc:cc_library_static.bzl", "CcStaticLibraryInfo") 33*7594170eSAndroid Build Coastguard Worker 34*7594170eSAndroid Build Coastguard WorkerAbiDumpInfo = provider(fields = ["dump_files"]) 35*7594170eSAndroid Build Coastguard WorkerAbiDiffInfo = provider(fields = ["diff_files"]) 36*7594170eSAndroid Build Coastguard Worker 37*7594170eSAndroid Build Coastguard Worker_ABI_CLASS_PLATFORM = "platform" 38*7594170eSAndroid Build Coastguard Worker 39*7594170eSAndroid Build Coastguard Workerdef _abi_dump_aspect_impl(target, ctx): 40*7594170eSAndroid Build Coastguard Worker if not _abi_diff_enabled(ctx, ctx.label.name, True): 41*7594170eSAndroid Build Coastguard Worker return [ 42*7594170eSAndroid Build Coastguard Worker AbiDumpInfo( 43*7594170eSAndroid Build Coastguard Worker dump_files = depset(), 44*7594170eSAndroid Build Coastguard Worker ), 45*7594170eSAndroid Build Coastguard Worker ] 46*7594170eSAndroid Build Coastguard Worker 47*7594170eSAndroid Build Coastguard Worker transitive_dumps = [] 48*7594170eSAndroid Build Coastguard Worker direct_dumps = [] 49*7594170eSAndroid Build Coastguard Worker 50*7594170eSAndroid Build Coastguard Worker if CcStaticLibraryInfo in target: 51*7594170eSAndroid Build Coastguard Worker direct_dumps.extend(_create_abi_dumps( 52*7594170eSAndroid Build Coastguard Worker ctx, 53*7594170eSAndroid Build Coastguard Worker target, 54*7594170eSAndroid Build Coastguard Worker ctx.rule.files.srcs_cpp, 55*7594170eSAndroid Build Coastguard Worker ctx.rule.attr.copts_cpp, 56*7594170eSAndroid Build Coastguard Worker CPP_COMPILE_ACTION_NAME, 57*7594170eSAndroid Build Coastguard Worker )) 58*7594170eSAndroid Build Coastguard Worker direct_dumps.extend(_create_abi_dumps( 59*7594170eSAndroid Build Coastguard Worker ctx, 60*7594170eSAndroid Build Coastguard Worker target, 61*7594170eSAndroid Build Coastguard Worker ctx.rule.files.srcs_c, 62*7594170eSAndroid Build Coastguard Worker ctx.rule.attr.copts_c, 63*7594170eSAndroid Build Coastguard Worker C_COMPILE_ACTION_NAME, 64*7594170eSAndroid Build Coastguard Worker )) 65*7594170eSAndroid Build Coastguard Worker 66*7594170eSAndroid Build Coastguard Worker for dep in ctx.rule.attr.static_deps: 67*7594170eSAndroid Build Coastguard Worker if AbiDumpInfo in dep: 68*7594170eSAndroid Build Coastguard Worker transitive_dumps.append(dep[AbiDumpInfo].dump_files) 69*7594170eSAndroid Build Coastguard Worker 70*7594170eSAndroid Build Coastguard Worker return [ 71*7594170eSAndroid Build Coastguard Worker AbiDumpInfo( 72*7594170eSAndroid Build Coastguard Worker dump_files = depset( 73*7594170eSAndroid Build Coastguard Worker direct_dumps, 74*7594170eSAndroid Build Coastguard Worker transitive = transitive_dumps, 75*7594170eSAndroid Build Coastguard Worker ), 76*7594170eSAndroid Build Coastguard Worker ), 77*7594170eSAndroid Build Coastguard Worker ] 78*7594170eSAndroid Build Coastguard Worker 79*7594170eSAndroid Build Coastguard Workerabi_dump_aspect = aspect( 80*7594170eSAndroid Build Coastguard Worker implementation = _abi_dump_aspect_impl, 81*7594170eSAndroid Build Coastguard Worker attr_aspects = ["static_deps", "whole_archive_deps"], 82*7594170eSAndroid Build Coastguard Worker attrs = { 83*7594170eSAndroid Build Coastguard Worker "_skip_abi_checks": attr.label( 84*7594170eSAndroid Build Coastguard Worker default = "//build/bazel/flags/cc/abi:skip_abi_checks", 85*7594170eSAndroid Build Coastguard Worker ), 86*7594170eSAndroid Build Coastguard Worker # Need this in order to call _abi_diff_enabled in the aspects code. 87*7594170eSAndroid Build Coastguard Worker "_within_apex": attr.label( 88*7594170eSAndroid Build Coastguard Worker default = "//build/bazel/rules/apex:within_apex", 89*7594170eSAndroid Build Coastguard Worker ), 90*7594170eSAndroid Build Coastguard Worker "_abi_dumper": attr.label( 91*7594170eSAndroid Build Coastguard Worker allow_files = True, 92*7594170eSAndroid Build Coastguard Worker executable = True, 93*7594170eSAndroid Build Coastguard Worker cfg = "exec", 94*7594170eSAndroid Build Coastguard Worker default = Label("//prebuilts/clang-tools:linux-x86/bin/header-abi-dumper"), 95*7594170eSAndroid Build Coastguard Worker ), 96*7594170eSAndroid Build Coastguard Worker "_platform_utils": attr.label(default = Label("//build/bazel/platforms:platform_utils")), 97*7594170eSAndroid Build Coastguard Worker }, 98*7594170eSAndroid Build Coastguard Worker toolchains = ["@bazel_tools//tools/cpp:toolchain_type"], 99*7594170eSAndroid Build Coastguard Worker fragments = ["cpp"], 100*7594170eSAndroid Build Coastguard Worker provides = [AbiDumpInfo], 101*7594170eSAndroid Build Coastguard Worker) 102*7594170eSAndroid Build Coastguard Worker 103*7594170eSAndroid Build Coastguard Workerdef _create_abi_dumps(ctx, target, srcs, user_flags, action_name): 104*7594170eSAndroid Build Coastguard Worker dumps = [] 105*7594170eSAndroid Build Coastguard Worker 106*7594170eSAndroid Build Coastguard Worker if len(srcs) == 0: 107*7594170eSAndroid Build Coastguard Worker return dumps 108*7594170eSAndroid Build Coastguard Worker 109*7594170eSAndroid Build Coastguard Worker compilation_context, compilation_flags = build_compilation_flags( 110*7594170eSAndroid Build Coastguard Worker ctx, 111*7594170eSAndroid Build Coastguard Worker ctx.rule.attr.roots + ctx.rule.attr.deps + ctx.rule.attr.includes, 112*7594170eSAndroid Build Coastguard Worker user_flags, 113*7594170eSAndroid Build Coastguard Worker action_name, 114*7594170eSAndroid Build Coastguard Worker ) 115*7594170eSAndroid Build Coastguard Worker sources, headers = get_non_header_srcs(srcs) 116*7594170eSAndroid Build Coastguard Worker 117*7594170eSAndroid Build Coastguard Worker header_inputs = ( 118*7594170eSAndroid Build Coastguard Worker headers + 119*7594170eSAndroid Build Coastguard Worker compilation_context.headers.to_list() + 120*7594170eSAndroid Build Coastguard Worker compilation_context.direct_headers + 121*7594170eSAndroid Build Coastguard Worker compilation_context.direct_private_headers + 122*7594170eSAndroid Build Coastguard Worker compilation_context.direct_public_headers + 123*7594170eSAndroid Build Coastguard Worker compilation_context.direct_textual_headers 124*7594170eSAndroid Build Coastguard Worker ) 125*7594170eSAndroid Build Coastguard Worker objects = [] 126*7594170eSAndroid Build Coastguard Worker linker_inputs = target[CcInfo].linking_context.linker_inputs.to_list() 127*7594170eSAndroid Build Coastguard Worker 128*7594170eSAndroid Build Coastguard Worker # These are created in cc_library_static and there should be only one 129*7594170eSAndroid Build Coastguard Worker # linker_inputs and one libraries 130*7594170eSAndroid Build Coastguard Worker if CcInfo in target and len(linker_inputs) == 1 and len(linker_inputs[0].libraries) == 1: 131*7594170eSAndroid Build Coastguard Worker objects = linker_inputs[0].libraries[0].objects 132*7594170eSAndroid Build Coastguard Worker for file in sources: 133*7594170eSAndroid Build Coastguard Worker output = _create_abi_dump(ctx, target, file, objects, header_inputs, compilation_flags) 134*7594170eSAndroid Build Coastguard Worker dumps.append(output) 135*7594170eSAndroid Build Coastguard Worker 136*7594170eSAndroid Build Coastguard Worker return dumps 137*7594170eSAndroid Build Coastguard Worker 138*7594170eSAndroid Build Coastguard Workerdef _include_flag(flag): 139*7594170eSAndroid Build Coastguard Worker return ["-I", flag] 140*7594170eSAndroid Build Coastguard Worker 141*7594170eSAndroid Build Coastguard Workerdef _create_abi_dump(ctx, target, src, objects, header_inputs, compilation_flags): 142*7594170eSAndroid Build Coastguard Worker """ Utility function to generate abi dump file.""" 143*7594170eSAndroid Build Coastguard Worker 144*7594170eSAndroid Build Coastguard Worker file = paths.join(src.dirname, target.label.name + "." + src.basename + ".sdump") 145*7594170eSAndroid Build Coastguard Worker output = ctx.actions.declare_file(file) 146*7594170eSAndroid Build Coastguard Worker args = ctx.actions.args() 147*7594170eSAndroid Build Coastguard Worker 148*7594170eSAndroid Build Coastguard Worker args.add("--root-dir", ".") 149*7594170eSAndroid Build Coastguard Worker args.add("-o", output) 150*7594170eSAndroid Build Coastguard Worker args.add(src) 151*7594170eSAndroid Build Coastguard Worker 152*7594170eSAndroid Build Coastguard Worker args.add_all(ctx.rule.attr.exports[0][CcInfo].compilation_context.includes.to_list(), map_each = _include_flag) 153*7594170eSAndroid Build Coastguard Worker 154*7594170eSAndroid Build Coastguard Worker args.add("--") 155*7594170eSAndroid Build Coastguard Worker args.add_all(compilation_flags) 156*7594170eSAndroid Build Coastguard Worker 157*7594170eSAndroid Build Coastguard Worker # The following two args come from here: 158*7594170eSAndroid Build Coastguard Worker # https://cs.android.com/android/platform/superproject/+/master:build/soong/cc/builder.go;l=247;drc=ba17c7243d0e297efbc6fb5385d6d5aa81db9152 159*7594170eSAndroid Build Coastguard Worker args.add("-w") 160*7594170eSAndroid Build Coastguard Worker 161*7594170eSAndroid Build Coastguard Worker # TODO(b/254625084): support darwin as well. 162*7594170eSAndroid Build Coastguard Worker args.add("-isystem", "prebuilts/clang-tools/linux-x86/clang-headers") 163*7594170eSAndroid Build Coastguard Worker 164*7594170eSAndroid Build Coastguard Worker ctx.actions.run( 165*7594170eSAndroid Build Coastguard Worker inputs = [src] + header_inputs + objects, 166*7594170eSAndroid Build Coastguard Worker executable = ctx.executable._abi_dumper, 167*7594170eSAndroid Build Coastguard Worker outputs = [output], 168*7594170eSAndroid Build Coastguard Worker arguments = [args], 169*7594170eSAndroid Build Coastguard Worker # TODO(b/186116353): enable sandbox once the bug is fixed. 170*7594170eSAndroid Build Coastguard Worker execution_requirements = { 171*7594170eSAndroid Build Coastguard Worker "no-sandbox": "1", 172*7594170eSAndroid Build Coastguard Worker }, 173*7594170eSAndroid Build Coastguard Worker mnemonic = "AbiDump", 174*7594170eSAndroid Build Coastguard Worker ) 175*7594170eSAndroid Build Coastguard Worker 176*7594170eSAndroid Build Coastguard Worker return output 177*7594170eSAndroid Build Coastguard Worker 178*7594170eSAndroid Build Coastguard Workerdef create_linked_abi_dump(ctx, dump_files): 179*7594170eSAndroid Build Coastguard Worker """ Utility function to generate abi dump files.""" 180*7594170eSAndroid Build Coastguard Worker shared_files = ctx.attr.shared[DefaultInfo].files.to_list() 181*7594170eSAndroid Build Coastguard Worker if len(shared_files) != 1: 182*7594170eSAndroid Build Coastguard Worker fail("Expected only one shared library file") 183*7594170eSAndroid Build Coastguard Worker 184*7594170eSAndroid Build Coastguard Worker file = ctx.attr.soname + ".lsdump" 185*7594170eSAndroid Build Coastguard Worker output = ctx.actions.declare_file(file) 186*7594170eSAndroid Build Coastguard Worker args = ctx.actions.args() 187*7594170eSAndroid Build Coastguard Worker 188*7594170eSAndroid Build Coastguard Worker args.add("--root-dir", ".") 189*7594170eSAndroid Build Coastguard Worker args.add("-o", output) 190*7594170eSAndroid Build Coastguard Worker args.add("-so", shared_files[0]) 191*7594170eSAndroid Build Coastguard Worker inputs = dump_files + [shared_files[0]] 192*7594170eSAndroid Build Coastguard Worker 193*7594170eSAndroid Build Coastguard Worker if ctx.file.symbol_file: 194*7594170eSAndroid Build Coastguard Worker args.add("-v", ctx.file.symbol_file.path) 195*7594170eSAndroid Build Coastguard Worker inputs.append(ctx.file.symbol_file) 196*7594170eSAndroid Build Coastguard Worker for v in ctx.attr.exclude_symbol_versions: 197*7594170eSAndroid Build Coastguard Worker args.add("--exclude-symbol-version", v) 198*7594170eSAndroid Build Coastguard Worker for t in ctx.attr.exclude_symbol_tags: 199*7594170eSAndroid Build Coastguard Worker args.add("--exclude-symbol-tag", t) 200*7594170eSAndroid Build Coastguard Worker 201*7594170eSAndroid Build Coastguard Worker args.add("-arch", platforms.get_target_arch(ctx.attr._platform_utils)) 202*7594170eSAndroid Build Coastguard Worker 203*7594170eSAndroid Build Coastguard Worker args.add_all(ctx.attr.root[CcInfo].compilation_context.includes.to_list(), map_each = _include_flag) 204*7594170eSAndroid Build Coastguard Worker 205*7594170eSAndroid Build Coastguard Worker args.add_all([d.path for d in dump_files]) 206*7594170eSAndroid Build Coastguard Worker 207*7594170eSAndroid Build Coastguard Worker ctx.actions.run( 208*7594170eSAndroid Build Coastguard Worker inputs = inputs, 209*7594170eSAndroid Build Coastguard Worker executable = ctx.executable._abi_linker, 210*7594170eSAndroid Build Coastguard Worker outputs = [output], 211*7594170eSAndroid Build Coastguard Worker arguments = [args], 212*7594170eSAndroid Build Coastguard Worker # TODO(b/186116353): enable sandbox once the bug is fixed. 213*7594170eSAndroid Build Coastguard Worker execution_requirements = { 214*7594170eSAndroid Build Coastguard Worker "no-sandbox": "1", 215*7594170eSAndroid Build Coastguard Worker }, 216*7594170eSAndroid Build Coastguard Worker mnemonic = "AbiLink", 217*7594170eSAndroid Build Coastguard Worker ) 218*7594170eSAndroid Build Coastguard Worker 219*7594170eSAndroid Build Coastguard Worker return output 220*7594170eSAndroid Build Coastguard Worker 221*7594170eSAndroid Build Coastguard Workerdef find_abi_config(_ctx): 222*7594170eSAndroid Build Coastguard Worker sdk_version = str(platform_versions.platform_sdk_version) 223*7594170eSAndroid Build Coastguard Worker prev_version = int(parse_apex_sdk_version(sdk_version)) 224*7594170eSAndroid Build Coastguard Worker version = "current" 225*7594170eSAndroid Build Coastguard Worker if platform_versions.platform_sdk_final: 226*7594170eSAndroid Build Coastguard Worker prev_version -= 1 227*7594170eSAndroid Build Coastguard Worker version = sdk_version 228*7594170eSAndroid Build Coastguard Worker 229*7594170eSAndroid Build Coastguard Worker return prev_version, version 230*7594170eSAndroid Build Coastguard Worker 231*7594170eSAndroid Build Coastguard Workerdef create_abi_diff(ctx, dump_file): 232*7594170eSAndroid Build Coastguard Worker prev_version, version = find_abi_config(ctx) 233*7594170eSAndroid Build Coastguard Worker 234*7594170eSAndroid Build Coastguard Worker arch = platforms.get_target_arch(ctx.attr._platform_utils) 235*7594170eSAndroid Build Coastguard Worker bitness = platforms.get_target_bitness(ctx.attr._platform_utils) 236*7594170eSAndroid Build Coastguard Worker abi_class = _ABI_CLASS_PLATFORM 237*7594170eSAndroid Build Coastguard Worker 238*7594170eSAndroid Build Coastguard Worker # The logic below comes from: 239*7594170eSAndroid Build Coastguard Worker # https://cs.android.com/android/platform/superproject/+/master:build/soong/cc/library.go;l=1891;drc=c645853ab73ac8c5889b42f4ce7dc9353ee8fd35 240*7594170eSAndroid Build Coastguard Worker abi_reference_file = None 241*7594170eSAndroid Build Coastguard Worker if not platform_versions.platform_sdk_final: 242*7594170eSAndroid Build Coastguard Worker abi_reference_file = _find_abi_ref_file(ctx, prev_version, arch, bitness, abi_class, dump_file.basename) 243*7594170eSAndroid Build Coastguard Worker if not abi_reference_file: 244*7594170eSAndroid Build Coastguard Worker prev_version -= 1 245*7594170eSAndroid Build Coastguard Worker 246*7594170eSAndroid Build Coastguard Worker diff_files = [] 247*7594170eSAndroid Build Coastguard Worker 248*7594170eSAndroid Build Coastguard Worker # We need to do the abi check for the previous version and current version if the reference 249*7594170eSAndroid Build Coastguard Worker # abi dump files are available. If the current previous version doesn't have the reference 250*7594170eSAndroid Build Coastguard Worker # abi dump file we will check against one version earlier. 251*7594170eSAndroid Build Coastguard Worker if not abi_reference_file: 252*7594170eSAndroid Build Coastguard Worker abi_reference_file = _find_abi_ref_file(ctx, prev_version, arch, bitness, abi_class, dump_file.basename) 253*7594170eSAndroid Build Coastguard Worker if abi_reference_file: 254*7594170eSAndroid Build Coastguard Worker diff_files.append(_run_abi_diff(ctx, arch, prev_version, dump_file, abi_reference_file, True)) 255*7594170eSAndroid Build Coastguard Worker 256*7594170eSAndroid Build Coastguard Worker abi_reference_file = _find_abi_ref_file(ctx, version, arch, bitness, abi_class, dump_file.basename) 257*7594170eSAndroid Build Coastguard Worker if abi_reference_file: 258*7594170eSAndroid Build Coastguard Worker diff_files.append(_run_abi_diff(ctx, arch, version, dump_file, abi_reference_file, False)) 259*7594170eSAndroid Build Coastguard Worker 260*7594170eSAndroid Build Coastguard Worker return diff_files 261*7594170eSAndroid Build Coastguard Worker 262*7594170eSAndroid Build Coastguard Workerdef _run_abi_diff(ctx, arch, version, dump_file, abi_reference_file, prev_version_diff): 263*7594170eSAndroid Build Coastguard Worker lib_name = ctx.attr.soname.removesuffix(".so") 264*7594170eSAndroid Build Coastguard Worker 265*7594170eSAndroid Build Coastguard Worker args = ctx.actions.args() 266*7594170eSAndroid Build Coastguard Worker 267*7594170eSAndroid Build Coastguard Worker if ctx.attr.check_all_apis: 268*7594170eSAndroid Build Coastguard Worker args.add("-check-all-apis") 269*7594170eSAndroid Build Coastguard Worker else: 270*7594170eSAndroid Build Coastguard Worker args.add_all(["-allow-unreferenced-changes", "-allow-unreferenced-elf-symbol-changes"]) 271*7594170eSAndroid Build Coastguard Worker 272*7594170eSAndroid Build Coastguard Worker if prev_version_diff: 273*7594170eSAndroid Build Coastguard Worker args.add("-target-version", version + 1) 274*7594170eSAndroid Build Coastguard Worker diff_file_name = ctx.attr.soname + "." + str(version) + ".abidiff" 275*7594170eSAndroid Build Coastguard Worker else: 276*7594170eSAndroid Build Coastguard Worker args.add("-target-version", "current") 277*7594170eSAndroid Build Coastguard Worker diff_file_name = ctx.attr.soname + ".abidiff" 278*7594170eSAndroid Build Coastguard Worker 279*7594170eSAndroid Build Coastguard Worker args.add("-allow-extensions") 280*7594170eSAndroid Build Coastguard Worker 281*7594170eSAndroid Build Coastguard Worker if len(ctx.attr.diff_flags) > 0: 282*7594170eSAndroid Build Coastguard Worker args.add_all(ctx.attr.diff_flags) 283*7594170eSAndroid Build Coastguard Worker 284*7594170eSAndroid Build Coastguard Worker args.add("-lib", lib_name) 285*7594170eSAndroid Build Coastguard Worker args.add("-arch", arch) 286*7594170eSAndroid Build Coastguard Worker 287*7594170eSAndroid Build Coastguard Worker diff_file = ctx.actions.declare_file(diff_file_name) 288*7594170eSAndroid Build Coastguard Worker args.add("-o", diff_file) 289*7594170eSAndroid Build Coastguard Worker args.add("-new", dump_file) 290*7594170eSAndroid Build Coastguard Worker args.add("-old", abi_reference_file) 291*7594170eSAndroid Build Coastguard Worker 292*7594170eSAndroid Build Coastguard Worker ctx.actions.run( 293*7594170eSAndroid Build Coastguard Worker inputs = [dump_file, abi_reference_file], 294*7594170eSAndroid Build Coastguard Worker executable = ctx.executable._abi_diff, 295*7594170eSAndroid Build Coastguard Worker outputs = [diff_file], 296*7594170eSAndroid Build Coastguard Worker arguments = [args], 297*7594170eSAndroid Build Coastguard Worker execution_requirements = { 298*7594170eSAndroid Build Coastguard Worker "no-sandbox": "1", 299*7594170eSAndroid Build Coastguard Worker }, 300*7594170eSAndroid Build Coastguard Worker mnemonic = "AbiDiff", 301*7594170eSAndroid Build Coastguard Worker ) 302*7594170eSAndroid Build Coastguard Worker 303*7594170eSAndroid Build Coastguard Worker return diff_file 304*7594170eSAndroid Build Coastguard Worker 305*7594170eSAndroid Build Coastguard Workerdef _find_abi_ref_file(ctx, version, arch, bitness, abi_class, lsdump_name): 306*7594170eSAndroid Build Coastguard Worker # Currently we only support platform. 307*7594170eSAndroid Build Coastguard Worker if abi_class == _ABI_CLASS_PLATFORM: 308*7594170eSAndroid Build Coastguard Worker abi_ref_dumps = ctx.attr.abi_ref_dumps_platform 309*7594170eSAndroid Build Coastguard Worker else: 310*7594170eSAndroid Build Coastguard Worker fail("Unsupported ABI class: %s" % abi_class) 311*7594170eSAndroid Build Coastguard Worker 312*7594170eSAndroid Build Coastguard Worker # The expected reference abi dump file 313*7594170eSAndroid Build Coastguard Worker ref_dump_file = paths.join( 314*7594170eSAndroid Build Coastguard Worker ctx.attr.ref_dumps_home, 315*7594170eSAndroid Build Coastguard Worker abi_class, 316*7594170eSAndroid Build Coastguard Worker str(version), 317*7594170eSAndroid Build Coastguard Worker str(bitness), 318*7594170eSAndroid Build Coastguard Worker arch, 319*7594170eSAndroid Build Coastguard Worker "source-based", 320*7594170eSAndroid Build Coastguard Worker lsdump_name, 321*7594170eSAndroid Build Coastguard Worker ) 322*7594170eSAndroid Build Coastguard Worker 323*7594170eSAndroid Build Coastguard Worker ref_file = None 324*7594170eSAndroid Build Coastguard Worker 325*7594170eSAndroid Build Coastguard Worker for file in abi_ref_dumps.files.to_list(): 326*7594170eSAndroid Build Coastguard Worker if ref_dump_file == file.path: 327*7594170eSAndroid Build Coastguard Worker ref_file = file 328*7594170eSAndroid Build Coastguard Worker break 329*7594170eSAndroid Build Coastguard Worker 330*7594170eSAndroid Build Coastguard Worker return ref_file 331*7594170eSAndroid Build Coastguard Worker 332*7594170eSAndroid Build Coastguard Workerdef _abi_diff_enabled(ctx, lib_name, is_aspect): 333*7594170eSAndroid Build Coastguard Worker # The logic here is based on: 334*7594170eSAndroid Build Coastguard Worker # https://cs.android.com/android/platform/superproject/+/master:build/soong/cc/sabi.go;l=103;drc=cb0ac95bde896fa2aa59193a37ceb580758c322c 335*7594170eSAndroid Build Coastguard Worker 336*7594170eSAndroid Build Coastguard Worker if ctx.attr._skip_abi_checks[BuildSettingInfo].value: 337*7594170eSAndroid Build Coastguard Worker return False 338*7594170eSAndroid Build Coastguard Worker if not platforms.is_target_android(ctx.attr._platform_utils): 339*7594170eSAndroid Build Coastguard Worker return False 340*7594170eSAndroid Build Coastguard Worker if ctx.coverage_instrumented(): 341*7594170eSAndroid Build Coastguard Worker return False 342*7594170eSAndroid Build Coastguard Worker if ctx.attr._within_apex[BuildSettingInfo].value: 343*7594170eSAndroid Build Coastguard Worker if not is_aspect and not ctx.attr.has_stubs: 344*7594170eSAndroid Build Coastguard Worker return False 345*7594170eSAndroid Build Coastguard Worker 346*7594170eSAndroid Build Coastguard Worker # Logic comes from here: 347*7594170eSAndroid Build Coastguard Worker # https://cs.android.com/android/platform/superproject/+/master:build/soong/cc/sabi.go;l=158;drc=cb0ac95bde896fa2aa59193a37ceb580758c322c 348*7594170eSAndroid Build Coastguard Worker 349*7594170eSAndroid Build Coastguard Worker elif is_bionic_lib(lib_name) or is_bootstrap_lib(lib_name): 350*7594170eSAndroid Build Coastguard Worker return False 351*7594170eSAndroid Build Coastguard Worker 352*7594170eSAndroid Build Coastguard Worker # TODO(b/260611960): handle all the other checks in sabi.go 353*7594170eSAndroid Build Coastguard Worker return True 354*7594170eSAndroid Build Coastguard Worker 355*7594170eSAndroid Build Coastguard Workerdef _abi_dump_impl(ctx): 356*7594170eSAndroid Build Coastguard Worker diff_files = depset() 357*7594170eSAndroid Build Coastguard Worker if _abi_diff_enabled(ctx, ctx.attr.soname.removesuffix(".so"), False) and ctx.attr.root != None: 358*7594170eSAndroid Build Coastguard Worker dump_files = ctx.attr.root[AbiDumpInfo].dump_files.to_list() 359*7594170eSAndroid Build Coastguard Worker linked_dump_file = create_linked_abi_dump(ctx, dump_files) 360*7594170eSAndroid Build Coastguard Worker diff_files = depset(create_abi_diff(ctx, linked_dump_file)) 361*7594170eSAndroid Build Coastguard Worker 362*7594170eSAndroid Build Coastguard Worker return ([ 363*7594170eSAndroid Build Coastguard Worker DefaultInfo(files = diff_files), 364*7594170eSAndroid Build Coastguard Worker AbiDiffInfo(diff_files = diff_files), 365*7594170eSAndroid Build Coastguard Worker ]) 366*7594170eSAndroid Build Coastguard Worker 367*7594170eSAndroid Build Coastguard Workerabi_dump = rule( 368*7594170eSAndroid Build Coastguard Worker implementation = _abi_dump_impl, 369*7594170eSAndroid Build Coastguard Worker attrs = { 370*7594170eSAndroid Build Coastguard Worker "shared": attr.label(mandatory = True, providers = [CcSharedLibraryInfo]), 371*7594170eSAndroid Build Coastguard Worker "root": attr.label(providers = [CcInfo], aspects = [abi_dump_aspect]), 372*7594170eSAndroid Build Coastguard Worker "soname": attr.string(mandatory = True), 373*7594170eSAndroid Build Coastguard Worker "has_stubs": attr.bool(default = False), 374*7594170eSAndroid Build Coastguard Worker "enabled": attr.bool(default = False), 375*7594170eSAndroid Build Coastguard Worker "explicitly_disabled": attr.bool(default = False), 376*7594170eSAndroid Build Coastguard Worker "symbol_file": attr.label(allow_single_file = True), 377*7594170eSAndroid Build Coastguard Worker "exclude_symbol_versions": attr.string_list(default = []), 378*7594170eSAndroid Build Coastguard Worker "exclude_symbol_tags": attr.string_list(default = []), 379*7594170eSAndroid Build Coastguard Worker "check_all_apis": attr.bool(default = False), 380*7594170eSAndroid Build Coastguard Worker "diff_flags": attr.string_list(default = []), 381*7594170eSAndroid Build Coastguard Worker "abi_ref_dumps_platform": attr.label(default = "//prebuilts/abi-dumps/platform:bp2build_all_srcs"), 382*7594170eSAndroid Build Coastguard Worker "ref_dumps_home": attr.string(default = "prebuilts/abi-dumps"), 383*7594170eSAndroid Build Coastguard Worker "_skip_abi_checks": attr.label( 384*7594170eSAndroid Build Coastguard Worker default = "//build/bazel/flags/cc/abi:skip_abi_checks", 385*7594170eSAndroid Build Coastguard Worker ), 386*7594170eSAndroid Build Coastguard Worker "_within_apex": attr.label( 387*7594170eSAndroid Build Coastguard Worker default = "//build/bazel/rules/apex:within_apex", 388*7594170eSAndroid Build Coastguard Worker ), 389*7594170eSAndroid Build Coastguard Worker # TODO(b/254625084): For the following tools we need to support darwin as well. 390*7594170eSAndroid Build Coastguard Worker "_abi_dumper": attr.label( 391*7594170eSAndroid Build Coastguard Worker allow_files = True, 392*7594170eSAndroid Build Coastguard Worker executable = True, 393*7594170eSAndroid Build Coastguard Worker cfg = "exec", 394*7594170eSAndroid Build Coastguard Worker default = Label("//prebuilts/clang-tools:linux-x86/bin/header-abi-dumper"), 395*7594170eSAndroid Build Coastguard Worker ), 396*7594170eSAndroid Build Coastguard Worker "_abi_linker": attr.label( 397*7594170eSAndroid Build Coastguard Worker allow_files = True, 398*7594170eSAndroid Build Coastguard Worker executable = True, 399*7594170eSAndroid Build Coastguard Worker cfg = "exec", 400*7594170eSAndroid Build Coastguard Worker default = Label("//prebuilts/clang-tools:linux-x86/bin/header-abi-linker"), 401*7594170eSAndroid Build Coastguard Worker ), 402*7594170eSAndroid Build Coastguard Worker "_abi_diff": attr.label( 403*7594170eSAndroid Build Coastguard Worker allow_files = True, 404*7594170eSAndroid Build Coastguard Worker executable = True, 405*7594170eSAndroid Build Coastguard Worker cfg = "exec", 406*7594170eSAndroid Build Coastguard Worker default = Label("//prebuilts/clang-tools:linux-x86/bin/header-abi-diff"), 407*7594170eSAndroid Build Coastguard Worker ), 408*7594170eSAndroid Build Coastguard Worker "_platform_utils": attr.label(default = Label("//build/bazel/platforms:platform_utils")), 409*7594170eSAndroid Build Coastguard Worker }, 410*7594170eSAndroid Build Coastguard Worker fragments = ["cpp"], 411*7594170eSAndroid Build Coastguard Worker toolchains = ["@bazel_tools//tools/cpp:toolchain_type"], 412*7594170eSAndroid Build Coastguard Worker) 413