# Copyright 2018 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import("//base/android/linker/config.gni")
import("//build/config/android/config.gni")
import("//build/config/android/create_unwind_table.gni")
import("//build/config/android/extract_unwind_tables.gni")
import("//build/config/android/linker_version_script.gni")
import("//build/config/chrome_build.gni")
import("//build/config/compiler/compiler.gni")
import("//build/partitioned_shared_library.gni")
import("//chrome/android/modules/buildflags.gni")
import("//device/vr/buildflags/buildflags.gni")
import("//third_party/jni_zero/jni_zero.gni")
declare_args() {
# Compile libmonochrome.so with RELR relocations, which are smaller and more
# efficient, but supported only on API 28+.
# This is not permanently enabled for Trichrome because it shares its native
# library with Monochrome.
# Restricted to official builds to avoid turning off is_high_end_android
# explicitly on all relevant non-official bots. TODO(crbug.com/41488915):
# Always use RELR when Android O (and O_MR1) is no longer supported.
use_relr_relocations = is_high_end_android && is_official_build
}
# This template contains all common configuration for native shared libraries,
# including libchrome, monochrome, standalone webview (also called monochrome),
# and libchromefortest (used by chrome_public_test_apk).
#
# Variables:
# is_monochrome: Optional. If set, the library is for use in monochrome.
# is_webview: If true, the library is for webview, and browser-specific
# config is skipped.
# module_descs: Optional. Descriptors of feature modules for which library
# targets should be auto-generated. The targets are called
# "${target_name}_<module name>" and can be depended on like shared_library
# targets. If enabled, the library targets create partitions containing the
# module's native code. Otherwise, they simply depend on the module's
# native_deps. See //chrome/android/modules/chrome_feature_modules.gni for
# the descriptor format.
template("chrome_common_shared_library") {
forward_variables_from(invoker, TESTONLY_AND_VISIBILITY)
_is_monochrome = defined(invoker.is_monochrome) && invoker.is_monochrome
_is_webview = defined(invoker.is_webview) && invoker.is_webview
_collect_inputs_only =
defined(invoker.collect_inputs_only) && invoker.collect_inputs_only
# Create a partitioned libraries if the build config supports it, and the
# invoker has supplied module descriptors.
_generate_partitions = defined(invoker.module_descs) &&
use_native_partitions && !_collect_inputs_only
_module_descs = []
if (defined(invoker.module_descs)) {
_module_descs = invoker.module_descs
}
if (!_collect_inputs_only) {
_linker_script_target = "${target_name}_linker_script"
_linker_script = "$target_gen_dir/${target_name}_linker_script.txt"
# Create a custom linker script based on JNI and feature module requirements.
generate_linker_version_script(_linker_script_target) {
linker_script = _linker_script
export_feature_registrations = true
if (_generate_partitions) {
export_symbol_allowlist_files = []
foreach(_module_desc, invoker.module_descs) {
if (defined(_module_desc.native_entrypoints)) {
export_symbol_allowlist_files += [ _module_desc.native_entrypoints ]
}
}
}
}
}
if (_generate_partitions) {
_target_type = "partitioned_shared_library_with_jni"
} else {
_target_type = "shared_library_with_jni"
}
target(_target_type, target_name) {
forward_variables_from(
invoker,
"*",
TESTONLY_AND_VISIBILITY + [ "define_unwind_table_target" ])
if (!defined(deps)) {
deps = []
}
if (!_is_webview) {
deps += [ "//chrome:chrome_android_core" ]
}
# Warn if linking code which could implicitly disable BTI on Arm systems
configs += [ "//build/config/android:lld_branch_target_hardening" ]
if (!(defined(testonly) && testonly)) {
configs -= [ "//build/config/compiler:thinlto_optimize_default" ]
configs += [ "//build/config/compiler:thinlto_optimize_max" ]
}
configs += [ "//build/config/compiler:chrome_orderfile_config" ]
# Use a dynamically-generated linker script.
configs -= [ "//build/config/android:hide_all_but_jni_onload" ]
if (!defined(ldflags)) {
ldflags = []
}
if (_collect_inputs_only) {
metadata = {
}
ldflags += [ "--collect-inputs-only" ]
} else {
deps += [ ":$_linker_script_target" ]
inputs = [ "$_linker_script" ]
ldflags += [ "-Wl,--version-script=" +
rebase_path(_linker_script, root_build_dir) ]
}
if (_generate_partitions) {
partitions = []
foreach(_module_desc, _module_descs) {
if (defined(_module_desc.native_deps)) {
partitions += [ _module_desc.name ]
deps += _module_desc.native_deps
}
}
} else if (_collect_inputs_only) {
foreach(_module_desc, _module_descs) {
if (defined(_module_desc.native_deps)) {
deps += _module_desc.native_deps
}
}
}
# Compress relocations if needed.
if (use_relr_relocations) {
configs += [ "//build/config/android:lld_relr_relocations" ]
} else if ((_is_monochrome || _is_webview || chromium_linker_supported) &&
use_lld) {
configs += [ "//build/config/android:lld_pack_relocations" ]
}
if ((_is_monochrome || _is_webview || chromium_linker_supported) &&
target_cpu != "mipsel" && target_cpu != "mips64el") {
# By default, the static linker will create ELF executables with both
# SysV and GNU hash tables. Now that the chromium linker supports the GNU
# format, which is considerably smaller, ensure that the SysV one is
# never compiled in the final library (http://crbug.com/742525#c28). GNU
# hash support was added in Android M. Also not supported on MIPS
# architecture (http://crbug.com/811306).
ldflags += [ "-Wl,--hash-style=gnu" ]
}
# See crbug.com/705088.
if (target_cpu == "arm" && is_asan) {
ldflags += [ "-Wl,--long-plt" ]
}
}
if (!_generate_partitions && !_collect_inputs_only) {
# Make helper targets so that we always have module native targets no matter
# whether partitions are enabled.
foreach(_module_desc, _module_descs) {
if (defined(_module_desc.native_deps)) {
group("${target_name}_${_module_desc.name}") {
deps = _module_desc.native_deps
}
}
}
}
if (defined(invoker.define_unwind_table_target) &&
invoker.define_unwind_table_target) {
_library_target = ":$target_name"
# TODO(crbug.com/40833600): Remove generation of v1 unwind asset when
# `CFIBacktraceAndroid` is replaced with `ChromeUnwinderAndroid`.
unwind_table_v1("${target_name}_unwind_table_v1") {
library_target = _library_target
}
if (use_android_unwinder_v2) {
unwind_table_v2("${target_name}_unwind_table_v2") {
library_target = _library_target
}
}
}
}