Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  rules.gni   Sprache: unbekannt

 
# 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("//chromium/build/apple/apple_info_plist.gni")
import("//chromium/build/config/apple/symbols.gni")
import("//chromium/build/config/ios/ios_sdk.gni")
import("//chromium/build/toolchain/goma.gni")
import("//chromium/build/toolchain/toolchain.gni")
import("//build_overrides/build.gni")

declare_args() {
  # Set to true if an Xcode project is generated for this build. Set this to
  # false if you do not plan to run `gn gen --ide=xcode` in this directory.
  # This will speed up the generation at the cost of generating an invalid
  # Xcode project if `gn gen --ide=xcode` is used. Defaults to true (favor
  # correctness over speed).
  ios_set_attributes_for_xcode_project_generation = true
}

# Constants corresponding to the bundle type identifiers use application,
# application extension, XCTest and XCUITest targets respectively.
_ios_xcode_app_bundle_id = "com.apple.product-type.application"
_ios_xcode_appex_bundle_id = "com.apple.product-type.app-extension"
_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")

  assert(!is_fat_secondary_toolchain,
         "lipo_binary can only be used in the primary toolchain of a fat build")

  _target_name = target_name
  _output_name = target_name
  if (defined(invoker.output_name)) {
    _output_name = invoker.output_name
  }

  _all_target_cpu = [ target_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 = "//chromium/build/toolchain/apple/linker_driver.py"

    # http://crbug.com/762840. Fix for bots running out of memory.
    pool = "//chromium/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 = [
             "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 (!use_xcode_clang) {
        args += [ "-Wcrl,dsymutilpath," +
                  rebase_path("//tools/clang/dsymutil/bin/dsymutil",
                              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.
#
#   has_public_headers:
#       (optional) boolean, defaults to false; only meaningful if the bundle
#       is a framework bundle; if true, then the frameworks includes public
#       headers
#
#   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.
#
#   xcode_product_bundle_id:
#       (optional) string, the bundle ID that will be added in the XCode
#       attributes to enable some features when debugging (e.g. MetricKit).
#
#   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
  }

  if (target_environment == "catalyst") {
    _enable_embedded_mobileprovision = false
  }

  _enable_entitlements = true
  if (defined(invoker.disable_entitlements)) {
    _enable_entitlements = !invoker.disable_entitlements
  }

  if (_enable_entitlements) {
    if (!defined(invoker.entitlements_target)) {
      _entitlements_path = "//chromium/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
  }

  if (!ios_set_attributes_for_xcode_project_generation) {
    not_needed(invoker,
               [
                 "xcode_product_bundle_id",
                 "xcode_extra_attributes",
               ])
  }

  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"
    if (target_environment == "simulator" || target_environment == "device") {
      bundle_contents_dir = bundle_root_dir
      bundle_resources_dir = bundle_contents_dir
      bundle_executable_dir = bundle_contents_dir
    } else if (target_environment == "catalyst") {
      if (_bundle_extension != ".framework") {
        bundle_contents_dir = "$bundle_root_dir/Contents"
        bundle_resources_dir = "$bundle_contents_dir/Resources"
        bundle_executable_dir = "$bundle_contents_dir/MacOS"
      } else {
        bundle_contents_dir = "$bundle_root_dir/Versions/A"
        bundle_resources_dir = "$bundle_contents_dir/Resources"
        bundle_executable_dir = bundle_contents_dir
      }
    }

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

    if (ios_set_attributes_for_xcode_project_generation) {
      _xcode_product_bundle_id = ""
      if (defined(invoker.xcode_product_bundle_id)) {
        _xcode_product_bundle_id = invoker.xcode_product_bundle_id
      }

      if (_xcode_product_bundle_id != "") {
        _ios_provisioning_profile_info =
            exec_script("//chromium/build/config/ios/codesign.py",
                        [
                          "find-provisioning-profile",
                          "-b=" + _xcode_product_bundle_id,
                        ],
                        "json")
      }

      xcode_extra_attributes = {
        IPHONEOS_DEPLOYMENT_TARGET = ios_deployment_target
        if (_xcode_product_bundle_id != "") {
          CODE_SIGN_IDENTITY = "iPhone Developer"
          DEVELOPMENT_TEAM = _ios_provisioning_profile_info.team_identifier
          PRODUCT_BUNDLE_IDENTIFIER = _xcode_product_bundle_id
          PROVISIONING_PROFILE_SPECIFIER = _ios_provisioning_profile_info.name
        }

        # 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 = "//chromium/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_executable_dir/$_output_name" ]
    if (_enable_code_signing) {
      code_signing_outputs +=
          [ "$bundle_contents_dir/_CodeSignature/CodeResources" ]
    }
    if (ios_code_signing_identity != "" && target_environment == "device" &&
        _enable_embedded_mobileprovision) {
      code_signing_outputs +=
          [ "$bundle_contents_dir/embedded.mobileprovision" ]
    }
    if (_bundle_extension == ".framework") {
      if (target_environment == "catalyst") {
        code_signing_outputs += [
          "$bundle_root_dir/Versions/Current",
          "$bundle_root_dir/$_output_name",
        ]

        if (defined(invoker.has_public_headers) && invoker.has_public_headers) {
          code_signing_outputs += [
            "$bundle_root_dir/Headers",
            "$bundle_root_dir/Modules",
          ]
        }
      } else {
        not_needed(invoker, [ "has_public_headers" ])
      }
    }

    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 = [
      "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 unless using Goma RBE and system Xcode (as in that
      # case the system framework are found via a symlink in root_build_dir).
      foreach(_framework, invoker.extra_system_frameworks) {
        if (use_system_xcode && use_goma) {
          _framework_path = rebase_path(_framework, root_build_dir)
        } else {
          _framework_path = _framework
        }
        code_signing_args += [ "-F=$_framework_path" ]
      }
    }
    if (defined(invoker.partial_info_plist)) {
      _partial_info_plists = [
        invoker.primary_info_plist,
        invoker.partial_info_plist,
      ]

      _plist_compiler_path = "//chromium/build/apple/plist_util.py"

      code_signing_sources += _partial_info_plists
      code_signing_sources += [ _plist_compiler_path ]
      if (target_environment != "catalyst" ||
          _bundle_extension != ".framework") {
        code_signing_outputs += [ "$bundle_contents_dir/Info.plist" ]
      } else {
        code_signing_outputs += [ "$bundle_resources_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]
  }

  apple_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",
      "BUILD_MACHINE_OS_BUILD=$machine_os_build",
      "IOS_DEPLOYMENT_TARGET=$ios_deployment_target",
      "XCODE_BUILD=$xcode_build",
      "XCODE_VERSION=$xcode_version",
    ]
    plist_templates = [
      "//chromium/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.
#
#   product_type
#       (optional) string, product type for the generated Xcode project,
#       default to "com.apple.product-type.application". Should only be
#       overriden when building application extension.
#
#   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.
#
#   xcode_product_bundle_id:
#       (optional) string, the bundle ID that will be added in the XCode
#       attributes to enable some features when debugging (e.g. MetricKit).
#       defaults to "$ios_app_bundle_id_prefix.$output_name".
#
# 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
  }

  _primary_toolchain = current_toolchain
  if (is_fat_secondary_toolchain) {
    _primary_toolchain = primary_fat_toolchain_name
  }

  assert(
      !defined(invoker.bundle_extension),
      "bundle_extension must not be set for ios_app_bundle template for $target_name")

  _xcode_product_bundle_id = "$ios_app_bundle_id_prefix.$_output_name"
  if (defined(invoker.xcode_product_bundle_id)) {
    _xcode_product_bundle_id = invoker.xcode_product_bundle_id
    _xcode_product_bundle_id =
        "$ios_app_bundle_id_prefix.$_xcode_product_bundle_id"
  } else if (defined(invoker.bundle_id)) {
    _xcode_product_bundle_id = invoker.bundle_id
  }

  # Bundle ID should respect rfc1034 and replace _ with -.
  _xcode_product_bundle_id =
      string_replace("$_xcode_product_bundle_id", "_", "-")

  _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]

  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",
                             "xcode_extra_attributes",
                           ])

    visibility = [ ":$_arch_executable_target" ]
  }

  if (!is_fat_secondary_toolchain || target_environment == "simulator") {
    _generate_entitlements_target = _target_name + "_gen_entitlements"
    _generate_entitlements_output =
        get_label_info(":$_generate_entitlements_target($_primary_toolchain)",
                       "target_out_dir") + "/$_output_name.xcent"
  }

  _product_type = _ios_xcode_app_bundle_id
  if (defined(invoker.product_type)) {
    _product_type = invoker.product_type
  }

  if (_product_type == _ios_xcode_app_bundle_id) {
    _bundle_extension = ".app"
  } else if (_product_type == _ios_xcode_appex_bundle_id) {
    _bundle_extension = ".appex"
  } else {
    assert(false, "unknown product_type \"$product_type\" for $_target_name")
  }

  _is_app_bundle = _product_type == _ios_xcode_app_bundle_id

  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",
                             "xcode_extra_attributes",
                           ])

    visibility = [ ":$_lipo_executable_target($_primary_toolchain)" ]
    if (is_fat_secondary_toolchain) {
      visibility += [ ":$_target_name" ]
    }

    if (!defined(deps)) {
      deps = []
    }
    deps += [ ":$_arch_executable_source" ]

    if (!defined(frameworks)) {
      frameworks = []
    }
    frameworks += [ "UIKit.framework" ]

    if (target_environment == "simulator") {
      deps += [ ":$_generate_entitlements_target($_primary_toolchain)" ]

      if (!defined(inputs)) {
        inputs = []
      }
      inputs += [ _generate_entitlements_output ]

      if (!defined(ldflags)) {
        ldflags = []
      }
      ldflags += [ "-Wl,-sectcreate,__TEXT,__entitlements," +
                   rebase_path(_generate_entitlements_output, root_build_dir) ]
    }

    output_name = _output_name
    output_prefix_override = true
    output_dir = "$target_out_dir/$target_cpu"
  }

  if (is_fat_secondary_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 (!is_fat_secondary_toolchain) {
      if (!defined(invoker.entitlements_target)) {
        _entitlements_path = "//chromium/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 = "//chromium/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 = [
                 "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)
      }
    }

    # Only write PkgInfo for real application, not application extension.
    if (_is_app_bundle) {
      _create_pkg_info = target_name + "_pkg_info"
      action(_create_pkg_info) {
        forward_variables_from(invoker, [ "testonly" ])
        script = "//chromium/build/apple/write_pkg_info.py"
        inputs = [ "//chromium/build/apple/plist_util.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",
                                 "xcode_extra_attributes",
                               ])

        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
        xcode_product_bundle_id = _xcode_product_bundle_id

        _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 (_is_app_bundle) {
          bundle_deps += [ ":$_bundle_data_pkg_info" ]
        }
        bundle_deps += _variant.bundle_deps

        if (target_environment == "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 = "//chromium/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_build_dir) +
               rebase_path(outputs, root_build_dir)
      }
    }
  }

  if (is_fat_secondary_toolchain) {
    not_needed("*")
  }
}

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",
                           ])
    product_type = _ios_xcode_appex_bundle_id
  }
}

