1# Copyright 2019 Google LLC. 2# Use of this source code is governed by a BSD-style license that can be 3# found in the LICENSE file. 4 5import("skia.gni") 6 7if (is_ios) { 8 # Template to compile .xib and .storyboard files. 9 # 10 # Arguments 11 # 12 # sources: 13 # list of string, sources to compile 14 # 15 # ibtool_flags: 16 # (optional) list of string, additional flags to pass to the ibtool 17 template("compile_ib_files") { 18 action_foreach(target_name) { 19 forward_variables_from(invoker, 20 [ 21 "testonly", 22 "visibility", 23 ]) 24 assert(defined(invoker.sources), 25 "sources must be specified for $target_name") 26 assert(defined(invoker.output_extension), 27 "output_extension must be specified for $target_name") 28 29 ibtool_flags = [] 30 if (defined(invoker.ibtool_flags)) { 31 ibtool_flags = invoker.ibtool_flags 32 } 33 34 _output_extension = invoker.output_extension 35 36 script = "//gn/compile_ib_files.py" 37 sources = invoker.sources 38 outputs = [ 39 "$target_gen_dir/$target_name/{{source_name_part}}.$_output_extension", 40 ] 41 args = [ 42 "--input", 43 "{{source}}", 44 "--output", 45 rebase_path( 46 "$target_gen_dir/$target_name/{{source_name_part}}.$_output_extension", 47 root_build_dir), 48 ] 49 50 # if (!use_system_xcode) { 51 # args += [ 52 # "--developer_dir", 53 # hermetic_xcode_path, 54 # ] 55 # } 56 args += ibtool_flags 57 } 58 } 59 60 template("bundle_data_ib_file") { 61 assert(defined(invoker.source), 62 "source needs to be defined for $target_name") 63 64 _source_extension = get_path_info(invoker.source, "extension") 65 assert(_source_extension == "xib" || _source_extension == "storyboard", 66 "source must be a .xib or .storyboard for $target_name") 67 68 _target_name = target_name 69 if (_source_extension == "xib") { 70 _compile_ib_file = target_name + "_compile_xib" 71 _output_extension = "nib" 72 } else { 73 _compile_ib_file = target_name + "_compile_storyboard" 74 _output_extension = "storyboardc" 75 } 76 77 compile_ib_files(_compile_ib_file) { 78 sources = [ invoker.source ] 79 output_extension = _output_extension 80 visibility = [ ":$_target_name" ] 81 ibtool_flags = [ 82 # "--minimum-deployment-target", 83 # ios_deployment_target, 84 "--auto-activate-custom-fonts", 85 "--target-device", 86 "iphone", 87 "--target-device", 88 "ipad", 89 ] 90 } 91 92 bundle_data(_target_name) { 93 forward_variables_from(invoker, "*", [ "source" ]) 94 95 if (!defined(public_deps)) { 96 public_deps = [] 97 } 98 public_deps += [ ":$_compile_ib_file" ] 99 100 sources = get_target_outputs(":$_compile_ib_file") 101 102 outputs = [ "{{bundle_resources_dir}}/{{source_file_part}}" ] 103 } 104 } 105 106 template("ios_app_bundle") { 107 app_name = target_name 108 gen_path = target_gen_dir 109 bundle_prefix = "com.google" 110 plist_string = string_join( 111 "$0x0A", 112 [ 113 "<plist version=\"1.0\">", 114 " <dict>", 115 " <key>CFBundleVersion</key> <string>0.1.0</string>", 116 " <key>CFBundleShortVersionString</key> <string>0.1.0</string>", 117 " <key>CFBundleName</key> <string>${app_name}</string>", 118 " <key>CFBundleExecutable</key> <string>${app_name}</string>", 119 " <key>CFBundleIdentifier</key> <string>${bundle_prefix}.${app_name}</string>", 120 " <key>CFBundlePackageType</key> <string>APPL</string>", 121 " <key>LSRequiresIPhoneOS</key> <true/>", 122 " <key>UILaunchStoryboardName</key> <string>LaunchScreen</string>", 123 " <key>UIFileSharingEnabled</key> <true/>", 124 " </dict>", 125 "</plist>", 126 ]) 127 128 write_file("$gen_path/${app_name}_Info.plist", plist_string) 129 130 bundle_data("${app_name}_bundle_info_plist") { 131 sources = [ "$gen_path/${app_name}_Info.plist" ] 132 outputs = [ "{{bundle_resources_dir}}/Info.plist" ] 133 } 134 135 if (defined(invoker.data_sources)) { 136 bundle_data("${app_name}_bundle_resources_and_skps") { 137 sources = invoker.data_sources 138 139 # iOS reserves the folders 'Resources' and 'resources' so store one level deeper 140 outputs = [ "{{bundle_resources_dir}}/data/{{source_file_part}}" ] 141 } 142 } 143 144 if (defined(invoker.launchscreen)) { 145 bundle_data_ib_file("${app_name}_bundle_launchscreen") { 146 source = invoker.launchscreen 147 } 148 } 149 150 executable("${app_name}_generate_executable") { 151 if (!defined(configs)) { 152 configs = [] 153 } 154 forward_variables_from(invoker, 155 "*", 156 [ 157 "output_name", 158 "visibility", 159 "is_shared_library", 160 "data_sources", 161 "extra_configs", 162 "configs", 163 ]) 164 if (defined(invoker.configs)) { 165 configs += invoker.configs 166 } 167 if (defined(invoker.extra_configs)) { 168 configs += invoker.extra_configs 169 } 170 output_name = rebase_path("$gen_path/$app_name", root_build_dir) 171 } 172 173 action("${app_name}_dsymutil") { 174 public_deps = [ ":${app_name}_generate_executable" ] 175 sources = [ "$gen_path/$app_name" ] 176 script = "//gn/call.py" 177 args = [ 178 "dsymutil", 179 rebase_path("$gen_path/$app_name"), 180 ] 181 outputs = [ "$gen_path/${app_name}.dSYM" ] 182 testonly = defined(invoker.testonly) && invoker.testonly 183 pool = "//gn/toolchain:dsymutil_pool($default_toolchain)" 184 } 185 186 bundle_data("${app_name}_bundle_executable_and_symbols") { 187 public_deps = [ 188 ":${app_name}_dsymutil", 189 ":${app_name}_generate_executable", 190 ] 191 sources = [ 192 "$gen_path/${app_name}", 193 "$gen_path/${app_name}.dSYM", 194 ] 195 outputs = [ "{{bundle_executable_dir}}/{{source_file_part}}" ] 196 testonly = defined(invoker.testonly) && invoker.testonly 197 } 198 199 create_bundle("$app_name") { 200 product_type = "com.apple.product-type.application" 201 testonly = defined(invoker.testonly) && invoker.testonly 202 203 bundle_root_dir = "${root_build_dir}/${target_name}.app" 204 bundle_resources_dir = bundle_root_dir 205 bundle_executable_dir = bundle_root_dir 206 207 xcode_extra_attributes = { 208 PRODUCT_BUNDLE_IDENTIFIER = "${bundle_prefix}.${app_name}" 209 if (ios_min_target != "") { 210 IPHONEOS_DEPLOYMENT_TARGET = ios_min_target 211 } 212 INFOPLIST_FILE = rebase_path("${target_gen_dir}/${app_name}_Info.plist") 213 } 214 215 deps = [ 216 ":${app_name}_bundle_executable_and_symbols", 217 ":${app_name}_bundle_info_plist", 218 ] 219 if (defined(invoker.launchscreen)) { 220 deps += [ ":${app_name}_bundle_launchscreen" ] 221 } 222 if (defined(invoker.data_sources)) { 223 deps += [ ":${app_name}_bundle_resources_and_skps" ] 224 } 225 226 if (skia_ios_use_signing) { 227 post_processing_script = "//gn/codesign_ios.py" 228 post_processing_sources = [ "$target_gen_dir/$app_name" ] 229 post_processing_outputs = [ 230 "$bundle_root_dir/_CodeSignature/CodeResources", 231 "$bundle_root_dir/embedded.mobileprovision", 232 ] 233 post_processing_args = [ 234 rebase_path("$bundle_root_dir", root_build_dir), 235 skia_ios_identity, 236 skia_ios_profile, 237 ] 238 } 239 } 240 } 241} 242