mirror of
https://github.com/klzgrad/naiveproxy.git
synced 2024-11-24 22:36:09 +03:00
2053 lines
66 KiB
Plaintext
2053 lines
66 KiB
Plaintext
|
# Copyright 2015 The Chromium Authors. All rights reserved.
|
||
|
# Use of this source code is governed by a BSD-style license that can be
|
||
|
# found in the LICENSE file.
|
||
|
|
||
|
import("//build/config/ios/ios_sdk.gni")
|
||
|
import("//build/config/mac/base_rules.gni")
|
||
|
import("//build/config/mac/symbols.gni")
|
||
|
import("//build/toolchain/toolchain.gni")
|
||
|
|
||
|
# Constants corresponding to the bundle type identifier for XCTest and XCUITest
|
||
|
# targets.
|
||
|
_ios_xcode_xctest_bundle_id = "com.apple.product-type.bundle.unit-test"
|
||
|
_ios_xcode_xcuitest_bundle_id = "com.apple.product-type.bundle.ui-testing"
|
||
|
|
||
|
# Invokes lipo on multiple arch-specific binaries to create a fat binary.
|
||
|
#
|
||
|
# Arguments
|
||
|
#
|
||
|
# arch_binary_target
|
||
|
# name of the target generating the arch-specific binaries, they must
|
||
|
# be named $target_out_dir/$toolchain_cpu/$arch_binary_output.
|
||
|
#
|
||
|
# arch_binary_output
|
||
|
# (optional, defaults to the name of $arch_binary_target) base name of
|
||
|
# the arch-specific binary generated by arch_binary_target.
|
||
|
#
|
||
|
# output_name
|
||
|
# (optional, defaults to $target_name) base name of the target output,
|
||
|
# the full path will be $target_out_dir/$output_name.
|
||
|
#
|
||
|
# configs
|
||
|
# (optional) a list of configurations, this is used to check whether
|
||
|
# the binary should be stripped, when "enable_stripping" is true.
|
||
|
#
|
||
|
template("lipo_binary") {
|
||
|
assert(defined(invoker.arch_binary_target),
|
||
|
"arch_binary_target must be defined for $target_name")
|
||
|
|
||
|
_target_name = target_name
|
||
|
_output_name = target_name
|
||
|
if (defined(invoker.output_name)) {
|
||
|
_output_name = invoker.output_name
|
||
|
}
|
||
|
|
||
|
_all_target_cpu = [ current_cpu ] + additional_target_cpus
|
||
|
_all_toolchains = [ current_toolchain ] + additional_toolchains
|
||
|
|
||
|
_arch_binary_target = invoker.arch_binary_target
|
||
|
_arch_binary_output = get_label_info(_arch_binary_target, "name")
|
||
|
if (defined(invoker.arch_binary_output)) {
|
||
|
_arch_binary_output = invoker.arch_binary_output
|
||
|
}
|
||
|
|
||
|
action(_target_name) {
|
||
|
forward_variables_from(invoker,
|
||
|
"*",
|
||
|
[
|
||
|
"arch_binary_output",
|
||
|
"arch_binary_target",
|
||
|
"configs",
|
||
|
"output_name",
|
||
|
])
|
||
|
|
||
|
script = "//build/toolchain/mac/linker_driver.py"
|
||
|
|
||
|
# http://crbug.com/762840. Fix for bots running out of memory.
|
||
|
pool = "//build/toolchain:link_pool($default_toolchain)"
|
||
|
|
||
|
outputs = [
|
||
|
"$target_out_dir/$_output_name",
|
||
|
]
|
||
|
|
||
|
deps = []
|
||
|
_index = 0
|
||
|
inputs = []
|
||
|
foreach(_cpu, _all_target_cpu) {
|
||
|
_toolchain = _all_toolchains[_index]
|
||
|
_index = _index + 1
|
||
|
|
||
|
inputs +=
|
||
|
[ get_label_info("$_arch_binary_target($_toolchain)",
|
||
|
"target_out_dir") + "/$_cpu/$_arch_binary_output" ]
|
||
|
|
||
|
deps += [ "$_arch_binary_target($_toolchain)" ]
|
||
|
}
|
||
|
|
||
|
args = []
|
||
|
if (!use_system_xcode) {
|
||
|
args += [
|
||
|
"--developer_dir",
|
||
|
hermetic_xcode_path,
|
||
|
]
|
||
|
}
|
||
|
args += [
|
||
|
"xcrun",
|
||
|
"lipo",
|
||
|
"-create",
|
||
|
"-output",
|
||
|
rebase_path("$target_out_dir/$_output_name", root_build_dir),
|
||
|
] + rebase_path(inputs, root_build_dir)
|
||
|
|
||
|
if (enable_dsyms) {
|
||
|
_dsyms_output_dir = "$root_out_dir/$_output_name.dSYM"
|
||
|
outputs += [
|
||
|
"$_dsyms_output_dir/",
|
||
|
"$_dsyms_output_dir/Contents/Info.plist",
|
||
|
"$_dsyms_output_dir/Contents/Resources/DWARF/$_output_name",
|
||
|
]
|
||
|
args += [ "-Wcrl,dsym," + rebase_path("$root_out_dir/.", root_build_dir) ]
|
||
|
}
|
||
|
|
||
|
if (enable_stripping) {
|
||
|
args += [ "-Wcrl,strip,-x,-S" ]
|
||
|
if (save_unstripped_output) {
|
||
|
outputs += [ "$root_out_dir/$_output_name.unstripped" ]
|
||
|
args += [ "-Wcrl,unstripped," +
|
||
|
rebase_path("$root_out_dir/.", root_build_dir) ]
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
# Wrapper around create_bundle taking care of code signature settings.
|
||
|
#
|
||
|
# Arguments
|
||
|
#
|
||
|
# product_type
|
||
|
# string, product type for the generated Xcode project.
|
||
|
#
|
||
|
# bundle_gen_dir
|
||
|
# (optional) directory where the bundle is generated; must be below
|
||
|
# root_out_dir and defaults to root_out_dir if omitted.
|
||
|
#
|
||
|
# bundle_deps
|
||
|
# (optional) list of additional dependencies.
|
||
|
#
|
||
|
# bundle_deps_filter
|
||
|
# (optional) list of dependencies to filter (for more information
|
||
|
# see "gn help bundle_deps_filter").
|
||
|
#
|
||
|
# bundle_extension
|
||
|
# string, extension of the bundle, used to generate bundle name.
|
||
|
#
|
||
|
# bundle_binary_target
|
||
|
# (optional) string, label of the target generating the bundle main
|
||
|
# binary. This target and bundle_binary_path are mutually exclusive.
|
||
|
#
|
||
|
# bundle_binary_output
|
||
|
# (optional) string, base name of the binary generated by the
|
||
|
# bundle_binary_target target, defaults to the target name.
|
||
|
#
|
||
|
# bundle_binary_path
|
||
|
# (optional) string, path to the bundle main binary. This target and
|
||
|
# bundle_binary_target are mutually exclusive.
|
||
|
#
|
||
|
# output_name:
|
||
|
# (optional) string, name of the generated application, if omitted,
|
||
|
# defaults to the target_name.
|
||
|
#
|
||
|
# extra_system_frameworks
|
||
|
# (optional) list of system framework to copy to the bundle.
|
||
|
#
|
||
|
# enable_code_signing
|
||
|
# (optional) boolean, control whether code signing is enabled or not,
|
||
|
# default to ios_enable_code_signing if not defined.
|
||
|
#
|
||
|
# entitlements_path:
|
||
|
# (optional) path to the template to use to generate the application
|
||
|
# entitlements by performing variable substitutions, defaults to
|
||
|
# //build/config/ios/entitlements.plist.
|
||
|
#
|
||
|
# entitlements_target:
|
||
|
# (optional) label of the target generating the application
|
||
|
# entitlements (must generate a single file as output); cannot be
|
||
|
# defined if entitlements_path is set.
|
||
|
#
|
||
|
# disable_entitlements
|
||
|
# (optional, defaults to false) boolean, control whether entitlements willi
|
||
|
# be embedded in the application during signature. If false and no
|
||
|
# entitlements are provided, default empty entitlements will be used.
|
||
|
#
|
||
|
# disable_embedded_mobileprovision
|
||
|
# (optional, default to false) boolean, control whether mobile provisions
|
||
|
# will be embedded in the bundle. If true, the existing
|
||
|
# embedded.mobileprovision will be deleted.
|
||
|
#
|
||
|
# xcode_extra_attributes
|
||
|
# (optional) scope, extra attributes for Xcode projects.
|
||
|
#
|
||
|
# xcode_test_application_name:
|
||
|
# (optional) string, name of the test application for Xcode unit or ui
|
||
|
# test target.
|
||
|
#
|
||
|
# primary_info_plist:
|
||
|
# (optional) path to Info.plist to merge with the $partial_info_plist
|
||
|
# generated by the compilation of the asset catalog.
|
||
|
#
|
||
|
# partial_info_plist:
|
||
|
# (optional) path to the partial Info.plist generated by the asset
|
||
|
# catalog compiler; if defined $primary_info_plist must also be defined.
|
||
|
#
|
||
|
template("create_signed_bundle") {
|
||
|
assert(defined(invoker.product_type),
|
||
|
"product_type must be defined for $target_name")
|
||
|
assert(defined(invoker.bundle_extension),
|
||
|
"bundle_extension must be defined for $target_name")
|
||
|
assert(defined(invoker.bundle_binary_target) !=
|
||
|
defined(invoker.bundle_binary_path),
|
||
|
"Only one of bundle_binary_target or bundle_binary_path may be " +
|
||
|
"specified for $target_name")
|
||
|
assert(!defined(invoker.partial_info_plist) ||
|
||
|
defined(invoker.primary_info_plist),
|
||
|
"primary_info_plist must be defined when partial_info_plist is " +
|
||
|
"defined for $target_name")
|
||
|
|
||
|
if (defined(invoker.xcode_test_application_name)) {
|
||
|
assert(
|
||
|
invoker.product_type == _ios_xcode_xctest_bundle_id ||
|
||
|
invoker.product_type == _ios_xcode_xcuitest_bundle_id,
|
||
|
"xcode_test_application_name can be only defined for Xcode unit or ui test target.")
|
||
|
}
|
||
|
|
||
|
_target_name = target_name
|
||
|
_output_name = target_name
|
||
|
if (defined(invoker.output_name)) {
|
||
|
_output_name = invoker.output_name
|
||
|
}
|
||
|
|
||
|
if (defined(invoker.bundle_binary_path)) {
|
||
|
_bundle_binary_path = invoker.bundle_binary_path
|
||
|
} else {
|
||
|
_bundle_binary_target = invoker.bundle_binary_target
|
||
|
_bundle_binary_output = get_label_info(_bundle_binary_target, "name")
|
||
|
if (defined(invoker.bundle_binary_output)) {
|
||
|
_bundle_binary_output = invoker.bundle_binary_output
|
||
|
}
|
||
|
_bundle_binary_path =
|
||
|
get_label_info(_bundle_binary_target, "target_out_dir") +
|
||
|
"/$_bundle_binary_output"
|
||
|
}
|
||
|
|
||
|
_bundle_gen_dir = root_out_dir
|
||
|
if (defined(invoker.bundle_gen_dir)) {
|
||
|
_bundle_gen_dir = invoker.bundle_gen_dir
|
||
|
}
|
||
|
|
||
|
_bundle_extension = invoker.bundle_extension
|
||
|
|
||
|
_enable_embedded_mobileprovision = true
|
||
|
if (defined(invoker.disable_embedded_mobileprovision)) {
|
||
|
_enable_embedded_mobileprovision = !invoker.disable_embedded_mobileprovision
|
||
|
}
|
||
|
|
||
|
_enable_entitlements = true
|
||
|
if (defined(invoker.disable_entitlements)) {
|
||
|
_enable_entitlements = !invoker.disable_entitlements
|
||
|
}
|
||
|
|
||
|
if (_enable_entitlements) {
|
||
|
if (!defined(invoker.entitlements_target)) {
|
||
|
_entitlements_path = "//build/config/ios/entitlements.plist"
|
||
|
if (defined(invoker.entitlements_path)) {
|
||
|
_entitlements_path = invoker.entitlements_path
|
||
|
}
|
||
|
} else {
|
||
|
assert(!defined(invoker.entitlements_path),
|
||
|
"Cannot define both entitlements_path and entitlements_target " +
|
||
|
"for $target_name")
|
||
|
|
||
|
_entitlements_target_outputs =
|
||
|
get_target_outputs(invoker.entitlements_target)
|
||
|
_entitlements_path = _entitlements_target_outputs[0]
|
||
|
}
|
||
|
}
|
||
|
|
||
|
_enable_code_signing = ios_enable_code_signing
|
||
|
if (defined(invoker.enable_code_signing)) {
|
||
|
_enable_code_signing = invoker.enable_code_signing
|
||
|
}
|
||
|
|
||
|
create_bundle(_target_name) {
|
||
|
forward_variables_from(invoker,
|
||
|
[
|
||
|
"bundle_deps_filter",
|
||
|
"data_deps",
|
||
|
"deps",
|
||
|
"partial_info_plist",
|
||
|
"product_type",
|
||
|
"public_configs",
|
||
|
"public_deps",
|
||
|
"testonly",
|
||
|
"visibility",
|
||
|
"xcode_test_application_name",
|
||
|
])
|
||
|
|
||
|
bundle_root_dir = "$_bundle_gen_dir/$_output_name$_bundle_extension"
|
||
|
bundle_contents_dir = bundle_root_dir
|
||
|
bundle_resources_dir = bundle_contents_dir
|
||
|
bundle_executable_dir = bundle_contents_dir
|
||
|
bundle_plugins_dir = "$bundle_contents_dir/PlugIns"
|
||
|
|
||
|
if (!defined(public_deps)) {
|
||
|
public_deps = []
|
||
|
}
|
||
|
|
||
|
xcode_extra_attributes = {
|
||
|
IPHONEOS_DEPLOYMENT_TARGET = ios_deployment_target
|
||
|
|
||
|
# If invoker has defined extra attributes, they override the defaults.
|
||
|
if (defined(invoker.xcode_extra_attributes)) {
|
||
|
forward_variables_from(invoker.xcode_extra_attributes, "*")
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (defined(invoker.bundle_binary_target)) {
|
||
|
public_deps += [ invoker.bundle_binary_target ]
|
||
|
}
|
||
|
|
||
|
if (defined(invoker.bundle_deps)) {
|
||
|
if (!defined(deps)) {
|
||
|
deps = []
|
||
|
}
|
||
|
deps += invoker.bundle_deps
|
||
|
}
|
||
|
if (!defined(deps)) {
|
||
|
deps = []
|
||
|
}
|
||
|
|
||
|
code_signing_script = "//build/config/ios/codesign.py"
|
||
|
code_signing_sources = [ _bundle_binary_path ]
|
||
|
if (_enable_entitlements) {
|
||
|
if (defined(invoker.entitlements_target)) {
|
||
|
deps += [ invoker.entitlements_target ]
|
||
|
}
|
||
|
code_signing_sources += [ _entitlements_path ]
|
||
|
}
|
||
|
code_signing_outputs = [ "$bundle_contents_dir/$_output_name" ]
|
||
|
if (_enable_code_signing) {
|
||
|
code_signing_outputs +=
|
||
|
[ "$bundle_contents_dir/_CodeSignature/CodeResources" ]
|
||
|
}
|
||
|
if (ios_code_signing_identity != "" && !use_ios_simulator &&
|
||
|
_enable_embedded_mobileprovision) {
|
||
|
code_signing_outputs +=
|
||
|
[ "$bundle_contents_dir/embedded.mobileprovision" ]
|
||
|
}
|
||
|
|
||
|
if (defined(invoker.extra_system_frameworks)) {
|
||
|
foreach(_framework, invoker.extra_system_frameworks) {
|
||
|
code_signing_outputs += [ "$bundle_contents_dir/Frameworks/" +
|
||
|
get_path_info(_framework, "file") ]
|
||
|
}
|
||
|
}
|
||
|
|
||
|
code_signing_args = []
|
||
|
if (!use_system_xcode) {
|
||
|
code_signing_args += [
|
||
|
"--developer_dir",
|
||
|
hermetic_xcode_path,
|
||
|
]
|
||
|
}
|
||
|
code_signing_args += [
|
||
|
"code-sign-bundle",
|
||
|
"-t=" + ios_sdk_name,
|
||
|
"-i=" + ios_code_signing_identity,
|
||
|
"-b=" + rebase_path(_bundle_binary_path, root_build_dir),
|
||
|
]
|
||
|
if (_enable_entitlements) {
|
||
|
code_signing_args +=
|
||
|
[ "-e=" + rebase_path(_entitlements_path, root_build_dir) ]
|
||
|
}
|
||
|
if (!_enable_embedded_mobileprovision) {
|
||
|
code_signing_args += [ "--disable-embedded-mobileprovision" ]
|
||
|
}
|
||
|
code_signing_args += [ rebase_path(bundle_root_dir, root_build_dir) ]
|
||
|
if (!_enable_code_signing) {
|
||
|
code_signing_args += [ "--disable-code-signature" ]
|
||
|
}
|
||
|
if (defined(invoker.extra_system_frameworks)) {
|
||
|
# All framework in extra_system_frameworks are expected to be
|
||
|
# system framework and the path to be already system absolute
|
||
|
# so do not use rebase_path here.
|
||
|
foreach(_framework, invoker.extra_system_frameworks) {
|
||
|
code_signing_args += [ "-F=" + _framework ]
|
||
|
}
|
||
|
}
|
||
|
if (defined(invoker.partial_info_plist)) {
|
||
|
_partial_info_plists = [
|
||
|
invoker.primary_info_plist,
|
||
|
invoker.partial_info_plist,
|
||
|
]
|
||
|
|
||
|
_plist_compiler_path = "//build/config/mac/plist_util.py"
|
||
|
|
||
|
code_signing_sources += _partial_info_plists
|
||
|
code_signing_sources += [ _plist_compiler_path ]
|
||
|
code_signing_outputs += [ "$bundle_contents_dir/Info.plist" ]
|
||
|
|
||
|
code_signing_args +=
|
||
|
[ "-P=" + rebase_path(_plist_compiler_path, root_build_dir) ]
|
||
|
foreach(_partial_info_plist, _partial_info_plists) {
|
||
|
code_signing_args +=
|
||
|
[ "-p=" + rebase_path(_partial_info_plist, root_build_dir) ]
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
# Generates Info.plist files for Mac apps and frameworks.
|
||
|
#
|
||
|
# Arguments
|
||
|
#
|
||
|
# info_plist:
|
||
|
# (optional) string, path to the Info.plist file that will be used for
|
||
|
# the bundle.
|
||
|
#
|
||
|
# info_plist_target:
|
||
|
# (optional) string, if the info_plist is generated from an action,
|
||
|
# rather than a regular source file, specify the target name in lieu
|
||
|
# of info_plist. The two arguments are mutually exclusive.
|
||
|
#
|
||
|
# executable_name:
|
||
|
# string, name of the generated target used for the product
|
||
|
# and executable name as specified in the output Info.plist.
|
||
|
#
|
||
|
# extra_substitutions:
|
||
|
# (optional) string array, 'key=value' pairs for extra fields which are
|
||
|
# specified in a source Info.plist template.
|
||
|
template("ios_info_plist") {
|
||
|
assert(defined(invoker.info_plist) != defined(invoker.info_plist_target),
|
||
|
"Only one of info_plist or info_plist_target may be specified in " +
|
||
|
target_name)
|
||
|
|
||
|
if (defined(invoker.info_plist)) {
|
||
|
_info_plist = invoker.info_plist
|
||
|
} else {
|
||
|
_info_plist_target_output = get_target_outputs(invoker.info_plist_target)
|
||
|
_info_plist = _info_plist_target_output[0]
|
||
|
}
|
||
|
|
||
|
info_plist(target_name) {
|
||
|
format = "binary1"
|
||
|
extra_substitutions = []
|
||
|
if (defined(invoker.extra_substitutions)) {
|
||
|
extra_substitutions = invoker.extra_substitutions
|
||
|
}
|
||
|
extra_substitutions += [
|
||
|
"IOS_BUNDLE_ID_PREFIX=$ios_app_bundle_id_prefix",
|
||
|
"IOS_PLATFORM_BUILD=$ios_platform_build",
|
||
|
"IOS_PLATFORM_NAME=$ios_sdk_name",
|
||
|
"IOS_PLATFORM_VERSION=$ios_sdk_version",
|
||
|
"IOS_SDK_BUILD=$ios_sdk_build",
|
||
|
"IOS_SDK_NAME=$ios_sdk_name$ios_sdk_version",
|
||
|
"IOS_SUPPORTED_PLATFORM=$ios_sdk_platform",
|
||
|
]
|
||
|
plist_templates = [
|
||
|
"//build/config/ios/BuildInfo.plist",
|
||
|
_info_plist,
|
||
|
]
|
||
|
if (defined(invoker.info_plist_target)) {
|
||
|
deps = [
|
||
|
invoker.info_plist_target,
|
||
|
]
|
||
|
}
|
||
|
forward_variables_from(invoker,
|
||
|
[
|
||
|
"executable_name",
|
||
|
"output_name",
|
||
|
"visibility",
|
||
|
"testonly",
|
||
|
])
|
||
|
}
|
||
|
}
|
||
|
|
||
|
# Template to build an application bundle for iOS.
|
||
|
#
|
||
|
# This should be used instead of "executable" built-in target type on iOS.
|
||
|
# As the template forward the generation of the application executable to
|
||
|
# an "executable" target, all arguments supported by "executable" targets
|
||
|
# are also supported by this template.
|
||
|
#
|
||
|
# Arguments
|
||
|
#
|
||
|
# output_name:
|
||
|
# (optional) string, name of the generated application, if omitted,
|
||
|
# defaults to the target_name.
|
||
|
#
|
||
|
# extra_substitutions:
|
||
|
# (optional) list of string in "key=value" format, each value will
|
||
|
# be used as an additional variable substitution rule when generating
|
||
|
# the application Info.plist
|
||
|
#
|
||
|
# info_plist:
|
||
|
# (optional) string, path to the Info.plist file that will be used for
|
||
|
# the bundle.
|
||
|
#
|
||
|
# info_plist_target:
|
||
|
# (optional) string, if the info_plist is generated from an action,
|
||
|
# rather than a regular source file, specify the target name in lieu
|
||
|
# of info_plist. The two arguments are mutually exclusive.
|
||
|
#
|
||
|
# entitlements_path:
|
||
|
# (optional) path to the template to use to generate the application
|
||
|
# entitlements by performing variable substitutions, defaults to
|
||
|
# //build/config/ios/entitlements.plist.
|
||
|
#
|
||
|
# entitlements_target:
|
||
|
# (optional) label of the target generating the application
|
||
|
# entitlements (must generate a single file as output); cannot be
|
||
|
# defined if entitlements_path is set.
|
||
|
#
|
||
|
# bundle_extension:
|
||
|
# (optional) bundle extension including the dot, default to ".app".
|
||
|
#
|
||
|
# product_type
|
||
|
# (optional) string, product type for the generated Xcode project,
|
||
|
# default to "com.apple.product-type.application". Should generally
|
||
|
# not be overridden.
|
||
|
#
|
||
|
# enable_code_signing
|
||
|
# (optional) boolean, control whether code signing is enabled or not,
|
||
|
# default to ios_enable_code_signing if not defined.
|
||
|
#
|
||
|
# variants
|
||
|
# (optional) list of scopes, each scope needs to define the attributes
|
||
|
# "name" and "bundle_deps"; if defined and non-empty, then one bundle
|
||
|
# named $target_out_dir/$variant/$output_name will be created for each
|
||
|
# variant with the same binary but the correct bundle_deps, the bundle
|
||
|
# at $target_out_dir/$output_name will be a copy of the first variant.
|
||
|
#
|
||
|
# For more information, see "gn help executable".
|
||
|
template("ios_app_bundle") {
|
||
|
_output_name = target_name
|
||
|
_target_name = target_name
|
||
|
if (defined(invoker.output_name)) {
|
||
|
_output_name = invoker.output_name
|
||
|
}
|
||
|
|
||
|
_arch_executable_source = _target_name + "_arch_executable_sources"
|
||
|
_arch_executable_target = _target_name + "_arch_executable"
|
||
|
_lipo_executable_target = _target_name + "_executable"
|
||
|
|
||
|
if (defined(invoker.variants) && invoker.variants != []) {
|
||
|
_variants = []
|
||
|
|
||
|
foreach(_variant, invoker.variants) {
|
||
|
assert(defined(_variant.name) && _variant.name != "",
|
||
|
"name must be defined for all $target_name variants")
|
||
|
|
||
|
assert(defined(_variant.bundle_deps),
|
||
|
"bundle_deps must be defined for all $target_name variants")
|
||
|
|
||
|
_variants += [
|
||
|
{
|
||
|
name = _variant.name
|
||
|
bundle_deps = _variant.bundle_deps
|
||
|
target_name = "${_target_name}_variants_${_variant.name}"
|
||
|
bundle_gen_dir = "$root_out_dir/variants/${_variant.name}"
|
||
|
},
|
||
|
]
|
||
|
}
|
||
|
} else {
|
||
|
# If no variants are passed to the template, use a fake variant with
|
||
|
# no name to avoid duplicating code. As no variant can have an empty
|
||
|
# name except this fake variant, it is possible to know if a variant
|
||
|
# is fake or not.
|
||
|
_variants = [
|
||
|
{
|
||
|
name = ""
|
||
|
bundle_deps = []
|
||
|
target_name = _target_name
|
||
|
bundle_gen_dir = root_out_dir
|
||
|
},
|
||
|
]
|
||
|
}
|
||
|
|
||
|
_default_variant = _variants[0]
|
||
|
|
||
|
if (current_toolchain != default_toolchain) {
|
||
|
# For use of _variants and _default_variant for secondary toolchain to
|
||
|
# avoid the "Assignment had no effect" error from gn.
|
||
|
assert(_variants != [])
|
||
|
assert(_default_variant.target_name != "")
|
||
|
}
|
||
|
|
||
|
source_set(_arch_executable_source) {
|
||
|
forward_variables_from(invoker,
|
||
|
"*",
|
||
|
[
|
||
|
"bundle_deps",
|
||
|
"bundle_deps_filter",
|
||
|
"bundle_extension",
|
||
|
"enable_code_signing",
|
||
|
"entitlements_path",
|
||
|
"entitlements_target",
|
||
|
"extra_substitutions",
|
||
|
"extra_system_frameworks",
|
||
|
"info_plist",
|
||
|
"info_plist_target",
|
||
|
"output_name",
|
||
|
"product_type",
|
||
|
"visibility",
|
||
|
])
|
||
|
|
||
|
visibility = [ ":$_arch_executable_target" ]
|
||
|
}
|
||
|
|
||
|
if (current_toolchain == default_toolchain || use_ios_simulator) {
|
||
|
_generate_entitlements_target = _target_name + "_gen_entitlements"
|
||
|
_generate_entitlements_output =
|
||
|
get_label_info(":$_generate_entitlements_target($default_toolchain)",
|
||
|
"target_out_dir") + "/$_output_name.xcent"
|
||
|
}
|
||
|
|
||
|
executable(_arch_executable_target) {
|
||
|
forward_variables_from(invoker,
|
||
|
"*",
|
||
|
[
|
||
|
"bundle_deps",
|
||
|
"bundle_deps_filter",
|
||
|
"bundle_extension",
|
||
|
"enable_code_signing",
|
||
|
"entitlements_path",
|
||
|
"entitlements_target",
|
||
|
"extra_substitutions",
|
||
|
"extra_system_frameworks",
|
||
|
"info_plist",
|
||
|
"info_plist_target",
|
||
|
"output_name",
|
||
|
"product_type",
|
||
|
"sources",
|
||
|
"visibility",
|
||
|
])
|
||
|
|
||
|
visibility = [ ":$_lipo_executable_target($default_toolchain)" ]
|
||
|
if (current_toolchain != default_toolchain) {
|
||
|
visibility += [ ":$_target_name" ]
|
||
|
}
|
||
|
|
||
|
if (!defined(deps)) {
|
||
|
deps = []
|
||
|
}
|
||
|
deps += [ ":$_arch_executable_source" ]
|
||
|
|
||
|
if (!defined(libs)) {
|
||
|
libs = []
|
||
|
}
|
||
|
libs += [ "UIKit.framework" ]
|
||
|
|
||
|
if (!defined(ldflags)) {
|
||
|
ldflags = []
|
||
|
}
|
||
|
ldflags += [
|
||
|
"-Xlinker",
|
||
|
"-rpath",
|
||
|
"-Xlinker",
|
||
|
"@executable_path/Frameworks",
|
||
|
"-Xlinker",
|
||
|
"-objc_abi_version",
|
||
|
"-Xlinker",
|
||
|
"2",
|
||
|
]
|
||
|
|
||
|
if (use_ios_simulator) {
|
||
|
deps += [ ":$_generate_entitlements_target($default_toolchain)" ]
|
||
|
|
||
|
if (!defined(inputs)) {
|
||
|
inputs = []
|
||
|
}
|
||
|
inputs += [ _generate_entitlements_output ]
|
||
|
|
||
|
if (!defined(ldflags)) {
|
||
|
ldflags = []
|
||
|
}
|
||
|
ldflags += [
|
||
|
"-Xlinker",
|
||
|
"-sectcreate",
|
||
|
"-Xlinker",
|
||
|
"__TEXT",
|
||
|
"-Xlinker",
|
||
|
"__entitlements",
|
||
|
"-Xlinker",
|
||
|
rebase_path(_generate_entitlements_output, root_build_dir),
|
||
|
]
|
||
|
}
|
||
|
|
||
|
output_name = _output_name
|
||
|
output_prefix_override = true
|
||
|
output_dir = "$target_out_dir/$current_cpu"
|
||
|
}
|
||
|
|
||
|
if (current_toolchain != default_toolchain) {
|
||
|
# For fat builds, only the default toolchain will generate an application
|
||
|
# bundle. For the other toolchains, the template is only used for building
|
||
|
# the arch-specific binary, thus the default target is just a group().
|
||
|
|
||
|
group(_target_name) {
|
||
|
forward_variables_from(invoker,
|
||
|
[
|
||
|
"visibility",
|
||
|
"testonly",
|
||
|
])
|
||
|
public_deps = [
|
||
|
":$_arch_executable_target",
|
||
|
]
|
||
|
}
|
||
|
} else {
|
||
|
lipo_binary(_lipo_executable_target) {
|
||
|
forward_variables_from(invoker,
|
||
|
[
|
||
|
"configs",
|
||
|
"testonly",
|
||
|
])
|
||
|
|
||
|
visibility = []
|
||
|
foreach(_variant, _variants) {
|
||
|
visibility += [ ":${_variant.target_name}" ]
|
||
|
}
|
||
|
|
||
|
output_name = _output_name
|
||
|
arch_binary_target = ":$_arch_executable_target"
|
||
|
arch_binary_output = _output_name
|
||
|
}
|
||
|
|
||
|
_generate_info_plist = target_name + "_generate_info_plist"
|
||
|
ios_info_plist(_generate_info_plist) {
|
||
|
forward_variables_from(invoker,
|
||
|
[
|
||
|
"extra_substitutions",
|
||
|
"info_plist",
|
||
|
"info_plist_target",
|
||
|
])
|
||
|
|
||
|
executable_name = _output_name
|
||
|
}
|
||
|
|
||
|
if (current_toolchain == default_toolchain) {
|
||
|
if (!defined(invoker.entitlements_target)) {
|
||
|
_entitlements_path = "//build/config/ios/entitlements.plist"
|
||
|
if (defined(invoker.entitlements_path)) {
|
||
|
_entitlements_path = invoker.entitlements_path
|
||
|
}
|
||
|
} else {
|
||
|
assert(!defined(invoker.entitlements_path),
|
||
|
"Cannot define both entitlements_path and entitlements_target" +
|
||
|
"for $_target_name")
|
||
|
|
||
|
_entitlements_target_outputs =
|
||
|
get_target_outputs(invoker.entitlements_target)
|
||
|
_entitlements_path = _entitlements_target_outputs[0]
|
||
|
}
|
||
|
|
||
|
action(_generate_entitlements_target) {
|
||
|
_gen_info_plist_outputs = get_target_outputs(":$_generate_info_plist")
|
||
|
_info_plist_path = _gen_info_plist_outputs[0]
|
||
|
|
||
|
script = "//build/config/ios/codesign.py"
|
||
|
deps = [
|
||
|
":$_generate_info_plist",
|
||
|
]
|
||
|
if (defined(invoker.entitlements_target)) {
|
||
|
deps += [ invoker.entitlements_target ]
|
||
|
}
|
||
|
sources = [
|
||
|
_entitlements_path,
|
||
|
_info_plist_path,
|
||
|
]
|
||
|
outputs = [
|
||
|
_generate_entitlements_output,
|
||
|
]
|
||
|
|
||
|
args = []
|
||
|
if (!use_system_xcode) {
|
||
|
args += [
|
||
|
"--developer_dir",
|
||
|
hermetic_xcode_path,
|
||
|
]
|
||
|
}
|
||
|
args += [
|
||
|
"generate-entitlements",
|
||
|
"-e=" + rebase_path(_entitlements_path, root_build_dir),
|
||
|
"-p=" + rebase_path(_info_plist_path, root_build_dir),
|
||
|
] + rebase_path(outputs, root_build_dir)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
_app_product_type = "com.apple.product-type.application"
|
||
|
_product_type = _app_product_type
|
||
|
if (defined(invoker.product_type)) {
|
||
|
_product_type = invoker.product_type
|
||
|
}
|
||
|
|
||
|
_app_bundle_extension = ".app"
|
||
|
_bundle_extension = _app_bundle_extension
|
||
|
if (defined(invoker.bundle_extension)) {
|
||
|
_bundle_extension = invoker.bundle_extension
|
||
|
}
|
||
|
|
||
|
# Only write PkgInfo for real application, not application extension (they
|
||
|
# have the same product type but a different extension).
|
||
|
_write_pkg_info = _product_type == _app_product_type &&
|
||
|
_bundle_extension == _app_bundle_extension
|
||
|
|
||
|
if (_write_pkg_info) {
|
||
|
_create_pkg_info = target_name + "_pkg_info"
|
||
|
action(_create_pkg_info) {
|
||
|
forward_variables_from(invoker, [ "testonly" ])
|
||
|
script = "//build/config/mac/write_pkg_info.py"
|
||
|
sources = get_target_outputs(":$_generate_info_plist")
|
||
|
outputs = [
|
||
|
# Cannot name the output PkgInfo as the name will not be unique if
|
||
|
# multiple ios_app_bundle are defined in the same BUILD.gn file. The
|
||
|
# file is renamed in the bundle_data outputs to the correct name.
|
||
|
"$target_gen_dir/$target_name",
|
||
|
]
|
||
|
args = [ "--plist" ] + rebase_path(sources, root_build_dir) +
|
||
|
[ "--output" ] + rebase_path(outputs, root_build_dir)
|
||
|
deps = [
|
||
|
":$_generate_info_plist",
|
||
|
]
|
||
|
}
|
||
|
|
||
|
_bundle_data_pkg_info = target_name + "_bundle_data_pkg_info"
|
||
|
bundle_data(_bundle_data_pkg_info) {
|
||
|
forward_variables_from(invoker, [ "testonly" ])
|
||
|
sources = get_target_outputs(":$_create_pkg_info")
|
||
|
outputs = [
|
||
|
"{{bundle_resources_dir}}/PkgInfo",
|
||
|
]
|
||
|
public_deps = [
|
||
|
":$_create_pkg_info",
|
||
|
]
|
||
|
}
|
||
|
}
|
||
|
|
||
|
foreach(_variant, _variants) {
|
||
|
create_signed_bundle(_variant.target_name) {
|
||
|
forward_variables_from(invoker,
|
||
|
[
|
||
|
"bundle_deps",
|
||
|
"bundle_deps_filter",
|
||
|
"data_deps",
|
||
|
"deps",
|
||
|
"enable_code_signing",
|
||
|
"entitlements_path",
|
||
|
"entitlements_target",
|
||
|
"extra_system_frameworks",
|
||
|
"public_configs",
|
||
|
"public_deps",
|
||
|
"testonly",
|
||
|
"visibility",
|
||
|
])
|
||
|
|
||
|
output_name = _output_name
|
||
|
bundle_gen_dir = _variant.bundle_gen_dir
|
||
|
bundle_binary_target = ":$_lipo_executable_target"
|
||
|
bundle_binary_output = _output_name
|
||
|
bundle_extension = _bundle_extension
|
||
|
product_type = _product_type
|
||
|
|
||
|
_generate_info_plist_outputs =
|
||
|
get_target_outputs(":$_generate_info_plist")
|
||
|
primary_info_plist = _generate_info_plist_outputs[0]
|
||
|
partial_info_plist =
|
||
|
"$target_gen_dir/${_variant.target_name}_partial_info.plist"
|
||
|
|
||
|
if (!defined(deps)) {
|
||
|
deps = []
|
||
|
}
|
||
|
deps += [ ":$_generate_info_plist" ]
|
||
|
|
||
|
if (!defined(bundle_deps)) {
|
||
|
bundle_deps = []
|
||
|
}
|
||
|
if (_write_pkg_info) {
|
||
|
bundle_deps += [ ":$_bundle_data_pkg_info" ]
|
||
|
}
|
||
|
bundle_deps += _variant.bundle_deps
|
||
|
|
||
|
if (use_ios_simulator) {
|
||
|
if (!defined(data_deps)) {
|
||
|
data_deps = []
|
||
|
}
|
||
|
data_deps += [ "//testing/iossim" ]
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (_default_variant.name != "") {
|
||
|
_bundle_short_name = "$_output_name$_bundle_extension"
|
||
|
action(_target_name) {
|
||
|
forward_variables_from(invoker, [ "testonly" ])
|
||
|
|
||
|
script = "//build/config/ios/hardlink.py"
|
||
|
public_deps = []
|
||
|
foreach(_variant, _variants) {
|
||
|
public_deps += [ ":${_variant.target_name}" ]
|
||
|
}
|
||
|
|
||
|
sources = [
|
||
|
"${_default_variant.bundle_gen_dir}/$_bundle_short_name",
|
||
|
]
|
||
|
outputs = [
|
||
|
"$root_out_dir/$_bundle_short_name",
|
||
|
]
|
||
|
|
||
|
args = rebase_path(sources, root_out_dir) +
|
||
|
rebase_path(outputs, root_out_dir)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
set_defaults("ios_app_bundle") {
|
||
|
configs = default_executable_configs
|
||
|
}
|
||
|
|
||
|
# Template to build an application extension bundle for iOS.
|
||
|
#
|
||
|
# This should be used instead of "executable" built-in target type on iOS.
|
||
|
# As the template forward the generation of the application executable to
|
||
|
# an "executable" target, all arguments supported by "executable" targets
|
||
|
# are also supported by this template.
|
||
|
#
|
||
|
# Arguments
|
||
|
#
|
||
|
# output_name:
|
||
|
# (optional) string, name of the generated application, if omitted,
|
||
|
# defaults to the target_name.
|
||
|
#
|
||
|
# extra_substitutions:
|
||
|
# (optional) list of string in "key=value" format, each value will
|
||
|
# be used as an additional variable substitution rule when generating
|
||
|
# the application Info.plist
|
||
|
#
|
||
|
# info_plist:
|
||
|
# (optional) string, path to the Info.plist file that will be used for
|
||
|
# the bundle.
|
||
|
#
|
||
|
# info_plist_target:
|
||
|
# (optional) string, if the info_plist is generated from an action,
|
||
|
# rather than a regular source file, specify the target name in lieu
|
||
|
# of info_plist. The two arguments are mutually exclusive.
|
||
|
#
|
||
|
# For more information, see "gn help executable".
|
||
|
template("ios_appex_bundle") {
|
||
|
ios_app_bundle(target_name) {
|
||
|
forward_variables_from(invoker,
|
||
|
"*",
|
||
|
[
|
||
|
"bundle_extension",
|
||
|
"product_type",
|
||
|
])
|
||
|
bundle_extension = ".appex"
|
||
|
product_type = "com.apple.product-type.app-extension"
|
||
|
|
||
|
# Add linker flags required for an application extension (determined by
|
||
|
# inspecting the link command-line when using Xcode 9.0+).
|
||
|
if (!defined(ldflags)) {
|
||
|
ldflags = []
|
||
|
}
|
||
|
ldflags += [
|
||
|
"-e",
|
||
|
"_NSExtensionMain",
|
||
|
"-fapplication-extension",
|
||
|
]
|
||
|
}
|
||
|
}
|
||
|
|
||
|
set_defaults("ios_appex_bundle") {
|
||
|
configs = default_executable_configs
|
||
|
}
|
||
|
|
||
|
# Compile a xib or storyboard file and add it to a bundle_data so that it is
|
||
|
# available at runtime in the bundle.
|
||
|
#
|
||
|
# Arguments
|
||
|
#
|
||
|
# source:
|
||
|
# string, path of the xib or storyboard to compile.
|
||
|
#
|
||
|
# Forwards all variables to the bundle_data target.
|
||
|
template("bundle_data_ib_file") {
|
||
|
assert(defined(invoker.source), "source needs to be defined for $target_name")
|
||
|
|
||
|
_source_extension = get_path_info(invoker.source, "extension")
|
||
|
assert(_source_extension == "xib" || _source_extension == "storyboard",
|
||
|
"source must be a .xib or .storyboard for $target_name")
|
||
|
|
||
|
_target_name = target_name
|
||
|
if (_source_extension == "xib") {
|
||
|
_compile_ib_file = target_name + "_compile_xib"
|
||
|
_output_extension = "nib"
|
||
|
} else {
|
||
|
_compile_ib_file = target_name + "_compile_storyboard"
|
||
|
_output_extension = "storyboardc"
|
||
|
}
|
||
|
|
||
|
compile_ib_files(_compile_ib_file) {
|
||
|
sources = [
|
||
|
invoker.source,
|
||
|
]
|
||
|
output_extension = _output_extension
|
||
|
visibility = [ ":$_target_name" ]
|
||
|
ibtool_flags = [
|
||
|
"--minimum-deployment-target",
|
||
|
ios_deployment_target,
|
||
|
"--auto-activate-custom-fonts",
|
||
|
"--target-device",
|
||
|
"iphone",
|
||
|
"--target-device",
|
||
|
"ipad",
|
||
|
]
|
||
|
}
|
||
|
|
||
|
bundle_data(_target_name) {
|
||
|
forward_variables_from(invoker, "*", [ "source" ])
|
||
|
|
||
|
if (!defined(public_deps)) {
|
||
|
public_deps = []
|
||
|
}
|
||
|
public_deps += [ ":$_compile_ib_file" ]
|
||
|
|
||
|
sources = get_target_outputs(":$_compile_ib_file")
|
||
|
|
||
|
outputs = [
|
||
|
"{{bundle_resources_dir}}/{{source_file_part}}",
|
||
|
]
|
||
|
}
|
||
|
}
|
||
|
|
||
|
# Compile a strings file and add it to a bundle_data so that it is available
|
||
|
# at runtime in the bundle.
|
||
|
#
|
||
|
# Arguments
|
||
|
#
|
||
|
# source:
|
||
|
# string, path of the strings file to compile.
|
||
|
#
|
||
|
# output:
|
||
|
# string, path of the compiled file in the final bundle.
|
||
|
#
|
||
|
# Forwards all variables to the bundle_data target.
|
||
|
template("bundle_data_strings") {
|
||
|
assert(defined(invoker.source), "source needs to be defined for $target_name")
|
||
|
assert(defined(invoker.output), "output needs to be defined for $target_name")
|
||
|
|
||
|
_source_extension = get_path_info(invoker.source, "extension")
|
||
|
assert(_source_extension == "strings",
|
||
|
"source must be a .strings for $target_name")
|
||
|
|
||
|
_target_name = target_name
|
||
|
_convert_target = target_name + "_compile_strings"
|
||
|
|
||
|
convert_plist(_convert_target) {
|
||
|
visibility = [ ":$_target_name" ]
|
||
|
source = invoker.source
|
||
|
output =
|
||
|
"$target_gen_dir/$_target_name/" + get_path_info(invoker.source, "file")
|
||
|
format = "binary1"
|
||
|
}
|
||
|
|
||
|
bundle_data(_target_name) {
|
||
|
forward_variables_from(invoker,
|
||
|
"*",
|
||
|
[
|
||
|
"source",
|
||
|
"output",
|
||
|
])
|
||
|
|
||
|
if (!defined(public_deps)) {
|
||
|
public_deps = []
|
||
|
}
|
||
|
public_deps += [ ":$_convert_target" ]
|
||
|
|
||
|
sources = get_target_outputs(":$_convert_target")
|
||
|
|
||
|
outputs = [
|
||
|
invoker.output,
|
||
|
]
|
||
|
}
|
||
|
}
|
||
|
|
||
|
# Template to package a shared library into an iOS framework bundle.
|
||
|
#
|
||
|
# By default, the bundle target this template generates does not link the
|
||
|
# resulting framework into anything that depends on it. If a dependency wants
|
||
|
# a link-time (as well as build-time) dependency on the framework bundle,
|
||
|
# depend against "$target_name+link". If only the build-time dependency is
|
||
|
# required (e.g., for copying into another bundle), then use "$target_name".
|
||
|
#
|
||
|
# Arguments
|
||
|
#
|
||
|
# output_name:
|
||
|
# (optional) string, name of the generated framework without the
|
||
|
# .framework suffix. If omitted, defaults to target_name.
|
||
|
#
|
||
|
# public_headers:
|
||
|
# (optional) list of paths to header file that needs to be copied
|
||
|
# into the framework bundle Headers subdirectory. If omitted or
|
||
|
# empty then the Headers subdirectory is not created.
|
||
|
#
|
||
|
# sources
|
||
|
# (optional) list of files. Needs to be defined and non-empty if
|
||
|
# public_headers is defined and non-empty.
|
||
|
#
|
||
|
# enable_code_signing
|
||
|
# (optional) boolean, control whether code signing is enabled or not,
|
||
|
# default to ios_enable_code_signing if not defined.
|
||
|
#
|
||
|
# This template provides two targets for the resulting framework bundle. The
|
||
|
# link-time behavior varies depending on which of the two targets below is
|
||
|
# added as a dependency:
|
||
|
# - $target_name only adds a build-time dependency. Targets that depend on
|
||
|
# it will not link against the framework.
|
||
|
# - $target_name+link adds a build-time and link-time dependency. Targets
|
||
|
# that depend on it will link against the framework.
|
||
|
#
|
||
|
# The build-time-only dependency is used for when a target needs to use the
|
||
|
# framework either only for resources, or because the target loads it at run-
|
||
|
# time, via dlopen() or NSBundle. The link-time dependency will cause the
|
||
|
# dependee to have the framework loaded by dyld at launch.
|
||
|
#
|
||
|
# Example of build-time only dependency:
|
||
|
#
|
||
|
# framework_bundle("CoreTeleportation") {
|
||
|
# sources = [ ... ]
|
||
|
# }
|
||
|
#
|
||
|
# bundle_data("core_teleportation_bundle_data") {
|
||
|
# deps = [ ":CoreTeleportation" ]
|
||
|
# sources = [ "$root_out_dir/CoreTeleportation.framework" ]
|
||
|
# outputs = [ "{{bundle_contents_dir}}/Frameworks/{{source_file_part}}" ]
|
||
|
# }
|
||
|
#
|
||
|
# app_bundle("GoatTeleporter") {
|
||
|
# sources = [ ... ]
|
||
|
# deps = [
|
||
|
# ":core_teleportation_bundle_data",
|
||
|
# ]
|
||
|
# }
|
||
|
#
|
||
|
# The GoatTeleporter.app will not directly link against
|
||
|
# CoreTeleportation.framework, but it will be included in the bundle's
|
||
|
# Frameworks directory.
|
||
|
#
|
||
|
# Example of link-time dependency:
|
||
|
#
|
||
|
# framework_bundle("CoreTeleportation") {
|
||
|
# sources = [ ... ]
|
||
|
# ldflags = [
|
||
|
# "-install_name",
|
||
|
# "@executable_path/../Frameworks/$target_name.framework"
|
||
|
# ]
|
||
|
# }
|
||
|
#
|
||
|
# bundle_data("core_teleportation_bundle_data") {
|
||
|
# deps = [ ":CoreTeleportation+link" ]
|
||
|
# sources = [ "$root_out_dir/CoreTeleportation.framework" ]
|
||
|
# outputs = [ "{{bundle_contents_dir}}/Frameworks/{{source_file_part}}" ]
|
||
|
# }
|
||
|
#
|
||
|
# app_bundle("GoatTeleporter") {
|
||
|
# sources = [ ... ]
|
||
|
# deps = [
|
||
|
# ":core_teleportation_bundle_data",
|
||
|
# ]
|
||
|
# }
|
||
|
#
|
||
|
# Note that the framework is still copied to the app's bundle, but dyld will
|
||
|
# load this library when the app is launched because it uses the "+link"
|
||
|
# target as a dependency. This also requires that the framework set its
|
||
|
# install_name so that dyld can locate it.
|
||
|
#
|
||
|
# See "gn help shared_library" for more information on arguments supported
|
||
|
# by shared library target.
|
||
|
template("ios_framework_bundle") {
|
||
|
_target_name = target_name
|
||
|
_output_name = target_name
|
||
|
if (defined(invoker.output_name)) {
|
||
|
_output_name = invoker.output_name
|
||
|
}
|
||
|
|
||
|
_has_public_headers =
|
||
|
defined(invoker.public_headers) && invoker.public_headers != []
|
||
|
|
||
|
# Public configs are not propagated across toolchain (see crbug.com/675224)
|
||
|
# so some configs have to be defined for both default_toolchain and all others
|
||
|
# toolchains when performing a fat build. Use "get_label_info" to construct
|
||
|
# the path since they need to be relative to the default_toolchain.
|
||
|
|
||
|
_default_toolchain_root_out_dir =
|
||
|
get_label_info("$_target_name($default_toolchain)", "root_out_dir")
|
||
|
_default_toolchain_target_gen_dir =
|
||
|
get_label_info("$_target_name($default_toolchain)", "target_gen_dir")
|
||
|
|
||
|
if (_has_public_headers) {
|
||
|
_framework_headers_target = _target_name + "_framework_headers"
|
||
|
_framework_headers_config = _target_name + "_framework_headers_config"
|
||
|
config(_framework_headers_config) {
|
||
|
# The link settings are inherited from the framework_bundle config.
|
||
|
cflags = [
|
||
|
"-F",
|
||
|
rebase_path("$_default_toolchain_root_out_dir/.", root_build_dir),
|
||
|
]
|
||
|
}
|
||
|
|
||
|
_headers_map_config = _target_name + "_headers_map"
|
||
|
_header_map_filename =
|
||
|
"$_default_toolchain_target_gen_dir/$_output_name.headers.hmap"
|
||
|
config(_headers_map_config) {
|
||
|
visibility = [ ":$_target_name" ]
|
||
|
include_dirs = [ _header_map_filename ]
|
||
|
}
|
||
|
}
|
||
|
|
||
|
_arch_shared_library_source = _target_name + "_arch_shared_library_sources"
|
||
|
_arch_shared_library_target = _target_name + "_arch_shared_library"
|
||
|
_lipo_shared_library_target = _target_name + "_shared_library"
|
||
|
_link_target_name = _target_name + "+link"
|
||
|
|
||
|
_framework_public_config = _target_name + "_public_config"
|
||
|
config(_framework_public_config) {
|
||
|
# TODO(sdefresne): should we have a framework_dirs similar to lib_dirs
|
||
|
# and include_dirs to avoid duplicate values on the command-line.
|
||
|
visibility = [ ":$_target_name" ]
|
||
|
ldflags = [
|
||
|
"-F",
|
||
|
rebase_path("$_default_toolchain_root_out_dir/.", root_build_dir),
|
||
|
]
|
||
|
lib_dirs = [ root_out_dir ]
|
||
|
libs = [ "$_output_name.framework" ]
|
||
|
}
|
||
|
|
||
|
source_set(_arch_shared_library_source) {
|
||
|
forward_variables_from(invoker,
|
||
|
"*",
|
||
|
[
|
||
|
"bundle_deps",
|
||
|
"bundle_deps_filter",
|
||
|
"data_deps",
|
||
|
"enable_code_signing",
|
||
|
"extra_substitutions",
|
||
|
"info_plist",
|
||
|
"info_plist_target",
|
||
|
"output_name",
|
||
|
"visibility",
|
||
|
])
|
||
|
|
||
|
visibility = [ ":$_arch_shared_library_target" ]
|
||
|
|
||
|
if (_has_public_headers) {
|
||
|
configs += [
|
||
|
":$_framework_headers_config",
|
||
|
":$_headers_map_config",
|
||
|
]
|
||
|
|
||
|
if (!defined(deps)) {
|
||
|
deps = []
|
||
|
}
|
||
|
deps += [ ":$_framework_headers_target($default_toolchain)" ]
|
||
|
}
|
||
|
}
|
||
|
|
||
|
shared_library(_arch_shared_library_target) {
|
||
|
forward_variables_from(invoker,
|
||
|
"*",
|
||
|
[
|
||
|
"bundle_deps",
|
||
|
"bundle_deps_filter",
|
||
|
"data_deps",
|
||
|
"enable_code_signing",
|
||
|
"extra_substitutions",
|
||
|
"info_plist",
|
||
|
"info_plist_target",
|
||
|
"output_name",
|
||
|
"sources",
|
||
|
"visibility",
|
||
|
])
|
||
|
|
||
|
visibility = [ ":$_lipo_shared_library_target($default_toolchain)" ]
|
||
|
if (current_toolchain != default_toolchain) {
|
||
|
visibility += [ ":$_target_name" ]
|
||
|
}
|
||
|
|
||
|
if (!defined(deps)) {
|
||
|
deps = []
|
||
|
}
|
||
|
deps += [ ":$_arch_shared_library_source" ]
|
||
|
if (_has_public_headers) {
|
||
|
deps += [ ":$_framework_headers_target($default_toolchain)" ]
|
||
|
}
|
||
|
if (!defined(ldflags)) {
|
||
|
ldflags = []
|
||
|
}
|
||
|
ldflags += [
|
||
|
"-Xlinker",
|
||
|
"-install_name",
|
||
|
"-Xlinker",
|
||
|
"@rpath/$_output_name.framework/$_output_name",
|
||
|
"-Xlinker",
|
||
|
"-objc_abi_version",
|
||
|
"-Xlinker",
|
||
|
"2",
|
||
|
]
|
||
|
|
||
|
output_extension = ""
|
||
|
output_name = _output_name
|
||
|
output_prefix_override = true
|
||
|
output_dir = "$target_out_dir/$current_cpu"
|
||
|
}
|
||
|
|
||
|
if (current_toolchain != default_toolchain) {
|
||
|
# For fat builds, only the default toolchain will generate a framework
|
||
|
# bundle. For the other toolchains, the template is only used for building
|
||
|
# the arch-specific binary, thus the default target is just a group().
|
||
|
|
||
|
group(_target_name) {
|
||
|
forward_variables_from(invoker,
|
||
|
[
|
||
|
"visibility",
|
||
|
"testonly",
|
||
|
])
|
||
|
public_deps = [
|
||
|
":$_arch_shared_library_target",
|
||
|
]
|
||
|
}
|
||
|
|
||
|
group(_link_target_name) {
|
||
|
forward_variables_from(invoker,
|
||
|
[
|
||
|
"public_configs",
|
||
|
"visibility",
|
||
|
"testonly",
|
||
|
])
|
||
|
public_deps = [
|
||
|
":$_link_target_name($default_toolchain)",
|
||
|
]
|
||
|
|
||
|
if (_has_public_headers) {
|
||
|
if (!defined(public_configs)) {
|
||
|
public_configs = []
|
||
|
}
|
||
|
public_configs += [ ":$_framework_headers_config" ]
|
||
|
}
|
||
|
if (!defined(all_dependent_configs)) {
|
||
|
all_dependent_configs = []
|
||
|
}
|
||
|
all_dependent_configs += [ ":$_framework_public_config" ]
|
||
|
}
|
||
|
|
||
|
if (defined(invoker.bundle_deps)) {
|
||
|
assert(invoker.bundle_deps != [], "mark bundle_deps as used")
|
||
|
}
|
||
|
} else {
|
||
|
if (_has_public_headers) {
|
||
|
_public_headers = invoker.public_headers
|
||
|
_framework_root = "$root_out_dir/$_output_name.framework"
|
||
|
|
||
|
_compile_headers_map_target = _target_name + "_compile_headers_map"
|
||
|
action(_compile_headers_map_target) {
|
||
|
visibility = [ ":$_framework_headers_target" ]
|
||
|
forward_variables_from(invoker,
|
||
|
[
|
||
|
"deps",
|
||
|
"public_deps",
|
||
|
"testonly",
|
||
|
])
|
||
|
script = "//build/config/ios/write_framework_hmap.py"
|
||
|
outputs = [
|
||
|
_header_map_filename,
|
||
|
]
|
||
|
|
||
|
# The header map generation only wants the list of headers, not all of
|
||
|
# sources, so filter any non-header source files from "sources". It is
|
||
|
# less error prone that having the developer duplicate the list of all
|
||
|
# headers in addition to "sources".
|
||
|
set_sources_assignment_filter([
|
||
|
"*.c",
|
||
|
"*.cc",
|
||
|
"*.cpp",
|
||
|
"*.m",
|
||
|
"*.mm",
|
||
|
])
|
||
|
sources = invoker.sources
|
||
|
set_sources_assignment_filter([])
|
||
|
|
||
|
args = [
|
||
|
rebase_path(_header_map_filename),
|
||
|
rebase_path(_framework_root, root_build_dir),
|
||
|
] + rebase_path(sources, root_build_dir)
|
||
|
}
|
||
|
|
||
|
_create_module_map_target = _target_name + "_module_map"
|
||
|
action(_create_module_map_target) {
|
||
|
visibility = [ ":$_framework_headers_target" ]
|
||
|
script = "//build/config/ios/write_framework_modulemap.py"
|
||
|
outputs = [
|
||
|
"$_framework_root/Modules/module.modulemap",
|
||
|
]
|
||
|
args = [ rebase_path("$_framework_root", root_build_dir) ]
|
||
|
}
|
||
|
|
||
|
_copy_public_headers_target = _target_name + "_copy_public_headers"
|
||
|
copy(_copy_public_headers_target) {
|
||
|
forward_variables_from(invoker,
|
||
|
[
|
||
|
"testonly",
|
||
|
"deps",
|
||
|
])
|
||
|
visibility = [ ":$_framework_headers_target" ]
|
||
|
sources = _public_headers
|
||
|
outputs = [
|
||
|
"$_framework_root/Headers/{{source_file_part}}",
|
||
|
]
|
||
|
|
||
|
# Do not use forward_variables_from for "public_deps" as
|
||
|
# we do not want to forward those dependencies.
|
||
|
if (defined(invoker.public_deps)) {
|
||
|
if (!defined(deps)) {
|
||
|
deps = []
|
||
|
}
|
||
|
deps += invoker.public_deps
|
||
|
}
|
||
|
}
|
||
|
|
||
|
group(_framework_headers_target) {
|
||
|
forward_variables_from(invoker, [ "testonly" ])
|
||
|
deps = [
|
||
|
":$_compile_headers_map_target",
|
||
|
":$_create_module_map_target",
|
||
|
]
|
||
|
public_deps = [
|
||
|
":$_copy_public_headers_target",
|
||
|
]
|
||
|
}
|
||
|
}
|
||
|
|
||
|
lipo_binary(_lipo_shared_library_target) {
|
||
|
forward_variables_from(invoker,
|
||
|
[
|
||
|
"configs",
|
||
|
"testonly",
|
||
|
])
|
||
|
|
||
|
visibility = [ ":$_target_name" ]
|
||
|
output_name = _output_name
|
||
|
arch_binary_target = ":$_arch_shared_library_target"
|
||
|
arch_binary_output = _output_name
|
||
|
}
|
||
|
|
||
|
_info_plist_target = _target_name + "_info_plist"
|
||
|
_info_plist_bundle = _target_name + "_info_plist_bundle"
|
||
|
ios_info_plist(_info_plist_target) {
|
||
|
visibility = [ ":$_info_plist_bundle" ]
|
||
|
executable_name = _output_name
|
||
|
forward_variables_from(invoker,
|
||
|
[
|
||
|
"extra_substitutions",
|
||
|
"info_plist",
|
||
|
"info_plist_target",
|
||
|
])
|
||
|
}
|
||
|
|
||
|
bundle_data(_info_plist_bundle) {
|
||
|
visibility = [ ":$_target_name" ]
|
||
|
forward_variables_from(invoker, [ "testonly" ])
|
||
|
sources = get_target_outputs(":$_info_plist_target")
|
||
|
outputs = [
|
||
|
"{{bundle_contents_dir}}/Info.plist",
|
||
|
]
|
||
|
public_deps = [
|
||
|
":$_info_plist_target",
|
||
|
]
|
||
|
}
|
||
|
|
||
|
create_signed_bundle(_target_name) {
|
||
|
forward_variables_from(invoker,
|
||
|
[
|
||
|
"bundle_deps",
|
||
|
"bundle_deps_filter",
|
||
|
"data_deps",
|
||
|
"deps",
|
||
|
"enable_code_signing",
|
||
|
"public_configs",
|
||
|
"public_deps",
|
||
|
"testonly",
|
||
|
"visibility",
|
||
|
])
|
||
|
|
||
|
product_type = "com.apple.product-type.framework"
|
||
|
bundle_extension = ".framework"
|
||
|
|
||
|
output_name = _output_name
|
||
|
bundle_binary_target = ":$_lipo_shared_library_target"
|
||
|
bundle_binary_output = _output_name
|
||
|
|
||
|
# Framework do not have entitlements nor mobileprovision because they use
|
||
|
# the one from the bundle using them (.app or .appex) as they are just
|
||
|
# dynamic library with shared code.
|
||
|
disable_entitlements = true
|
||
|
disable_embedded_mobileprovision = true
|
||
|
|
||
|
if (!defined(deps)) {
|
||
|
deps = []
|
||
|
}
|
||
|
deps += [ ":$_info_plist_bundle" ]
|
||
|
}
|
||
|
|
||
|
group(_link_target_name) {
|
||
|
forward_variables_from(invoker,
|
||
|
[
|
||
|
"public_configs",
|
||
|
"public_deps",
|
||
|
"testonly",
|
||
|
"visibility",
|
||
|
])
|
||
|
if (!defined(public_deps)) {
|
||
|
public_deps = []
|
||
|
}
|
||
|
public_deps += [ ":$_target_name" ]
|
||
|
|
||
|
if (_has_public_headers) {
|
||
|
if (!defined(public_configs)) {
|
||
|
public_configs = []
|
||
|
}
|
||
|
public_configs += [ ":$_framework_headers_config" ]
|
||
|
}
|
||
|
if (!defined(all_dependent_configs)) {
|
||
|
all_dependent_configs = []
|
||
|
}
|
||
|
all_dependent_configs += [ ":$_framework_public_config" ]
|
||
|
}
|
||
|
|
||
|
bundle_data(_target_name + "+bundle") {
|
||
|
forward_variables_from(invoker,
|
||
|
[
|
||
|
"testonly",
|
||
|
"visibility",
|
||
|
])
|
||
|
public_deps = [
|
||
|
":$_target_name",
|
||
|
]
|
||
|
sources = [
|
||
|
"$root_out_dir/$_output_name.framework",
|
||
|
]
|
||
|
outputs = [
|
||
|
"{{bundle_resources_dir}}/Frameworks/$_output_name.framework",
|
||
|
]
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
set_defaults("ios_framework_bundle") {
|
||
|
configs = default_shared_library_configs
|
||
|
}
|
||
|
|
||
|
# Template to build a xctest bundle that contains a loadable module for iOS.
|
||
|
#
|
||
|
# Arguments
|
||
|
#
|
||
|
# deps:
|
||
|
# list of labels to depends on, these values are used to create the
|
||
|
# loadable module.
|
||
|
#
|
||
|
# product_type
|
||
|
# string, product type for the generated Xcode project, use
|
||
|
# "com.apple.product-type.bundle.unit-test" for unit test and
|
||
|
# "com.apple.product-type.bundle.ui-testing" for UI testing.
|
||
|
#
|
||
|
# host_target:
|
||
|
# string, name of the target that depends on the generated bundle, this
|
||
|
# value is used to restrict visibilities.
|
||
|
#
|
||
|
# xcode_test_application_name:
|
||
|
# string, name of the test application for Xcode unit or ui test target.
|
||
|
#
|
||
|
# output_name
|
||
|
# (optional) string, name of the generated application, if omitted,
|
||
|
# defaults to the target_name.
|
||
|
#
|
||
|
# This template defines two targets, one named "${target_name}" is the xctest
|
||
|
# bundle, and the other named "${target_name}_bundle" is a bundle_data that
|
||
|
# wraps the xctest bundle and that only the "${host_target}" can depend on.
|
||
|
#
|
||
|
template("ios_xctest_bundle") {
|
||
|
assert(defined(invoker.deps), "deps must be defined for $target_name")
|
||
|
assert(defined(invoker.product_type),
|
||
|
"product_type must be defined for $target_name")
|
||
|
assert(invoker.product_type == _ios_xcode_xctest_bundle_id ||
|
||
|
invoker.product_type == _ios_xcode_xcuitest_bundle_id,
|
||
|
"product_type defined for $target_name is invalid.")
|
||
|
assert(defined(invoker.host_target),
|
||
|
"host_target must be defined for $target_name")
|
||
|
assert(defined(invoker.xcode_test_application_name),
|
||
|
"xcode_test_application_name must be defined for $target_name")
|
||
|
|
||
|
# Silence "assignment had no effect" error for non-default toolchains as
|
||
|
# following variables are only used in the expansion of the template for the
|
||
|
# default toolchain.
|
||
|
assert(invoker.configs != [])
|
||
|
assert(invoker.host_target != target_name)
|
||
|
assert(invoker.xcode_test_application_name != target_name)
|
||
|
|
||
|
_target_name = target_name
|
||
|
_output_name = target_name
|
||
|
|
||
|
if (defined(invoker.output_name)) {
|
||
|
_output_name = invoker.output_name
|
||
|
}
|
||
|
|
||
|
_arch_loadable_module_source = _target_name + "_arch_loadable_module_source"
|
||
|
_arch_loadable_module_target = _target_name + "_arch_loadable_module"
|
||
|
_lipo_loadable_module_target = _target_name + "_loadable_module"
|
||
|
|
||
|
source_set(_arch_loadable_module_source) {
|
||
|
forward_variables_from(invoker, [ "deps" ])
|
||
|
|
||
|
testonly = true
|
||
|
visibility = [ ":$_arch_loadable_module_target" ]
|
||
|
}
|
||
|
|
||
|
loadable_module(_arch_loadable_module_target) {
|
||
|
testonly = true
|
||
|
visibility = [ ":$_lipo_loadable_module_target($default_toolchain)" ]
|
||
|
if (current_toolchain != default_toolchain) {
|
||
|
visibility += [ ":$_target_name" ]
|
||
|
}
|
||
|
|
||
|
deps = [
|
||
|
":$_arch_loadable_module_source",
|
||
|
]
|
||
|
configs += [ "//build/config/ios:xctest_config" ]
|
||
|
|
||
|
output_dir = "$target_out_dir/$current_cpu"
|
||
|
output_name = _output_name
|
||
|
output_prefix_override = true
|
||
|
output_extension = ""
|
||
|
}
|
||
|
|
||
|
if (current_toolchain != default_toolchain) {
|
||
|
# For fat builds, only the default toolchain will generate a test bundle.
|
||
|
# For the other toolchains, the template is only used for building the
|
||
|
# arch-specific binary, thus the default target is just a group().
|
||
|
group(_target_name) {
|
||
|
forward_variables_from(invoker, [ "visibility" ])
|
||
|
testonly = true
|
||
|
|
||
|
public_deps = [
|
||
|
":$_arch_loadable_module_target",
|
||
|
]
|
||
|
}
|
||
|
} else {
|
||
|
_info_plist_target = _target_name + "_info_plist"
|
||
|
_info_plist_bundle = _target_name + "_info_plist_bundle"
|
||
|
|
||
|
ios_info_plist(_info_plist_target) {
|
||
|
testonly = true
|
||
|
visibility = [ ":$_info_plist_bundle" ]
|
||
|
|
||
|
info_plist = "//build/config/ios/Module-Info.plist"
|
||
|
executable_name = _output_name
|
||
|
|
||
|
if (ios_automatically_manage_certs) {
|
||
|
# Use a fixed bundle identifier for EarlGrey tests when using Xcode to
|
||
|
# manage the certificates as the number of free certs is limited.
|
||
|
extra_substitutions = [
|
||
|
"MODULE_BUNDLE_ID=gtest.${ios_generic_test_bundle_id_suffix}-module",
|
||
|
]
|
||
|
} else {
|
||
|
extra_substitutions = [ "MODULE_BUNDLE_ID=gtest.$_output_name" ]
|
||
|
}
|
||
|
}
|
||
|
|
||
|
bundle_data(_info_plist_bundle) {
|
||
|
testonly = true
|
||
|
visibility = [ ":$_target_name" ]
|
||
|
|
||
|
public_deps = [
|
||
|
":$_info_plist_target",
|
||
|
]
|
||
|
|
||
|
sources = get_target_outputs(":$_info_plist_target")
|
||
|
outputs = [
|
||
|
"{{bundle_contents_dir}}/Info.plist",
|
||
|
]
|
||
|
}
|
||
|
|
||
|
lipo_binary(_lipo_loadable_module_target) {
|
||
|
forward_variables_from(invoker, [ "configs" ])
|
||
|
|
||
|
testonly = true
|
||
|
visibility = [ ":$_target_name" ]
|
||
|
|
||
|
output_name = _output_name
|
||
|
arch_binary_target = ":$_arch_loadable_module_target"
|
||
|
arch_binary_output = _output_name
|
||
|
}
|
||
|
|
||
|
_xctest_bundle = _target_name + "_bundle"
|
||
|
create_signed_bundle(_target_name) {
|
||
|
forward_variables_from(invoker,
|
||
|
[
|
||
|
"enable_code_signing",
|
||
|
"product_type",
|
||
|
"xcode_test_application_name",
|
||
|
])
|
||
|
|
||
|
testonly = true
|
||
|
visibility = [ ":$_xctest_bundle" ]
|
||
|
|
||
|
bundle_extension = ".xctest"
|
||
|
|
||
|
output_name = _output_name
|
||
|
bundle_binary_target = ":$_lipo_loadable_module_target"
|
||
|
bundle_binary_output = _output_name
|
||
|
|
||
|
# Test files need to be known to Xcode for proper indexing and discovery
|
||
|
# of tests function for XCTest, but the compilation is done via ninja and
|
||
|
# thus must prevent Xcode from linking object files via this hack.
|
||
|
xcode_extra_attributes = {
|
||
|
OTHER_LDFLAGS = "-help"
|
||
|
ONLY_ACTIVE_ARCH = "YES"
|
||
|
DEBUG_INFORMATION_FORMAT = "dwarf"
|
||
|
|
||
|
# For XCUITest, Xcode requires specifying the host application name via
|
||
|
# the TEST_TARGET_NAME attribute.
|
||
|
if (invoker.product_type == _ios_xcode_xcuitest_bundle_id) {
|
||
|
TEST_TARGET_NAME = invoker.xcode_test_application_name
|
||
|
}
|
||
|
|
||
|
# For XCTest, Xcode requires specifying the host application path via
|
||
|
# both BUNDLE_LOADER and TEST_HOST attributes.
|
||
|
if (invoker.product_type == _ios_xcode_xctest_bundle_id) {
|
||
|
BUNDLE_LOADER = "\$(TEST_HOST)"
|
||
|
TEST_HOST =
|
||
|
"\$(BUILT_PRODUCTS_DIR)/${invoker.xcode_test_application_name}" +
|
||
|
".app/${invoker.xcode_test_application_name}"
|
||
|
}
|
||
|
}
|
||
|
|
||
|
deps = [
|
||
|
":$_info_plist_bundle",
|
||
|
]
|
||
|
}
|
||
|
|
||
|
bundle_data(_xctest_bundle) {
|
||
|
forward_variables_from(invoker, [ "host_target" ])
|
||
|
|
||
|
testonly = true
|
||
|
visibility = [ ":$host_target" ]
|
||
|
|
||
|
public_deps = [
|
||
|
":$_target_name",
|
||
|
]
|
||
|
sources = [
|
||
|
"$root_out_dir/$_output_name.xctest",
|
||
|
]
|
||
|
outputs = [
|
||
|
"{{bundle_plugins_dir}}/$_output_name.xctest",
|
||
|
]
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
set_defaults("ios_xctest_bundle") {
|
||
|
configs = default_shared_library_configs
|
||
|
}
|
||
|
|
||
|
# For Chrome on iOS we want to run XCTests for all our build configurations
|
||
|
# (Debug, Release, ...). In addition, the symbols visibility is configured to
|
||
|
# private by default. To simplify testing with those constraints, our tests are
|
||
|
# compiled in the TEST_HOST target instead of the .xctest bundle.
|
||
|
template("ios_xctest_test") {
|
||
|
_target_name = target_name
|
||
|
_output_name = target_name
|
||
|
if (defined(invoker.output_name)) {
|
||
|
_output_name = invoker.output_name
|
||
|
}
|
||
|
|
||
|
_xctest_target = _target_name + "_module"
|
||
|
_xctest_output = _output_name + "_module"
|
||
|
|
||
|
_host_target = _target_name
|
||
|
_host_output = _output_name
|
||
|
|
||
|
_xctest_shell_source_target = _xctest_target + "shell_source"
|
||
|
source_set(_xctest_shell_source_target) {
|
||
|
sources = [
|
||
|
"//build/config/ios/xctest_shell.mm",
|
||
|
]
|
||
|
|
||
|
configs += [ "//build/config/ios:xctest_config" ]
|
||
|
}
|
||
|
|
||
|
ios_xctest_bundle(_xctest_target) {
|
||
|
output_name = _xctest_output
|
||
|
product_type = _ios_xcode_xctest_bundle_id
|
||
|
host_target = _host_target
|
||
|
xcode_test_application_name = _host_output
|
||
|
|
||
|
deps = [
|
||
|
":$_xctest_shell_source_target",
|
||
|
]
|
||
|
}
|
||
|
|
||
|
ios_app_bundle(_host_target) {
|
||
|
forward_variables_from(invoker, "*", [ "testonly" ])
|
||
|
|
||
|
testonly = true
|
||
|
output_name = _host_output
|
||
|
configs += [ "//build/config/ios:xctest_config" ]
|
||
|
|
||
|
if (!defined(invoker.info_plist) && !defined(invoker.info_plist_target)) {
|
||
|
info_plist = "//build/config/ios/Host-Info.plist"
|
||
|
if (ios_automatically_manage_certs) {
|
||
|
# Use the same bundle identifier for EarlGrey tests as for unit tests
|
||
|
# when managing certificates as the number of free certs is limited.
|
||
|
if (!defined(extra_substitutions)) {
|
||
|
extra_substitutions = []
|
||
|
}
|
||
|
extra_substitutions +=
|
||
|
[ "EXECUTABLE_NAME=gtest.${ios_generic_test_bundle_id_suffix}" ]
|
||
|
}
|
||
|
}
|
||
|
|
||
|
# Xcode needs those two framework installed in the application (and signed)
|
||
|
# for the XCTest to run, so install them using extra_system_frameworks.
|
||
|
_ios_platform_library = "$ios_sdk_platform_path/Developer/Library"
|
||
|
extra_system_frameworks =
|
||
|
[ "$_ios_platform_library/Frameworks/XCTest.framework" ]
|
||
|
|
||
|
# TODO: Remove this once support for Xcode 9.x is dropped.
|
||
|
if (xcode_version_int >= 1000) {
|
||
|
extra_system_frameworks += [
|
||
|
"$ios_sdk_platform_path/Developer/usr/lib/libXCTestBundleInject.dylib",
|
||
|
]
|
||
|
} else {
|
||
|
extra_system_frameworks += [
|
||
|
"$_ios_platform_library/PrivateFrameworks/IDEBundleInjection.framework",
|
||
|
]
|
||
|
}
|
||
|
|
||
|
_xctest_bundle = _xctest_target + "_bundle"
|
||
|
if (current_toolchain == default_toolchain) {
|
||
|
if (!defined(bundle_deps)) {
|
||
|
bundle_deps = []
|
||
|
}
|
||
|
bundle_deps += [ ":$_xctest_bundle" ]
|
||
|
}
|
||
|
|
||
|
if (!defined(ldflags)) {
|
||
|
ldflags = []
|
||
|
}
|
||
|
ldflags += [
|
||
|
"-Xlinker",
|
||
|
"-rpath",
|
||
|
"-Xlinker",
|
||
|
"@executable_path/Frameworks",
|
||
|
"-Xlinker",
|
||
|
"-rpath",
|
||
|
"-Xlinker",
|
||
|
"@loader_path/Frameworks",
|
||
|
]
|
||
|
}
|
||
|
}
|
||
|
|
||
|
set_defaults("ios_xctest_test") {
|
||
|
configs = default_executable_configs
|
||
|
}
|
||
|
|
||
|
# Template to build a xcuitest test runner bundle.
|
||
|
#
|
||
|
# Xcode requires a test runner application with a copy of the XCTest dynamic
|
||
|
# library bundle in it for the XCUITest to run. The test runner bundle is created
|
||
|
# by copying the system bundle XCTRunner.app from Xcode SDK with the plist file
|
||
|
# being properly tweaked, and a xctest and it needs to be code signed in order
|
||
|
# to run on devices.
|
||
|
#
|
||
|
# Arguments
|
||
|
#
|
||
|
# xctest_bundle
|
||
|
# string, name of the dependent xctest bundle target.
|
||
|
#
|
||
|
# output_name
|
||
|
# (optional) string, name of the generated application, if omitted,
|
||
|
# defaults to the target_name.
|
||
|
#
|
||
|
template("ios_xcuitest_test_runner_bundle") {
|
||
|
assert(defined(invoker.xctest_bundle),
|
||
|
"xctest_bundle must be defined for $target_name")
|
||
|
|
||
|
_target_name = target_name
|
||
|
_output_name = target_name
|
||
|
if (defined(invoker.output_name)) {
|
||
|
_output_name = invoker.output_name
|
||
|
}
|
||
|
|
||
|
_xctrunner_path =
|
||
|
"$ios_sdk_platform_path/Developer/Library/Xcode/Agents/XCTRunner.app"
|
||
|
|
||
|
_info_plist_merge_plist = _target_name + "_info_plist_merge_plist"
|
||
|
_info_plist_target = _target_name + "_info_plist"
|
||
|
_info_plist_bundle = _target_name + "_info_plist_bundle"
|
||
|
|
||
|
action(_info_plist_merge_plist) {
|
||
|
testonly = true
|
||
|
script = "//build/config/mac/plist_util.py"
|
||
|
|
||
|
sources = [
|
||
|
"$_xctrunner_path/Info.plist",
|
||
|
|
||
|
# NOTE: The XCTRunnerAddition+Info.plist must come after the Info.plist
|
||
|
# because it overrides the values under "CFBundleIdentifier" and
|
||
|
# "CFBundleName".
|
||
|
"//ios/chrome/app/resources/XCTRunnerAddition+Info.plist",
|
||
|
]
|
||
|
|
||
|
_output_name = "$target_gen_dir/${_target_name}_merged.plist"
|
||
|
outputs = [
|
||
|
_output_name,
|
||
|
]
|
||
|
args = [
|
||
|
"merge",
|
||
|
"-f=xml1",
|
||
|
"-o=" + rebase_path(_output_name, root_build_dir),
|
||
|
] + rebase_path(sources, root_build_dir)
|
||
|
}
|
||
|
|
||
|
ios_info_plist(_info_plist_target) {
|
||
|
testonly = true
|
||
|
visibility = [ ":$_info_plist_bundle" ]
|
||
|
|
||
|
executable_name = _output_name
|
||
|
info_plist_target = ":$_info_plist_merge_plist"
|
||
|
|
||
|
if (ios_automatically_manage_certs) {
|
||
|
# Use the same bundle identifier for XCUITest tests as for unit tests
|
||
|
# when managing certificates as the number of free certs is limited.
|
||
|
extra_substitutions =
|
||
|
[ "EXECUTABLE_NAME=gtest.${ios_generic_test_bundle_id_suffix}" ]
|
||
|
}
|
||
|
}
|
||
|
|
||
|
bundle_data(_info_plist_bundle) {
|
||
|
testonly = true
|
||
|
visibility = [ ":$_target_name" ]
|
||
|
|
||
|
public_deps = [
|
||
|
":$_info_plist_target",
|
||
|
]
|
||
|
|
||
|
sources = get_target_outputs(":$_info_plist_target")
|
||
|
outputs = [
|
||
|
"{{bundle_contents_dir}}/Info.plist",
|
||
|
]
|
||
|
}
|
||
|
|
||
|
_pkginfo_bundle = _target_name + "_pkginfo_bundle"
|
||
|
bundle_data(_pkginfo_bundle) {
|
||
|
testonly = true
|
||
|
visibility = [ ":$_target_name" ]
|
||
|
|
||
|
sources = [
|
||
|
"$_xctrunner_path/PkgInfo",
|
||
|
]
|
||
|
|
||
|
outputs = [
|
||
|
"{{bundle_contents_dir}}/PkgInfo",
|
||
|
]
|
||
|
}
|
||
|
|
||
|
_xctest_bundle = invoker.xctest_bundle
|
||
|
create_signed_bundle(_target_name) {
|
||
|
testonly = true
|
||
|
|
||
|
bundle_binary_path = "$_xctrunner_path/XCTRunner"
|
||
|
bundle_extension = ".app"
|
||
|
product_type = "com.apple.product-type.application"
|
||
|
|
||
|
output_name = _output_name
|
||
|
|
||
|
# Xcode needs the following frameworks installed in the application
|
||
|
# (and signed) for the XCUITest to run, so install them using
|
||
|
# extra_system_frameworks.
|
||
|
extra_system_frameworks = [
|
||
|
"$ios_sdk_platform_path/Developer/Library/Frameworks/XCTest.framework",
|
||
|
"$ios_sdk_platform_path/Developer/Library/PrivateFrameworks/XCTAutomationSupport.framework",
|
||
|
]
|
||
|
|
||
|
bundle_deps = [
|
||
|
":$_info_plist_bundle",
|
||
|
":$_pkginfo_bundle",
|
||
|
":$_xctest_bundle",
|
||
|
]
|
||
|
}
|
||
|
}
|
||
|
|
||
|
# Template to build a XCUITest that consists of two parts: the test runner
|
||
|
# application bundle and the xctest dynamic library.
|
||
|
#
|
||
|
# Arguments
|
||
|
#
|
||
|
# deps:
|
||
|
# list of labels to depends on, these values are used to create the
|
||
|
# xctest dynamic library.
|
||
|
#
|
||
|
# xcode_test_application_name:
|
||
|
# string, name of the test application for the ui test target.
|
||
|
#
|
||
|
# This template defines two targets, one named "${target_name}_module" is the
|
||
|
# xctest dynamic library, and the other named "${target_name}_runner" is the
|
||
|
# test runner application bundle.
|
||
|
#
|
||
|
template("ios_xcuitest_test") {
|
||
|
assert(defined(invoker.deps), "deps must be defined for $target_name")
|
||
|
assert(defined(invoker.xcode_test_application_name),
|
||
|
"xcode_test_application_name must be defined for $target_name")
|
||
|
|
||
|
_xcuitest_target = target_name
|
||
|
_xcuitest_runner_target = _xcuitest_target + "_runner"
|
||
|
_xcuitest_module_target = _xcuitest_target + "_module"
|
||
|
|
||
|
group(_xcuitest_target) {
|
||
|
testonly = true
|
||
|
|
||
|
deps = [
|
||
|
":$_xcuitest_runner_target",
|
||
|
]
|
||
|
}
|
||
|
|
||
|
_xcuitest_module_output = _xcuitest_target
|
||
|
ios_xctest_bundle(_xcuitest_module_target) {
|
||
|
forward_variables_from(invoker, [ "xcode_test_application_name" ])
|
||
|
|
||
|
product_type = _ios_xcode_xcuitest_bundle_id
|
||
|
host_target = _xcuitest_runner_target
|
||
|
output_name = _xcuitest_module_output
|
||
|
|
||
|
deps = invoker.deps
|
||
|
}
|
||
|
|
||
|
_xcuitest_runner_output = _xcuitest_target + "-Runner"
|
||
|
ios_xcuitest_test_runner_bundle(_xcuitest_runner_target) {
|
||
|
output_name = _xcuitest_runner_output
|
||
|
xctest_bundle = _xcuitest_module_target + "_bundle"
|
||
|
}
|
||
|
}
|
||
|
|
||
|
set_defaults("ios_xcuitest_test") {
|
||
|
configs = default_executable_configs
|
||
|
}
|