set_defaults("ios_appex_bundle") {
  configs = [ "//chromium/build/config/ios:ios_extension_executable_flags" ]
}

# Template to compile .xib and .storyboard files.
#
# Arguments
#
#     sources:
#         list of string, sources to compile
#
#     ibtool_flags:
#         (optional) list of string, additional flags to pass to the ibtool
template("compile_ib_files") {
  action_foreach(target_name) {
    forward_variables_from(invoker,
                           [
                             "testonly",
                             "visibility",
                           ])
    assert(defined(invoker.sources),
           "sources must be specified for $target_name")
    assert(defined(invoker.output_extension),
           "output_extension must be specified for $target_name")

    ibtool_flags = []
    if (defined(invoker.ibtool_flags)) {
      ibtool_flags = invoker.ibtool_flags
    }

    _output_extension = invoker.output_extension

    script = "//chromium/build/config/ios/compile_ib_files.py"
    sources = invoker.sources
    outputs = [
      "$target_gen_dir/$target_name/{{source_name_part}}.$_output_extension",
    ]
    args = [
      "--input",
      "{{source}}",
      "--output",
      rebase_path(
          "$target_gen_dir/$target_name/{{source_name_part}}.$_output_extension",
          root_build_dir),
    ]
    args += ibtool_flags
  }
}

