910e62b5创建于 1月15日历史提交
# 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/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")

# 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
  _use_webview_orderfile =
      defined(invoker.use_webview_orderfile) && invoker.use_webview_orderfile
  _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",
                                 "extra_configs",
                               ])

    if (!defined(deps)) {
      deps = []
    }

    if (!_is_webview) {
      deps += [ "//chrome:chrome_android_core" ]
    }

    if (enable_javaless_renderers) {
      deps += [ "//content/app:javaless_renderer" ]
    }

    if (!(defined(testonly) && testonly)) {
      configs -= [ "//build/config/compiler:thinlto_optimize_default" ]
      configs += [ "//build/config/compiler:thinlto_optimize_max" ]
    }

    if (_use_webview_orderfile) {
      configs += [ "//android_webview:webview_orderfile_config" ]
    } else {
      configs += [ "//build/config/compiler:chrome_orderfile_config" ]
    }

    # TODO(crbug.com/40031409): Fix code that adds exit-time destructors and
    # enable the diagnostic by removing this line.
    configs += [ "//build/config/compiler:no_exit_time_destructors" ]

    # 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 {
      foreach(_module_desc, _module_descs) {
        if (defined(_module_desc.native_deps)) {
          deps += _module_desc.native_deps
        }
      }
    }

    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 (defined(invoker.extra_configs)) {
      configs += invoker.extra_configs
    }
  }

  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"

    unwind_table_v2("${target_name}_unwind_table_v2") {
      library_target = _library_target
    }
  }
}