| # Copyright 2024 The Chromium Authors |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| import("//build/config/apple/mobile_config.gni") |
| import("//build/toolchain/rbe.gni") |
| import("//build_overrides/build.gni") |
| |
| # Constants corresponding to the bundle type identifiers use application, |
| # application extension, XCTest and XCUITest targets respectively. |
| apple_mobile_xcode_app_bundle_id = "com.apple.product-type.application" |
| apple_mobile_xcode_appex_bundle_id = "com.apple.product-type.app-extension" |
| apple_mobile_xcode_xctest_bundle_id = "com.apple.product-type.bundle.unit-test" |
| apple_mobile_xcode_xcuitest_bundle_id = |
| "com.apple.product-type.bundle.ui-testing" |
| |
| # Wrapper around create_bundle taking care of code signature settings. |
| # |
| # Arguments |
| # |
| # product_type |
| # string, product type for the generated Xcode project. |
| # |
| # platform_sdk_name |
| # string, the name of the platform SDK |
| # |
| # 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. |
| # |
| # transparent |
| # (optional) boolean, whether the bundle is "transparent"; defaults to |
| # "false" if omitted; a bundle is considered "transparent" if it does |
| # not package the "bundle_data" deps but forward them to all targets |
| # the depend on it (unless the "bundle_data" target sets "product_type" |
| # to the same value as the "create_signed_bundle" target). |
| # |
| template("apple_mobile_create_signed_bundle") { |
| assert(defined(invoker.product_type), |
| "product_type must be defined for $target_name") |
| assert(defined(invoker.platform_sdk_name), |
| "platform_sdk_name 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 == apple_mobile_xcode_xctest_bundle_id || |
| invoker.product_type == apple_mobile_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 = "//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", |
| "transparent", |
| "visibility", |
| "xcasset_compiler_flags", |
| "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 = [] |
| } |
| |
| _bundle_identifier = "" |
| if (defined(invoker.xcode_product_bundle_id)) { |
| _bundle_identifier = invoker.xcode_product_bundle_id |
| assert(_bundle_identifier == string_replace(_bundle_identifier, "_", "-"), |
| "$target_name: bundle_identifier does not respect rfc1034: " + |
| _bundle_identifier) |
| } |
| |
| xcode_extra_attributes = { |
| PRODUCT_BUNDLE_IDENTIFIER = _bundle_identifier |
| CODE_SIGNING_REQUIRED = "NO" |
| CODE_SIGNING_ALLOWED = "NO" |
| CODE_SIGN_IDENTITY = "" |
| DONT_GENERATE_INFOPLIST_FILE = "YES" |
| |
| # 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 = [] |
| } |
| |
| post_processing_script = "//build/config/apple/codesign.py" |
| post_processing_sources = [ _bundle_binary_path ] |
| if (_enable_entitlements) { |
| if (defined(invoker.entitlements_target)) { |
| deps += [ invoker.entitlements_target ] |
| } |
| post_processing_sources += [ _entitlements_path ] |
| } |
| post_processing_outputs = [ "$bundle_executable_dir/$_output_name" ] |
| if (_enable_code_signing) { |
| post_processing_outputs += |
| [ "$bundle_contents_dir/_CodeSignature/CodeResources" ] |
| } |
| if (ios_code_signing_identity != "" && target_environment == "device" && |
| _enable_embedded_mobileprovision) { |
| post_processing_outputs += |
| [ "$bundle_contents_dir/embedded.mobileprovision" ] |
| } |
| if (_bundle_extension == ".framework") { |
| if (target_environment == "catalyst") { |
| post_processing_outputs += [ |
| "$bundle_root_dir/Versions/Current", |
| "$bundle_root_dir/$_output_name", |
| ] |
| |
| if (defined(invoker.has_public_headers) && invoker.has_public_headers) { |
| post_processing_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) { |
| post_processing_outputs += [ "$bundle_contents_dir/Frameworks/" + |
| get_path_info(_framework, "file") ] |
| } |
| } |
| |
| post_processing_args = [ |
| "code-sign-bundle", |
| "-t=" + invoker.platform_sdk_name, |
| "-i=" + ios_code_signing_identity, |
| "-b=" + rebase_path(_bundle_binary_path, root_build_dir), |
| ] |
| foreach(mobileprovision, ios_mobileprovision_files) { |
| post_processing_args += |
| [ "-m=" + rebase_path(mobileprovision, root_build_dir) ] |
| } |
| post_processing_sources += ios_mobileprovision_files |
| if (_enable_entitlements) { |
| post_processing_args += |
| [ "-e=" + rebase_path(_entitlements_path, root_build_dir) ] |
| } |
| if (!_enable_embedded_mobileprovision) { |
| post_processing_args += [ "--disable-embedded-mobileprovision" ] |
| } |
| post_processing_args += [ rebase_path(bundle_root_dir, root_build_dir) ] |
| if (!_enable_code_signing) { |
| post_processing_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 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_remoteexec) { |
| _framework_path = rebase_path(_framework, root_build_dir) |
| } else { |
| _framework_path = _framework |
| } |
| post_processing_args += [ "-F=$_framework_path" ] |
| } |
| } |
| if (defined(invoker.partial_info_plist)) { |
| _partial_info_plists = [ |
| invoker.primary_info_plist, |
| invoker.partial_info_plist, |
| ] |
| |
| _plist_compiler_path = "//build/apple/plist_util.py" |
| |
| post_processing_sources += _partial_info_plists |
| post_processing_sources += [ _plist_compiler_path ] |
| if (target_environment != "catalyst" || |
| _bundle_extension != ".framework") { |
| post_processing_outputs += [ "$bundle_contents_dir/Info.plist" ] |
| } else { |
| post_processing_outputs += [ "$bundle_resources_dir/Info.plist" ] |
| } |
| |
| post_processing_args += |
| [ "-P=" + rebase_path(_plist_compiler_path, root_build_dir) ] |
| foreach(_partial_info_plist, _partial_info_plists) { |
| post_processing_args += |
| [ "-p=" + rebase_path(_partial_info_plist, root_build_dir) ] |
| } |
| } |
| } |
| } |