# 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 != []

  _primary_toolchain = current_toolchain
  if (is_fat_secondary_toolchain) {
    _primary_toolchain = primary_fat_toolchain_name
  }

  # 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($_primary_toolchain)", "root_out_dir")

  _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"

  if (_has_public_headers) {
    _default_toolchain_target_gen_dir =
        get_label_info("$_target_name($_primary_toolchain)", "target_gen_dir")

    _framework_headers_target = _target_name + "_framework_headers"

    _headers_map_config = _target_name + "_headers_map"
    _header_map_filename =
        "$_default_toolchain_target_gen_dir/$_output_name.headers.hmap"
    config(_headers_map_config) {
      visibility = [
        ":${_arch_shared_library_source}",
        ":${_target_name}_signed_bundle",
      ]
      include_dirs = [ _header_map_filename ]
    }
  }

  _framework_headers_config = _target_name + "_framework_headers_config"
  config(_framework_headers_config) {
    framework_dirs = [ _default_toolchain_root_out_dir ]
  }

  _framework_public_config = _target_name + "_public_config"
  config(_framework_public_config) {
    configs = [ ":$_framework_headers_config" ]
    frameworks = [ "$_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",
                             "public_configs",
                             "visibility",
                           ])

    visibility = [ ":$_arch_shared_library_target" ]

    if (_has_public_headers) {
      configs += [ ":$_headers_map_config" ]

      if (!defined(deps)) {
        deps = []
      }
      deps += [ ":$_framework_headers_target($_primary_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",
                             "public_configs",
                             "visibility",
                           ])

    visibility = [ ":$_lipo_shared_library_target($_primary_toolchain)" ]
    if (is_fat_secondary_toolchain) {
      visibility += [
        ":${_target_name}",
        ":${_target_name}_signed_bundle",
      ]
    }

    if (!defined(deps)) {
      deps = []
    }
    deps += [ ":$_arch_shared_library_source" ]
    if (_has_public_headers) {
      deps += [ ":$_framework_headers_target($_primary_toolchain)" ]
    }
    if (!defined(ldflags)) {
      ldflags = []
    }
    ldflags +=
        [ "-Wl,-install_name,@rpath/$_output_name.framework/$_output_name" ]

    output_extension = ""
    output_name = _output_name
    output_prefix_override = true
    output_dir = "$target_out_dir/$target_cpu"
  }

  if (is_fat_secondary_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($_primary_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" ]
    }

    group("$_target_name+bundle") {
      forward_variables_from(invoker, [ "testonly" ])
      public_deps = [ ":$_target_name+bundle($_primary_toolchain)" ]
    }

    not_needed(invoker, "*")
  } else {
    if (_has_public_headers) {
      _public_headers = invoker.public_headers

      _framework_root_dir = "$root_out_dir/$_output_name.framework"
      if (target_environment == "simulator" || target_environment == "device") {
        _framework_contents_dir = _framework_root_dir
      } else if (target_environment == "catalyst") {
        _framework_contents_dir = "$_framework_root_dir/Versions/A"
      }

      _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 = "//chromium/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".
        sources = []
        foreach(_source, invoker.sources) {
          if (get_path_info(_source, "extension") == "h") {
            sources += [ _source ]
          }
        }

        args = [
                 rebase_path(_header_map_filename),
                 rebase_path(_framework_root_dir, 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 = "//chromium/build/config/ios/write_framework_modulemap.py"
        outputs = [ "$_framework_contents_dir/Modules/module.modulemap" ]
        args = [
          _output_name,
          rebase_path("$_framework_contents_dir/Modules", 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_contents_dir/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}_signed_bundle" ]
      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}_signed_bundle" ]
      forward_variables_from(invoker, [ "testonly" ])
      sources = get_target_outputs(":$_info_plist_target")
      public_deps = [ ":$_info_plist_target" ]

      if (target_environment != "catalyst") {
        outputs = [ "{{bundle_contents_dir}}/Info.plist" ]
      } else {
        outputs = [ "{{bundle_resources_dir}}/Info.plist" ]
      }
    }

    create_signed_bundle(_target_name + "_signed_bundle") {
      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

      has_public_headers = _has_public_headers

      # 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(_target_name) {
      forward_variables_from(invoker,
                             [
                               "public_configs",
                               "public_deps",
                               "testonly",
                               "visibility",
                             ])
      if (!defined(public_deps)) {
        public_deps = []
      }
      public_deps += [ ":${_target_name}_signed_bundle" ]

      if (_has_public_headers) {
        if (!defined(public_configs)) {
          public_configs = []
        }
        public_configs += [ ":$_framework_headers_config" ]
      }
    }

    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 (!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_contents_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.
  if (is_fat_secondary_toolchain) {
    not_needed(invoker, "*")
  }

  _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"

  _primary_toolchain = current_toolchain
  if (is_fat_secondary_toolchain) {
    _primary_toolchain = primary_fat_toolchain_name
  }

  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($_primary_toolchain)" ]
    if (is_fat_secondary_toolchain) {
      visibility += [ ":$_target_name" ]
    }

    deps = [ ":$_arch_loadable_module_source" ]
    configs += [ "//chromium/build/config/ios:xctest_config" ]

    output_dir = "$target_out_dir/$target_cpu"
    output_name = _output_name
    output_prefix_override = true
    output_extension = ""
  }

  if (is_fat_secondary_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" ]
    }

    not_needed(invoker, "*")
  } 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 = "//chromium/build/config/ios/Module-Info.plist"
      executable_name = _output_name

      if (defined(invoker.xctest_bundle_principal_class)) {
        _principal_class = invoker.xctest_bundle_principal_class
      } else {
        # Fall back to a reasonable default value.
        _principal_class = "NSObject"
      }
      extra_substitutions = [
        "XCTEST_BUNDLE_PRINCIPAL_CLASS=${_principal_class}",
        "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,
                             [
                               "bundle_id",
                               "data_deps",
                               "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

      if (ios_set_attributes_for_xcode_project_generation) {
        _xcode_product_bundle_id =
            "$ios_app_bundle_id_prefix.gtest.$_output_name"

        _ios_provisioning_profile_info =
            exec_script("//chromium/build/config/ios/codesign.py",
                        [
                          "find-provisioning-profile",
                          "-b=" + _xcode_product_bundle_id,
                        ],
                        "json")

        xcode_extra_attributes = {
          IPHONEOS_DEPLOYMENT_TARGET = ios_deployment_target
          CODE_SIGN_IDENTITY = "iPhone Developer"
          DEVELOPMENT_TEAM = _ios_provisioning_profile_info.team_identifier
          PRODUCT_BUNDLE_IDENTIFIER = _xcode_product_bundle_id
          PROVISIONING_PROFILE_SPECIFIER = _ios_provisioning_profile_info.name

          # 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) {
            _xcode_app_name = invoker.xcode_test_application_name
            if (defined(invoker.xcode_test_application_output_name)) {
              _xcode_app_name = invoker.xcode_test_application_output_name
            }

            BUNDLE_LOADER = "\$(TEST_HOST)"
            TEST_HOST = "\$(BUILT_PRODUCTS_DIR)/" +
                        "${_xcode_app_name}.app/${_xcode_app_name}"
          }
        }
      } else {
        not_needed(invoker,
                   [
                     "xcode_test_application_name",
                     "xcode_test_application_output_name",
                   ])
      }

--> --------------------

--> maximum size reached

--> --------------------

[ Dauer der Verarbeitung: 0.24 Sekunden  (vorverarbeitet)  ]

                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge