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 " </dict>", 124 "</plist>", 125 ]) 126 127 write_file("$gen_path/${app_name}_Info.plist", plist_string) 128 129 bundle_data("${app_name}_bundle_info_plist") { 130 sources = [ "$gen_path/${app_name}_Info.plist" ] 131 outputs = [ "{{bundle_resources_dir}}/Info.plist" ] 132 } 133 134 if (defined(invoker.data_sources)) { 135 bundle_data("${app_name}_bundle_resources_and_skps") { 136 sources = invoker.data_sources 137 138 # iOS reserves the folders 'Resources' and 'resources' so store one level deeper 139 outputs = [ "{{bundle_resources_dir}}/data/{{source_file_part}}" ] 140 } 141 } 142 143 if (defined(invoker.launchscreen)) { 144 bundle_data_ib_file("${app_name}_bundle_launchscreen") { 145 source = invoker.launchscreen 146 } 147 } 148 149 executable("${app_name}_generate_executable") { 150 if (!defined(configs)) { 151 configs = [] 152 } 153 forward_variables_from(invoker, 154 "*", 155 [ 156 "output_name", 157 "visibility", 158 "is_shared_library", 159 "data_sources", 160 "extra_configs", 161 "configs", 162 ]) 163 if (defined(invoker.configs)) { 164 configs += invoker.configs 165 } 166 if (defined(invoker.extra_configs)) { 167 configs += invoker.extra_configs 168 } 169 output_name = rebase_path("$gen_path/$app_name", root_build_dir) 170 } 171 172 action("${app_name}_dsymutil") { 173 public_deps = [ ":${app_name}_generate_executable" ] 174 sources = [ "$gen_path/$app_name" ] 175 script = "//gn/call.py" 176 args = [ 177 "dsymutil", 178 rebase_path("$gen_path/$app_name"), 179 ] 180 outputs = [ "$gen_path/${app_name}.dSYM" ] 181 testonly = defined(invoker.testonly) && invoker.testonly 182 pool = "//gn/toolchain:dsymutil_pool($default_toolchain)" 183 } 184 185 bundle_data("${app_name}_bundle_executable_and_symbols") { 186 public_deps = [ 187 ":${app_name}_dsymutil", 188 ":${app_name}_generate_executable", 189 ] 190 sources = [ 191 "$gen_path/${app_name}", 192 "$gen_path/${app_name}.dSYM", 193 ] 194 outputs = [ "{{bundle_executable_dir}}/{{source_file_part}}" ] 195 testonly = defined(invoker.testonly) && invoker.testonly 196 } 197 198 create_bundle("$app_name") { 199 product_type = "com.apple.product-type.application" 200 testonly = defined(invoker.testonly) && invoker.testonly 201 202 bundle_root_dir = "${root_build_dir}/${target_name}.app" 203 bundle_resources_dir = bundle_root_dir 204 bundle_executable_dir = bundle_root_dir 205 206 xcode_extra_attributes = { 207 PRODUCT_BUNDLE_IDENTIFIER = "${bundle_prefix}.${app_name}" 208 if (ios_min_target != "") { 209 IPHONEOS_DEPLOYMENT_TARGET = ios_min_target 210 } 211 INFOPLIST_FILE = rebase_path("${target_gen_dir}/${app_name}_Info.plist") 212 } 213 214 deps = [ 215 ":${app_name}_bundle_executable_and_symbols", 216 ":${app_name}_bundle_info_plist", 217 ] 218 if (defined(invoker.launchscreen)) { 219 deps += [ ":${app_name}_bundle_launchscreen" ] 220 } 221 if (defined(invoker.data_sources)) { 222 deps += [ ":${app_name}_bundle_resources_and_skps" ] 223 } 224 225 if (skia_ios_use_signing) { 226 post_processing_script = "//gn/codesign_ios.py" 227 post_processing_sources = [ "$target_gen_dir/$app_name" ] 228 post_processing_outputs = [ 229 "$bundle_root_dir/_CodeSignature/CodeResources", 230 "$bundle_root_dir/embedded.mobileprovision", 231 ] 232 post_processing_args = [ 233 rebase_path("$bundle_root_dir", root_build_dir), 234 skia_ios_identity, 235 skia_ios_profile, 236 ] 237 } 238 } 239 } 240} 241