| OLD | NEW |
| 1 # Copyright 2015 The Chromium Authors. All rights reserved. | 1 # Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
| 4 | 4 |
| 5 ios_app_script = "//build/config/ios/ios_app.py" | 5 import("//build/config/ios/ios_sdk.gni") |
| 6 | 6 |
| 7 template("code_sign_ios") { | 7 # TODO(crbug.com/297668): refactor this template to extract common behaviour |
| 8 assert(defined(invoker.entitlements_path), | 8 # between OS X and iOS bundle generation, then create a generic "app" template |
| 9 "The path to the entitlements .xcent file") | 9 # that forward to "executable" on all platform except iOS/OS X. |
| 10 assert(defined(invoker.identity), "The code signing identity") | |
| 11 assert(defined(invoker.application_path), "The application to code sign") | |
| 12 assert(defined(invoker.deps)) | |
| 13 | 10 |
| 14 action(target_name) { | 11 # Template to build an application bundle for iOS. |
| 12 # |
| 13 # This should be used instead of "executable" built-in target type on iOS. |
| 14 # As the template forward the generation of the application executable to |
| 15 # an "executable" target, all arguments supported by "executable" targets |
| 16 # are also supported by this template. |
| 17 # |
| 18 # Arguments |
| 19 # |
| 20 # app_name: |
| 21 # (optional) string, name of the generated application, if omitted, |
| 22 # defaults to the target_name. |
| 23 # |
| 24 # extra_substitutions: |
| 25 # (optional) list of string in "key=value" format, each value will |
| 26 # be used as an additional variable substitution rule when generating |
| 27 # the application Info.plist |
| 28 # |
| 29 # info_plist: |
| 30 # path to the template to use to generate the application Info.plist |
| 31 # by performing variable substitutions. |
| 32 # |
| 33 # For more information, see "gn help executable". |
| 34 template("app") { |
| 35 assert(defined(invoker.info_plist), |
| 36 "info_plist must be specified for target $target_name") |
| 37 |
| 38 _app_name = target_name |
| 39 _target_name = target_name |
| 40 if (defined(invoker.app_name)) { |
| 41 _app_name = invoker.app_name |
| 42 } |
| 43 |
| 44 _generate_info_plist = target_name + "_generate_info_plist" |
| 45 _bundle_data_info_plist = target_name + "_bundle_data_info_plist" |
| 46 |
| 47 action(_generate_info_plist) { |
| 48 visibility = [ ":$_bundle_data_info_plist" ] |
| 49 script = "//build/config/ios/ios_gen_plist.py" |
| 15 sources = [ | 50 sources = [ |
| 16 invoker.entitlements_path, | 51 "//build/config/ios/BuildInfo.plist", |
| 52 invoker.info_plist, |
| 17 ] | 53 ] |
| 54 outputs = [ |
| 55 "$target_gen_dir/$target_name/Info.plist", |
| 56 ] |
| 57 extra_args = [] |
| 58 if (defined(invoker.extra_substitutions)) { |
| 59 foreach(substitution, invoker.extra_substitutions) { |
| 60 extra_args += [ "-s=$substitution" ] |
| 61 } |
| 62 } |
| 63 response_file_contents = |
| 64 extra_args + [ |
| 65 "-s=BUILD_MACHINE_OS_BUILD=$machine_os_build", |
| 66 "-s=EXECUTABLE_NAME=$_app_name", |
| 67 "-s=GCC_VERSION=com.apple.compilers.llvm.clang.1_0", |
| 68 "-s=IOS_DEPLOYMENT_TARGET=$ios_deployment_target", |
| 69 "-s=IOS_PLATFORM_BUILD=$ios_platform_build", |
| 70 "-s=IOS_PLATFORM_NAME=$ios_sdk_name", |
| 71 "-s=IOS_PLATFORM_VERSION=$ios_sdk_version", |
| 72 "-s=IOS_SDK_BUILD=$ios_sdk_build", |
| 73 "-s=IOS_SDK_NAME=$ios_sdk_name$ios_sdk_version", |
| 74 "-s=IOS_SUPPORTED_PLATFORM=$ios_sdk_platform", |
| 75 "-s=PRODUCT_NAME=$_app_name", |
| 76 "-s=XCODE_BUILD=$xcode_build", |
| 77 "-s=XCODE_VERSION=$xcode_version", |
| 78 "-o=" + rebase_path(outputs[0], root_build_dir), |
| 79 ] + rebase_path(sources, root_build_dir) |
| 80 args = [ "@{{response_file_name}}" ] |
| 81 } |
| 18 | 82 |
| 19 _application_path = invoker.application_path | 83 bundle_data(_bundle_data_info_plist) { |
| 84 forward_variables_from(invoker, [ "testonly" ]) |
| 85 visibility = [ ":$_target_name" ] |
| 86 sources = get_target_outputs(":$_generate_info_plist") |
| 87 outputs = [ |
| 88 "{{bundle_root_dir}}/Info.plist", |
| 89 ] |
| 90 public_deps = [ |
| 91 ":$_generate_info_plist", |
| 92 ] |
| 93 } |
| 20 | 94 |
| 21 script = ios_app_script | 95 _generate_executable = target_name + "_generate_executable" |
| 96 _bundle_data_executable = target_name + "_bundle_data_executable" |
| 22 | 97 |
| 98 executable(_generate_executable) { |
| 99 visibility = [ ":$_bundle_data_executable" ] |
| 100 forward_variables_from(invoker, |
| 101 "*", |
| 102 [ |
| 103 "app_name", |
| 104 "code_signing_identity", |
| 105 "data_deps", |
| 106 "entitlements_path", |
| 107 "info_plist", |
| 108 "visibility", |
| 109 ]) |
| 110 |
| 111 output_name = rebase_path("$target_gen_dir/$_app_name", root_build_dir) |
| 112 if (!defined(libs)) { |
| 113 libs = [] |
| 114 } |
| 115 libs += [ "UIKit.framework" ] |
| 116 } |
| 117 |
| 118 bundle_data(_bundle_data_executable) { |
| 119 forward_variables_from(invoker, [ "testonly" ]) |
| 120 visibility = [ ":$_target_name" ] |
| 121 sources = [ |
| 122 "$target_gen_dir/$_app_name", |
| 123 ] |
| 23 outputs = [ | 124 outputs = [ |
| 24 "$_application_path/_CodeSignature/CodeResources", | 125 "{{bundle_executable_dir}}/$_app_name", |
| 25 ] | 126 ] |
| 127 public_deps = [ |
| 128 ":$_generate_executable", |
| 129 ] |
| 130 } |
| 26 | 131 |
| 27 args = [ | 132 create_bundle(target_name) { |
| 28 "codesign", | |
| 29 "-p", | |
| 30 rebase_path(invoker.application_path, root_build_dir), | |
| 31 "-i", | |
| 32 invoker.identity, | |
| 33 "-e", | |
| 34 rebase_path(invoker.entitlements_path, root_build_dir), | |
| 35 ] | |
| 36 | |
| 37 forward_variables_from(invoker, | 133 forward_variables_from(invoker, |
| 38 [ | 134 [ |
| 135 "data_deps", |
| 39 "deps", | 136 "deps", |
| 40 "public_deps", | 137 "public_deps", |
| 41 "testonly", | 138 "testonly", |
| 139 "visibility", |
| 42 ]) | 140 ]) |
| 43 } | |
| 44 } | |
| 45 | 141 |
| 46 # TODO(GYP), TODO(dpranke): Should this be part of ios_app? | 142 if (!defined(deps)) { |
| 47 template("resource_copy_ios") { | 143 deps = [] |
| 48 assert(defined(invoker.resources), | 144 } |
| 49 "The source list of resources to copy over") | 145 deps += [ |
| 50 assert(defined(invoker.bundle_directory), | 146 ":$_bundle_data_executable", |
| 51 "The directory within the bundle to place the sources in") | 147 ":$_bundle_data_info_plist", |
| 52 assert(defined(invoker.app_name), "The name of the application") | 148 ] |
| 53 | 149 |
| 54 _bundle_directory = invoker.bundle_directory | 150 bundle_root_dir = "$root_out_dir/$_app_name.app" |
| 55 _app_name = invoker.app_name | 151 bundle_resources_dir = bundle_root_dir |
| 56 _resources = invoker.resources | 152 bundle_executable_dir = bundle_root_dir |
| 57 | 153 bundle_plugins_dir = "$bundle_root_dir/Plugins" |
| 58 copy(target_name) { | |
| 59 set_sources_assignment_filter([]) | |
| 60 sources = _resources | |
| 61 outputs = [ | |
| 62 "$root_build_dir/$_app_name.app/$_bundle_directory/{{source_file_part}}", | |
| 63 ] | |
| 64 } | |
| 65 } | |
| 66 | |
| 67 template("ios_app") { | |
| 68 assert(defined(invoker.deps), | |
| 69 "Dependencies must be specified for $target_name") | |
| 70 assert(defined(invoker.info_plist), | |
| 71 "The application plist file must be specified for $target_name") | |
| 72 assert(defined(invoker.entitlements_path), | |
| 73 "The entitlements path must be specified for $target_name") | |
| 74 assert(defined(invoker.code_signing_identity), | |
| 75 "The code_signing_identity must be specified for $target_name") | |
| 76 | |
| 77 # We just create a variable so we can use the same in interpolation | |
| 78 if (defined(invoker.app_name)) { | |
| 79 _app_name = invoker.app_name | |
| 80 } else { | |
| 81 _app_name = target_name | |
| 82 } | 154 } |
| 83 | 155 |
| 84 forward_variables_from(invoker, [ "testonly" ]) | 156 # TODO(crbug.com/297668): |
| 85 | 157 # - add support for codesigning, |
| 86 plist_gen_target_name = target_name + "_plist" | 158 # - find a way to make "ninja -C out/Default base_unittests.app" work as |
| 87 bin_gen_target_name = target_name + "_bin" | 159 # an alias to "ninja -C out/Default base_unittests" (for convenience |
| 88 group_target_name = target_name | 160 # and compatibility with gyp), |
| 89 | 161 # - implement //testing/iossim(//build/toolchain/mac:clang_x64) and then |
| 90 # Generate the executable | 162 # add a depency to that target. |
| 91 executable(bin_gen_target_name) { | |
| 92 visibility = [ ":$group_target_name" ] | |
| 93 | |
| 94 output_name = "${_app_name}.app/${_app_name}" | |
| 95 | |
| 96 forward_variables_from(invoker, | |
| 97 [ | |
| 98 "all_dependent_configs", | |
| 99 "allow_circular_includes_from", | |
| 100 "cflags", | |
| 101 "cflags_c", | |
| 102 "cflags_cc", | |
| 103 "cflags_objc", | |
| 104 "cflags_objcc", | |
| 105 "configs", | |
| 106 "check_includes", | |
| 107 "data", | |
| 108 "data_deps", | |
| 109 "defines", | |
| 110 "include_dirs", | |
| 111 "ldflags", | |
| 112 "public", | |
| 113 "public_configs", | |
| 114 "public_deps", | |
| 115 "sources", | |
| 116 ]) | |
| 117 | |
| 118 if (defined(invoker.libs)) { | |
| 119 libs = invoker.libs | |
| 120 } else { | |
| 121 libs = [] | |
| 122 } | |
| 123 libs += [ | |
| 124 "UIKit.framework", | |
| 125 "QuartzCore.framework", | |
| 126 "OpenGLES.framework", | |
| 127 ] | |
| 128 | |
| 129 if (defined(invoker.deps)) { | |
| 130 deps = invoker.deps | |
| 131 } else { | |
| 132 deps = [] | |
| 133 } | |
| 134 deps += [ ":$plist_gen_target_name" ] | |
| 135 } | |
| 136 | |
| 137 # Process the Info.plist | |
| 138 action(plist_gen_target_name) { | |
| 139 visibility = [ | |
| 140 ":$group_target_name", | |
| 141 ":$bin_gen_target_name", | |
| 142 ] | |
| 143 | |
| 144 script = ios_app_script | |
| 145 | |
| 146 sources = [ | |
| 147 invoker.info_plist, | |
| 148 ] | |
| 149 outputs = [ | |
| 150 "$root_build_dir/${_app_name}.app/Info.plist", | |
| 151 ] | |
| 152 | |
| 153 args = [ | |
| 154 "plist", | |
| 155 "-i", | |
| 156 rebase_path(invoker.info_plist, root_build_dir), | |
| 157 "-o", | |
| 158 rebase_path("$root_build_dir/${_app_name}.app"), | |
| 159 ] | |
| 160 } | |
| 161 | |
| 162 # Perform Code Signing | |
| 163 entitlements_path = invoker.entitlements_path | |
| 164 if (invoker.code_signing_identity != "") { | |
| 165 code_sign_gen_target_name = target_name + "_codesign" | |
| 166 code_sign_ios(code_sign_gen_target_name) { | |
| 167 visibility = [ ":$target_name" ] | |
| 168 | |
| 169 identity = invoker.code_signing_identity | |
| 170 application_path = "$root_build_dir/$app_name.app" | |
| 171 deps = [ | |
| 172 ":$bin_gen_target_name", | |
| 173 ":$plist_gen_target_name", | |
| 174 ] | |
| 175 } | |
| 176 } else { | |
| 177 # This avoids a potential unused variable warning in the caller. | |
| 178 entitlements_path = entitlements_path | |
| 179 } | |
| 180 | |
| 181 # Top level group | |
| 182 group(target_name) { | |
| 183 forward_variables_from(invoker, [ "visibility" ]) | |
| 184 deps = [ | |
| 185 ":$bin_gen_target_name", | |
| 186 ":$plist_gen_target_name", | |
| 187 ] | |
| 188 if (invoker.code_signing_identity != "") { | |
| 189 deps += [ ":$code_sign_gen_target_name" ] | |
| 190 } | |
| 191 } | |
| 192 } | 163 } |
| OLD | NEW |