blob: 3ed14ca0e50057b3edaf5ad6ed24950527e664c0 [file] [log] [blame]
"""
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.
"""
"""A macro to handle shared library stripping."""
load("@bazel_tools//tools/cpp:toolchain_utils.bzl", "find_cpp_toolchain")
load(":cc_library_common.bzl", "CcAndroidMkInfo")
CcUnstrippedInfo = provider(
"Provides unstripped binary/shared library",
fields = {
"unstripped": "unstripped target",
},
)
# Keep this consistent with soong/cc/strip.go#NeedsStrip.
def _needs_strip(ctx):
if ctx.attr.none:
return False
if ctx.target_platform_has_constraint(ctx.attr._android_constraint[platform_common.ConstraintValueInfo]):
return True
return (ctx.attr.all or ctx.attr.keep_symbols or
ctx.attr.keep_symbols_and_debug_frame or ctx.attr.keep_symbols_list)
# Keep this consistent with soong/cc/strip.go#strip and soong/cc/builder.go#transformStrip.
def _get_strip_args(attrs):
strip_args = []
keep_mini_debug_info = False
if attrs.keep_symbols:
strip_args += ["--keep-symbols"]
elif attrs.keep_symbols_and_debug_frame:
strip_args += ["--keep-symbols-and-debug-frame"]
elif attrs.keep_symbols_list:
strip_args += ["-k" + ",".join(attrs.keep_symbols_list)]
elif not attrs.all:
strip_args += ["--keep-mini-debug-info"]
keep_mini_debug_info = True
if not keep_mini_debug_info:
strip_args += ["--add-gnu-debuglink"]
return strip_args
# https://cs.android.com/android/platform/superproject/+/master:build/soong/cc/builder.go;l=131-146;drc=master
def stripped_impl(ctx, prefix = "", suffix = "", extension = ""):
out_file = ctx.actions.declare_file(prefix + ctx.attr.name + suffix + extension)
if not _needs_strip(ctx):
ctx.actions.symlink(
output = out_file,
target_file = ctx.files.src[0],
)
return out_file
cc_toolchain = find_cpp_toolchain(ctx)
d_file = ctx.actions.declare_file(ctx.attr.name + ".d")
ctx.actions.run(
env = {
"CREATE_MINIDEBUGINFO": ctx.executable._create_minidebuginfo.path,
"XZ": ctx.executable._xz.path,
"CLANG_BIN": ctx.executable._ar.dirname,
},
inputs = ctx.files.src,
tools = [
ctx.executable._ar,
ctx.executable._create_minidebuginfo,
ctx.executable._objcopy,
ctx.executable._readelf,
ctx.executable._strip,
ctx.executable._strip_script,
ctx.executable._xz,
],
outputs = [out_file, d_file],
executable = ctx.executable._strip_script,
arguments = _get_strip_args(ctx.attr) + [
"-i",
ctx.files.src[0].path,
"-o",
out_file.path,
"-d",
d_file.path,
],
mnemonic = "CcStrip",
)
return out_file
strip_attrs = dict(
keep_symbols = attr.bool(default = False),
keep_symbols_and_debug_frame = attr.bool(default = False),
all = attr.bool(default = False),
none = attr.bool(default = False),
keep_symbols_list = attr.string_list(default = []),
)
common_strip_attrs = dict(
strip_attrs,
_xz = attr.label(
cfg = "exec",
executable = True,
allow_single_file = True,
default = "//prebuilts/build-tools:linux-x86/bin/xz",
),
_create_minidebuginfo = attr.label(
cfg = "exec",
executable = True,
allow_single_file = True,
default = "//prebuilts/build-tools:linux-x86/bin/create_minidebuginfo",
),
_strip_script = attr.label(
cfg = "exec",
executable = True,
allow_single_file = True,
default = "//build/soong/scripts:strip.sh",
),
_ar = attr.label(
cfg = "exec",
executable = True,
allow_single_file = True,
default = "//prebuilts/clang/host/linux-x86:llvm-ar",
),
_strip = attr.label(
cfg = "exec",
executable = True,
allow_single_file = True,
default = "//prebuilts/clang/host/linux-x86:llvm-strip",
),
_readelf = attr.label(
cfg = "exec",
executable = True,
allow_single_file = True,
default = "//prebuilts/clang/host/linux-x86:llvm-readelf",
),
_objcopy = attr.label(
cfg = "exec",
executable = True,
allow_single_file = True,
default = "//prebuilts/clang/host/linux-x86:llvm-objcopy",
),
_cc_toolchain = attr.label(
default = Label("@local_config_cc//:toolchain"),
providers = [cc_common.CcToolchainInfo],
),
_android_constraint = attr.label(
default = Label("//build/bazel/platforms/os:android"),
),
)
def _stripped_shared_library_impl(ctx):
out_file = stripped_impl(ctx, prefix = "lib", extension = ".so")
return [
DefaultInfo(files = depset([out_file])),
ctx.attr.src[CcSharedLibraryInfo],
ctx.attr.src[OutputGroupInfo],
]
stripped_shared_library = rule(
implementation = _stripped_shared_library_impl,
attrs = dict(
common_strip_attrs,
src = attr.label(
mandatory = True,
# TODO(b/217908237): reenable allow_single_file
# allow_single_file = True,
providers = [CcSharedLibraryInfo],
),
),
toolchains = ["@bazel_tools//tools/cpp:toolchain_type"],
)
# A marker provider to distinguish a cc_binary from everything else that exports
# a CcInfo.
StrippedCcBinaryInfo = provider()
def _stripped_binary_impl(ctx):
common_providers = [
ctx.attr.src[CcInfo],
ctx.attr.src[InstrumentedFilesInfo],
ctx.attr.src[DebugPackageInfo],
ctx.attr.src[OutputGroupInfo],
StrippedCcBinaryInfo(), # a marker for dependents
CcUnstrippedInfo(
unstripped = ctx.attr.unstripped,
),
] + [
d[CcAndroidMkInfo]
for d in ctx.attr.androidmk_deps
]
out_file = stripped_impl(ctx, suffix = ctx.attr.suffix)
return [
DefaultInfo(
files = depset([out_file]),
executable = out_file,
),
] + common_providers
stripped_binary = rule(
implementation = _stripped_binary_impl,
attrs = dict(
common_strip_attrs,
src = attr.label(mandatory = True, allow_single_file = True, providers = [CcInfo]),
runtime_deps = attr.label_list(
providers = [CcInfo],
doc = "Deps that should be installed along with this target. Read by the apex cc aspect.",
),
androidmk_deps = attr.label_list(
providers = [CcAndroidMkInfo],
),
suffix = attr.string(),
unstripped = attr.label(
mandatory = True,
allow_single_file = True,
doc = "Unstripped binary to be returned by ",
),
),
executable = True,
toolchains = ["@bazel_tools//tools/cpp:toolchain_type"],
)