1*7594170eSAndroid Build Coastguard Worker# Copyright (C) 2021 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 Worker"""A macro to handle shared library stripping.""" 16*7594170eSAndroid Build Coastguard Worker 17*7594170eSAndroid Build Coastguard Workerload("@bazel_skylib//lib:paths.bzl", "paths") 18*7594170eSAndroid Build Coastguard Workerload(":cc_library_common.bzl", "CcAndroidMkInfo", "check_valid_ldlibs") 19*7594170eSAndroid Build Coastguard Workerload(":clang_tidy.bzl", "collect_deps_clang_tidy_info") 20*7594170eSAndroid Build Coastguard Workerload( 21*7594170eSAndroid Build Coastguard Worker ":composed_transitions.bzl", 22*7594170eSAndroid Build Coastguard Worker "drop_lto_and_sanitizer_transition", 23*7594170eSAndroid Build Coastguard Worker "lto_and_sanitizer_deps_transition", 24*7594170eSAndroid Build Coastguard Worker) 25*7594170eSAndroid Build Coastguard Worker 26*7594170eSAndroid Build Coastguard WorkerCcUnstrippedInfo = provider( 27*7594170eSAndroid Build Coastguard Worker "Provides unstripped binary/shared library", 28*7594170eSAndroid Build Coastguard Worker fields = { 29*7594170eSAndroid Build Coastguard Worker "unstripped": "unstripped target", 30*7594170eSAndroid Build Coastguard Worker }, 31*7594170eSAndroid Build Coastguard Worker) 32*7594170eSAndroid Build Coastguard Worker 33*7594170eSAndroid Build Coastguard Worker# Keep this consistent with soong/cc/strip.go#NeedsStrip. 34*7594170eSAndroid Build Coastguard Workerdef _needs_strip(ctx): 35*7594170eSAndroid Build Coastguard Worker if ctx.attr.none: 36*7594170eSAndroid Build Coastguard Worker return False 37*7594170eSAndroid Build Coastguard Worker if ctx.target_platform_has_constraint(ctx.attr._android_constraint[platform_common.ConstraintValueInfo]): 38*7594170eSAndroid Build Coastguard Worker return True 39*7594170eSAndroid Build Coastguard Worker return (ctx.attr.all or ctx.attr.keep_symbols or 40*7594170eSAndroid Build Coastguard Worker ctx.attr.keep_symbols_and_debug_frame or ctx.attr.keep_symbols_list) 41*7594170eSAndroid Build Coastguard Worker 42*7594170eSAndroid Build Coastguard Worker# Keep this consistent with soong/cc/strip.go#strip and soong/cc/builder.go#transformStrip. 43*7594170eSAndroid Build Coastguard Workerdef _get_strip_args(attrs): 44*7594170eSAndroid Build Coastguard Worker strip_args = [] 45*7594170eSAndroid Build Coastguard Worker keep_mini_debug_info = False 46*7594170eSAndroid Build Coastguard Worker if attrs.keep_symbols: 47*7594170eSAndroid Build Coastguard Worker strip_args.append("--keep-symbols") 48*7594170eSAndroid Build Coastguard Worker elif attrs.keep_symbols_and_debug_frame: 49*7594170eSAndroid Build Coastguard Worker strip_args.append("--keep-symbols-and-debug-frame") 50*7594170eSAndroid Build Coastguard Worker elif attrs.keep_symbols_list: 51*7594170eSAndroid Build Coastguard Worker strip_args.append("-k" + ",".join(attrs.keep_symbols_list)) 52*7594170eSAndroid Build Coastguard Worker elif not attrs.all: 53*7594170eSAndroid Build Coastguard Worker strip_args.append("--keep-mini-debug-info") 54*7594170eSAndroid Build Coastguard Worker keep_mini_debug_info = True 55*7594170eSAndroid Build Coastguard Worker 56*7594170eSAndroid Build Coastguard Worker if not keep_mini_debug_info: 57*7594170eSAndroid Build Coastguard Worker strip_args.append("--add-gnu-debuglink") 58*7594170eSAndroid Build Coastguard Worker 59*7594170eSAndroid Build Coastguard Worker return strip_args 60*7594170eSAndroid Build Coastguard Worker 61*7594170eSAndroid Build Coastguard Worker# https://cs.android.com/android/platform/superproject/+/master:build/soong/cc/builder.go;l=131-146;drc=master 62*7594170eSAndroid Build Coastguard Workerdef stripped_impl(ctx, file, prefix = "", stem = "", suffix = "", extension = "", subdir = ""): 63*7594170eSAndroid Build Coastguard Worker filename_stem = stem or ctx.attr.name 64*7594170eSAndroid Build Coastguard Worker filename = prefix + filename_stem + suffix + extension 65*7594170eSAndroid Build Coastguard Worker out_file = ctx.actions.declare_file( 66*7594170eSAndroid Build Coastguard Worker paths.join( 67*7594170eSAndroid Build Coastguard Worker subdir, # Prevent name collision by generating in a directory unique to the target 68*7594170eSAndroid Build Coastguard Worker filename, 69*7594170eSAndroid Build Coastguard Worker ), 70*7594170eSAndroid Build Coastguard Worker ) 71*7594170eSAndroid Build Coastguard Worker if not _needs_strip(ctx): 72*7594170eSAndroid Build Coastguard Worker ctx.actions.symlink( 73*7594170eSAndroid Build Coastguard Worker output = out_file, 74*7594170eSAndroid Build Coastguard Worker target_file = file, 75*7594170eSAndroid Build Coastguard Worker ) 76*7594170eSAndroid Build Coastguard Worker return out_file 77*7594170eSAndroid Build Coastguard Worker d_file = ctx.actions.declare_file( 78*7594170eSAndroid Build Coastguard Worker paths.join( 79*7594170eSAndroid Build Coastguard Worker subdir, 80*7594170eSAndroid Build Coastguard Worker filename + ".d", 81*7594170eSAndroid Build Coastguard Worker ), 82*7594170eSAndroid Build Coastguard Worker ) 83*7594170eSAndroid Build Coastguard Worker 84*7594170eSAndroid Build Coastguard Worker ctx.actions.run( 85*7594170eSAndroid Build Coastguard Worker env = { 86*7594170eSAndroid Build Coastguard Worker "CREATE_MINIDEBUGINFO": ctx.executable._create_minidebuginfo.path, 87*7594170eSAndroid Build Coastguard Worker "XZ": ctx.executable._xz.path, 88*7594170eSAndroid Build Coastguard Worker "CLANG_BIN": ctx.executable._ar.dirname, 89*7594170eSAndroid Build Coastguard Worker }, 90*7594170eSAndroid Build Coastguard Worker inputs = [file], 91*7594170eSAndroid Build Coastguard Worker tools = [ 92*7594170eSAndroid Build Coastguard Worker ctx.executable._ar, 93*7594170eSAndroid Build Coastguard Worker ctx.executable._create_minidebuginfo, 94*7594170eSAndroid Build Coastguard Worker ctx.executable._objcopy, 95*7594170eSAndroid Build Coastguard Worker ctx.executable._readelf, 96*7594170eSAndroid Build Coastguard Worker ctx.executable._strip, 97*7594170eSAndroid Build Coastguard Worker ctx.executable._strip_script, 98*7594170eSAndroid Build Coastguard Worker ctx.executable._xz, 99*7594170eSAndroid Build Coastguard Worker ], 100*7594170eSAndroid Build Coastguard Worker outputs = [out_file, d_file], 101*7594170eSAndroid Build Coastguard Worker executable = ctx.executable._strip_script, 102*7594170eSAndroid Build Coastguard Worker arguments = _get_strip_args(ctx.attr) + [ 103*7594170eSAndroid Build Coastguard Worker "-i", 104*7594170eSAndroid Build Coastguard Worker file.path, 105*7594170eSAndroid Build Coastguard Worker "-o", 106*7594170eSAndroid Build Coastguard Worker out_file.path, 107*7594170eSAndroid Build Coastguard Worker "-d", 108*7594170eSAndroid Build Coastguard Worker d_file.path, 109*7594170eSAndroid Build Coastguard Worker ], 110*7594170eSAndroid Build Coastguard Worker mnemonic = "CcStrip", 111*7594170eSAndroid Build Coastguard Worker ) 112*7594170eSAndroid Build Coastguard Worker return out_file 113*7594170eSAndroid Build Coastguard Worker 114*7594170eSAndroid Build Coastguard Workerstrip_attrs = dict( 115*7594170eSAndroid Build Coastguard Worker keep_symbols = attr.bool(default = False), 116*7594170eSAndroid Build Coastguard Worker keep_symbols_and_debug_frame = attr.bool(default = False), 117*7594170eSAndroid Build Coastguard Worker all = attr.bool(default = False), 118*7594170eSAndroid Build Coastguard Worker none = attr.bool(default = False), 119*7594170eSAndroid Build Coastguard Worker keep_symbols_list = attr.string_list(default = []), 120*7594170eSAndroid Build Coastguard Worker) 121*7594170eSAndroid Build Coastguard Workercommon_strip_attrs = dict( 122*7594170eSAndroid Build Coastguard Worker strip_attrs, 123*7594170eSAndroid Build Coastguard Worker _xz = attr.label( 124*7594170eSAndroid Build Coastguard Worker cfg = "exec", 125*7594170eSAndroid Build Coastguard Worker executable = True, 126*7594170eSAndroid Build Coastguard Worker allow_single_file = True, 127*7594170eSAndroid Build Coastguard Worker default = "//prebuilts/build-tools:linux-x86/bin/xz", 128*7594170eSAndroid Build Coastguard Worker ), 129*7594170eSAndroid Build Coastguard Worker _create_minidebuginfo = attr.label( 130*7594170eSAndroid Build Coastguard Worker cfg = "exec", 131*7594170eSAndroid Build Coastguard Worker executable = True, 132*7594170eSAndroid Build Coastguard Worker allow_single_file = True, 133*7594170eSAndroid Build Coastguard Worker default = "//prebuilts/build-tools:linux-x86/bin/create_minidebuginfo", 134*7594170eSAndroid Build Coastguard Worker ), 135*7594170eSAndroid Build Coastguard Worker _strip_script = attr.label( 136*7594170eSAndroid Build Coastguard Worker cfg = "exec", 137*7594170eSAndroid Build Coastguard Worker executable = True, 138*7594170eSAndroid Build Coastguard Worker allow_single_file = True, 139*7594170eSAndroid Build Coastguard Worker default = "//build/soong/scripts:strip.sh", 140*7594170eSAndroid Build Coastguard Worker ), 141*7594170eSAndroid Build Coastguard Worker _ar = attr.label( 142*7594170eSAndroid Build Coastguard Worker cfg = "exec", 143*7594170eSAndroid Build Coastguard Worker executable = True, 144*7594170eSAndroid Build Coastguard Worker allow_single_file = True, 145*7594170eSAndroid Build Coastguard Worker default = "//prebuilts/clang/host/linux-x86:llvm-ar", 146*7594170eSAndroid Build Coastguard Worker ), 147*7594170eSAndroid Build Coastguard Worker _strip = attr.label( 148*7594170eSAndroid Build Coastguard Worker cfg = "exec", 149*7594170eSAndroid Build Coastguard Worker executable = True, 150*7594170eSAndroid Build Coastguard Worker allow_single_file = True, 151*7594170eSAndroid Build Coastguard Worker default = "//prebuilts/clang/host/linux-x86:llvm-strip", 152*7594170eSAndroid Build Coastguard Worker ), 153*7594170eSAndroid Build Coastguard Worker _readelf = attr.label( 154*7594170eSAndroid Build Coastguard Worker cfg = "exec", 155*7594170eSAndroid Build Coastguard Worker executable = True, 156*7594170eSAndroid Build Coastguard Worker allow_single_file = True, 157*7594170eSAndroid Build Coastguard Worker default = "//prebuilts/clang/host/linux-x86:llvm-readelf", 158*7594170eSAndroid Build Coastguard Worker ), 159*7594170eSAndroid Build Coastguard Worker _objcopy = attr.label( 160*7594170eSAndroid Build Coastguard Worker cfg = "exec", 161*7594170eSAndroid Build Coastguard Worker executable = True, 162*7594170eSAndroid Build Coastguard Worker allow_single_file = True, 163*7594170eSAndroid Build Coastguard Worker default = "//prebuilts/clang/host/linux-x86:llvm-objcopy", 164*7594170eSAndroid Build Coastguard Worker ), 165*7594170eSAndroid Build Coastguard Worker _cc_toolchain = attr.label( 166*7594170eSAndroid Build Coastguard Worker default = Label("@local_config_cc//:toolchain"), 167*7594170eSAndroid Build Coastguard Worker providers = [cc_common.CcToolchainInfo], 168*7594170eSAndroid Build Coastguard Worker ), 169*7594170eSAndroid Build Coastguard Worker _android_constraint = attr.label( 170*7594170eSAndroid Build Coastguard Worker default = Label("//build/bazel_common_rules/platforms/os:android"), 171*7594170eSAndroid Build Coastguard Worker ), 172*7594170eSAndroid Build Coastguard Worker _darwin_constraint = attr.label( 173*7594170eSAndroid Build Coastguard Worker default = Label("//build/bazel_common_rules/platforms/os:darwin"), 174*7594170eSAndroid Build Coastguard Worker ), 175*7594170eSAndroid Build Coastguard Worker _linux_constraint = attr.label( 176*7594170eSAndroid Build Coastguard Worker default = Label("//build/bazel_common_rules/platforms/os:linux"), 177*7594170eSAndroid Build Coastguard Worker ), 178*7594170eSAndroid Build Coastguard Worker _windows_constraint = attr.label( 179*7594170eSAndroid Build Coastguard Worker default = Label("//build/bazel_common_rules/platforms/os:windows"), 180*7594170eSAndroid Build Coastguard Worker ), 181*7594170eSAndroid Build Coastguard Worker) 182*7594170eSAndroid Build Coastguard Worker 183*7594170eSAndroid Build Coastguard Workerdef _stripped_shared_library_impl(ctx): 184*7594170eSAndroid Build Coastguard Worker check_valid_ldlibs(ctx, ctx.attr.linkopts) 185*7594170eSAndroid Build Coastguard Worker 186*7594170eSAndroid Build Coastguard Worker out_file = stripped_impl(ctx, ctx.file.src, prefix = "lib", extension = ".so", subdir = ctx.attr.name) 187*7594170eSAndroid Build Coastguard Worker 188*7594170eSAndroid Build Coastguard Worker return [ 189*7594170eSAndroid Build Coastguard Worker DefaultInfo(files = depset([out_file])), 190*7594170eSAndroid Build Coastguard Worker ctx.attr.src[CcSharedLibraryInfo], 191*7594170eSAndroid Build Coastguard Worker ctx.attr.src[OutputGroupInfo], 192*7594170eSAndroid Build Coastguard Worker ] 193*7594170eSAndroid Build Coastguard Worker 194*7594170eSAndroid Build Coastguard Workerstripped_shared_library = rule( 195*7594170eSAndroid Build Coastguard Worker implementation = _stripped_shared_library_impl, 196*7594170eSAndroid Build Coastguard Worker attrs = dict( 197*7594170eSAndroid Build Coastguard Worker common_strip_attrs, 198*7594170eSAndroid Build Coastguard Worker src = attr.label( 199*7594170eSAndroid Build Coastguard Worker mandatory = True, 200*7594170eSAndroid Build Coastguard Worker providers = [CcSharedLibraryInfo], 201*7594170eSAndroid Build Coastguard Worker allow_single_file = True, 202*7594170eSAndroid Build Coastguard Worker ), 203*7594170eSAndroid Build Coastguard Worker linkopts = attr.string_list(default = []), # Used for validation 204*7594170eSAndroid Build Coastguard Worker ), 205*7594170eSAndroid Build Coastguard Worker toolchains = ["@bazel_tools//tools/cpp:toolchain_type"], 206*7594170eSAndroid Build Coastguard Worker) 207*7594170eSAndroid Build Coastguard Worker 208*7594170eSAndroid Build Coastguard Worker# A marker provider to distinguish a cc_binary from everything else that exports 209*7594170eSAndroid Build Coastguard Worker# a CcInfo. 210*7594170eSAndroid Build Coastguard WorkerStrippedCcBinaryInfo = provider() 211*7594170eSAndroid Build Coastguard Worker 212*7594170eSAndroid Build Coastguard Workerdef _stripped_binary_impl(ctx): 213*7594170eSAndroid Build Coastguard Worker check_valid_ldlibs(ctx, ctx.attr.linkopts) 214*7594170eSAndroid Build Coastguard Worker 215*7594170eSAndroid Build Coastguard Worker common_providers = [ 216*7594170eSAndroid Build Coastguard Worker ctx.attr.src[0][CcInfo], 217*7594170eSAndroid Build Coastguard Worker ctx.attr.src[0][InstrumentedFilesInfo], 218*7594170eSAndroid Build Coastguard Worker ctx.attr.src[0][DebugPackageInfo], 219*7594170eSAndroid Build Coastguard Worker ctx.attr.src[0][OutputGroupInfo], 220*7594170eSAndroid Build Coastguard Worker StrippedCcBinaryInfo(), # a marker for dependents 221*7594170eSAndroid Build Coastguard Worker CcUnstrippedInfo( 222*7594170eSAndroid Build Coastguard Worker unstripped = ctx.attr.unstripped, 223*7594170eSAndroid Build Coastguard Worker ), 224*7594170eSAndroid Build Coastguard Worker collect_deps_clang_tidy_info(ctx), 225*7594170eSAndroid Build Coastguard Worker ] + [ 226*7594170eSAndroid Build Coastguard Worker d[CcAndroidMkInfo] 227*7594170eSAndroid Build Coastguard Worker for d in ctx.attr.androidmk_deps 228*7594170eSAndroid Build Coastguard Worker ] 229*7594170eSAndroid Build Coastguard Worker 230*7594170eSAndroid Build Coastguard Worker # Generate binary in a directory unique to this target to prevent possible collisions due to common `stem` 231*7594170eSAndroid Build Coastguard Worker # Generate in `bin` to prevent incrementality issues for mixed builds where <package>/<name> could be a file and not a dir 232*7594170eSAndroid Build Coastguard Worker subdir = paths.join("bin", ctx.attr.name) 233*7594170eSAndroid Build Coastguard Worker out_file = stripped_impl(ctx, ctx.file.src, stem = ctx.attr.stem, suffix = ctx.attr.suffix, subdir = subdir) 234*7594170eSAndroid Build Coastguard Worker 235*7594170eSAndroid Build Coastguard Worker return [ 236*7594170eSAndroid Build Coastguard Worker DefaultInfo( 237*7594170eSAndroid Build Coastguard Worker files = depset([out_file]), 238*7594170eSAndroid Build Coastguard Worker executable = out_file, 239*7594170eSAndroid Build Coastguard Worker runfiles = ctx.attr.src[0][DefaultInfo].default_runfiles, 240*7594170eSAndroid Build Coastguard Worker ), 241*7594170eSAndroid Build Coastguard Worker ] + common_providers 242*7594170eSAndroid Build Coastguard Worker 243*7594170eSAndroid Build Coastguard Worker_rule_attrs = dict( 244*7594170eSAndroid Build Coastguard Worker common_strip_attrs, 245*7594170eSAndroid Build Coastguard Worker src = attr.label( 246*7594170eSAndroid Build Coastguard Worker mandatory = True, 247*7594170eSAndroid Build Coastguard Worker allow_single_file = True, 248*7594170eSAndroid Build Coastguard Worker providers = [CcInfo], 249*7594170eSAndroid Build Coastguard Worker cfg = lto_and_sanitizer_deps_transition, 250*7594170eSAndroid Build Coastguard Worker ), 251*7594170eSAndroid Build Coastguard Worker linkopts = attr.string_list(default = []), # Used for validation 252*7594170eSAndroid Build Coastguard Worker runtime_deps = attr.label_list( 253*7594170eSAndroid Build Coastguard Worker providers = [CcInfo], 254*7594170eSAndroid Build Coastguard Worker doc = "Deps that should be installed along with this target. Read by the apex cc aspect.", 255*7594170eSAndroid Build Coastguard Worker ), 256*7594170eSAndroid Build Coastguard Worker androidmk_deps = attr.label_list( 257*7594170eSAndroid Build Coastguard Worker providers = [CcAndroidMkInfo], 258*7594170eSAndroid Build Coastguard Worker cfg = lto_and_sanitizer_deps_transition, 259*7594170eSAndroid Build Coastguard Worker ), 260*7594170eSAndroid Build Coastguard Worker stem = attr.string(), 261*7594170eSAndroid Build Coastguard Worker suffix = attr.string(), 262*7594170eSAndroid Build Coastguard Worker unstripped = attr.label( 263*7594170eSAndroid Build Coastguard Worker mandatory = True, 264*7594170eSAndroid Build Coastguard Worker allow_single_file = True, 265*7594170eSAndroid Build Coastguard Worker cfg = lto_and_sanitizer_deps_transition, 266*7594170eSAndroid Build Coastguard Worker doc = "Unstripped binary to be returned by ", 267*7594170eSAndroid Build Coastguard Worker ), 268*7594170eSAndroid Build Coastguard Worker package_name = attr.string( 269*7594170eSAndroid Build Coastguard Worker mandatory = True, 270*7594170eSAndroid Build Coastguard Worker doc = "Just the path to the target package. Used by transitions.", 271*7594170eSAndroid Build Coastguard Worker ), 272*7594170eSAndroid Build Coastguard Worker _allowlist_function_transition = attr.label( 273*7594170eSAndroid Build Coastguard Worker default = "@bazel_tools//tools/allowlists/function_transition_allowlist", 274*7594170eSAndroid Build Coastguard Worker ), 275*7594170eSAndroid Build Coastguard Worker) 276*7594170eSAndroid Build Coastguard Worker 277*7594170eSAndroid Build Coastguard Workerstripped_binary = rule( 278*7594170eSAndroid Build Coastguard Worker implementation = _stripped_binary_impl, 279*7594170eSAndroid Build Coastguard Worker cfg = drop_lto_and_sanitizer_transition, 280*7594170eSAndroid Build Coastguard Worker attrs = _rule_attrs, 281*7594170eSAndroid Build Coastguard Worker executable = True, 282*7594170eSAndroid Build Coastguard Worker toolchains = ["@bazel_tools//tools/cpp:toolchain_type"], 283*7594170eSAndroid Build Coastguard Worker) 284*7594170eSAndroid Build Coastguard Worker 285*7594170eSAndroid Build Coastguard Workerstripped_test = rule( 286*7594170eSAndroid Build Coastguard Worker implementation = _stripped_binary_impl, 287*7594170eSAndroid Build Coastguard Worker cfg = drop_lto_and_sanitizer_transition, 288*7594170eSAndroid Build Coastguard Worker attrs = _rule_attrs, 289*7594170eSAndroid Build Coastguard Worker test = True, 290*7594170eSAndroid Build Coastguard Worker toolchains = ["@bazel_tools//tools/cpp:toolchain_type"], 291*7594170eSAndroid Build Coastguard Worker) 292