Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(169)

Unified Diff: build/config/ios/rules.gni

Issue 2123253004: Add support for multi-architecture application bundle on iOS. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Add comment on how to use additional_target_cpus variable Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « build/config/ios/ios_sdk.gni ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: build/config/ios/rules.gni
diff --git a/build/config/ios/rules.gni b/build/config/ios/rules.gni
index 219b580be3c0e7beb6ade0a48bdcf603bb6942a1..aec0de5b8fa322d77b856fa4906ba88939bc995c 100644
--- a/build/config/ios/rules.gni
+++ b/build/config/ios/rules.gni
@@ -70,10 +70,6 @@ template("ios_info_plist") {
}
}
-# TODO(crbug.com/297668): refactor this template to extract common behaviour
-# between OS X and iOS bundle generation, then create a generic "app" template
-# that forward to "executable" on all platform except iOS/OS X.
-
# Template to build an application bundle for iOS.
#
# This should be used instead of "executable" built-in target type on iOS.
@@ -122,156 +118,324 @@ template("ios_app_bundle") {
_output_name = invoker.output_name
}
- _generate_info_plist = target_name + "_generate_info_plist"
- _bundle_data_info_plist = target_name + "_bundle_data_info_plist"
-
- ios_info_plist(_generate_info_plist) {
- executable_name = _output_name
- forward_variables_from(invoker,
- [
- "extra_substitutions",
- "info_plist",
- "info_plist_target",
- ])
- }
-
- bundle_data(_bundle_data_info_plist) {
- forward_variables_from(invoker, [ "testonly" ])
- visibility = [ ":$_target_name" ]
- sources = get_target_outputs(":$_generate_info_plist")
- outputs = [
- "{{bundle_root_dir}}/Info.plist",
- ]
- public_deps = [
- ":$_generate_info_plist",
- ]
- }
-
- _generate_executable = target_name + "_generate_executable"
- if (!ios_enable_code_signing) {
- _bundle_data_executable = target_name + "_bundle_data_executable"
+ # This template expands to multiple targets with some differences between
+ # the the different build configuration.
+ #
+ # For a thin build (i.e. when additional_target_cpus is an empty list),
+ # it compiles the final application binary with an "executable" target,
+ # performs variable expansions on the Info.plist, defines some "bundle_data"
+ # target to pack Info.plist and the executable into the .app bundle, and
+ # finally a "create_bundle" target that packs everything the bundle. If the
+ # bundle needs to be signed, then the binary is copied into the bundle by
+ # the "create_bundle" target and the intermediate "bundle_data" target is
+ # not generated.
+ #
+ # For a multi-architecture build (aka fat-build), the template expands to
+ # a simple "executable" target for non-default toolchain. This is because
+ # the real application bundle will contains a single binary that supports
+ # all the architectures and creating a separate .app bundle for every
+ # architecture would be a waste of time.
+ #
+ # The target for the default toolchain of a multi-architecture build will
+ # build the executable for current_cpu in a temporary location. The real
+ # fat binary will be created by "lipo" command from all those "executable"
+ # target (including those of the non-default toolchains). This additional
+ # target has the same role as the "executable" target of a thin build.
+ #
+ # The rest of the build, including the codesigning step, are the same for
+ # thin and fat builds.
+
+ _is_fat_build = additional_toolchains != []
+ if (_is_fat_build) {
+ _is_fat_build_main_target = current_toolchain == default_toolchain
}
- executable(_generate_executable) {
- if (ios_enable_code_signing) {
- visibility = [ ":$_target_name" ]
- } else {
- visibility = [ ":$_bundle_data_executable" ]
- }
- forward_variables_from(invoker,
- "*",
- [
- "bundle_extension",
- "data_deps",
- "entitlements_path",
- "info_plist",
- "info_plist_target",
- "output_name",
- "product_type",
- "visibility",
- ])
+ if (_is_fat_build && !_is_fat_build_main_target) {
+ # For the non-default toolchain of a fat-build, the template expands to a
+ # single "executable" target that creates "$root_out_dir/$_output_name".
+ executable(_target_name) {
+ forward_variables_from(invoker,
+ "*",
+ [
+ "bundle_extension",
+ "entitlements_path",
+ "extra_substitutions",
+ "info_plist",
+ "info_plist_target",
+ "output_name",
+ "product_type",
+ ])
- output_name = rebase_path("$target_gen_dir/$_output_name", root_out_dir)
- output_prefix_override = true
+ if (defined(visibility)) {
+ visibility += [ ":*($default_toolchain)" ]
+ }
- if (!defined(libs)) {
- libs = []
+ output_name = _output_name
+ if (!defined(libs)) {
+ libs = []
+ }
+ libs += [ "UIKit.framework" ]
+ if (!defined(ldflags)) {
+ ldflags = []
+ }
+ ldflags += [ "-ObjC" ]
}
- libs += [ "UIKit.framework" ]
- if (!defined(ldflags)) {
- ldflags = []
+ } else {
+ # This is either a thin build or the default toolchain of a fat-build.
+ # The template will expand in many different target ($target_name is the
+ # create_bundle target) used as input to the create_bundle target.
+ _generate_info_plist = target_name + "_generate_info_plist"
+ _bundle_data_info_plist = target_name + "_bundle_data_info_plist"
+
+ ios_info_plist(_generate_info_plist) {
+ visibility = [ ":$_bundle_data_info_plist" ]
+ executable_name = _output_name
+ forward_variables_from(invoker,
+ [
+ "extra_substitutions",
+ "info_plist",
+ "info_plist_target",
+ ])
}
- ldflags += [ "-ObjC" ]
- }
- if (!ios_enable_code_signing) {
- bundle_data(_bundle_data_executable) {
- forward_variables_from(invoker, [ "testonly" ])
+ bundle_data(_bundle_data_info_plist) {
visibility = [ ":$_target_name" ]
- sources = [
- "$target_gen_dir/$_output_name",
- ]
+ forward_variables_from(invoker, [ "testonly" ])
+ sources = get_target_outputs(":$_generate_info_plist")
outputs = [
- "{{bundle_executable_dir}}/$_output_name",
+ "{{bundle_root_dir}}/Info.plist",
]
public_deps = [
- ":$_generate_executable",
+ ":$_generate_info_plist",
]
}
- }
- create_bundle(target_name) {
- forward_variables_from(invoker,
- [
- "data_deps",
- "deps",
- "public_deps",
- "testonly",
- "visibility",
- ])
+ _link_executable = _target_name + "_link_executable"
+ _executable_path = "$target_out_dir/$_output_name"
- if (!defined(deps)) {
- deps = []
- }
- deps += [ ":$_bundle_data_info_plist" ]
if (ios_enable_code_signing) {
- deps += [ ":$_generate_executable" ]
+ _link_executable_visibility = [ ":$_target_name" ]
} else {
- deps += [ ":$_bundle_data_executable" ]
+ _bundle_data_executable = target_name + "_bundle_data_executable"
+ _link_executable_visibility = [ ":$_bundle_data_executable" ]
}
- if (use_ios_simulator) {
- if (!defined(data_deps)) {
- data_deps = []
+ # For a fat-build, the different "executable" outputs will be used to
+ # create the final binary using "lipo". As the corresponding target has
+ # the same role as the "executable" target in a thin build, copy the
+ # visibility and redefine some variables.
+ if (_is_fat_build) {
+ _lipo_executable = _target_name + "_lipo_executable"
+ _lipo_executable_visibility = _link_executable_visibility
+
+ _link_executable_visibility = []
+ _link_executable_visibility = [ ":$_lipo_executable" ]
+
+ _arch_executable_path = "$target_out_dir/$current_cpu/$_output_name"
+ }
+
+ executable(_link_executable) {
+ forward_variables_from(invoker,
+ "*",
+ [
+ "bundle_extension",
+ "data_deps",
+ "entitlements_path",
+ "extra_substitutions",
+ "info_plist",
+ "info_plist_target",
+ "output_name",
+ "product_type",
+ "visibility",
+ ])
+
+ visibility = _link_executable_visibility
+
+ output_prefix_override = true
+ if (_is_fat_build) {
+ output_name = rebase_path(_arch_executable_path, root_build_dir)
+ } else {
+ output_name = rebase_path(_executable_path, root_build_dir)
+ }
+
+ if (!defined(libs)) {
+ libs = []
+ }
+ libs += [ "UIKit.framework" ]
+ if (!defined(ldflags)) {
+ ldflags = []
}
- data_deps += [ "//testing/iossim" ]
+ ldflags += [ "-ObjC" ]
}
- if (defined(invoker.product_type)) {
- product_type = invoker.product_type
- } else {
- product_type = "com.apple.product-type.application"
+ if (_is_fat_build) {
+ # Create the multi-architecture binary from all the single architecture
+ # binaries using "lipo". This target exists for the default toolchain
+ # of a fat-build only and depends on the expansion of "ios_app_bundle"
+ # for the other toolchains (i.e. a single "executable" target).
+ #
+ # This action only happens once per "ios_app_bundle" template (for the
+ # main toolchain).
+ action(_lipo_executable) {
+ forward_variables_from(invoker, [ "testonly" ])
+ visibility = _lipo_executable_visibility
+ script = "//build/config/mac/xcrun.py"
+ outputs = [
+ _executable_path,
+ ]
+ inputs = [
+ _arch_executable_path,
+ ]
+ deps = [
+ ":$_link_executable",
+ ]
+ foreach(_additional_toolchain, additional_toolchains) {
+ _additional_toolchain_target = "$_target_name($_additional_toolchain)"
+ deps += [ ":$_additional_toolchain_target" ]
+ inputs += [ get_label_info(_additional_toolchain_target,
+ "root_out_dir") + "/$_output_name" ]
+ }
+ args = [
+ "lipo",
+ "-create",
+ "-output",
+ rebase_path(outputs[0], root_build_dir),
+ ] + rebase_path(inputs, root_build_dir)
+ }
}
- if (defined(invoker.bundle_extension)) {
- _bundle_extension = invoker.bundle_extension
- } else {
- _bundle_extension = ".app"
+ if (!ios_enable_code_signing) {
+ # If codesigning is enabled, the binary will be copied into the bundle
+ # by the codesigning script (as the binary is updated by the signature).
+ # Otherwise, this "bundle_data" declares the location of the binary in
+ # the .app bundle.
+ bundle_data(_bundle_data_executable) {
+ forward_variables_from(invoker, [ "testonly" ])
+ visibility = [ ":$_target_name" ]
+ outputs = [
+ "{{bundle_executable_dir}}/$_output_name",
+ ]
+ if (_is_fat_build) {
+ public_deps = [
+ ":$_lipo_executable",
+ ]
+ } else {
+ public_deps = [
+ ":$_link_executable",
+ ]
+ }
+ sources = [
+ "$target_out_dir/$_output_name",
+ ]
+ }
}
- bundle_root_dir = "$root_out_dir/$_output_name$_bundle_extension"
- bundle_resources_dir = bundle_root_dir
- bundle_executable_dir = bundle_root_dir
- bundle_plugins_dir = "$bundle_root_dir/PlugIns"
+ create_bundle(target_name) {
+ forward_variables_from(invoker,
+ [
+ "data_deps",
+ "deps",
+ "public_deps",
+ "testonly",
+ "visibility",
+ ])
- if (defined(invoker.entitlements_path)) {
- _entitlements_path = invoker.entitlements_path
- } else {
- _entitlements_path = "$ios_sdk_path/Entitlements.plist"
- }
+ if (!defined(deps)) {
+ deps = []
+ }
+ deps += [ ":$_bundle_data_info_plist" ]
+ if (ios_enable_code_signing) {
+ if (_is_fat_build) {
+ deps += [ ":$_lipo_executable" ]
+ } else {
+ deps += [ ":$_link_executable" ]
+ }
+ } else {
+ deps += [ ":$_bundle_data_executable" ]
+ }
- if (ios_enable_code_signing) {
- code_signing_script = "//build/config/ios/codesign.py"
- code_signing_sources = [
- _entitlements_path,
- "$target_gen_dir/$_output_name",
- ]
- code_signing_outputs = [
- "$bundle_root_dir/$_output_name",
- "$bundle_root_dir/_CodeSignature/CodeResources",
- "$bundle_root_dir/embedded.mobileprovision",
- ]
- code_signing_args = [
- "-i=" + ios_code_signing_identity,
- "-b=" + rebase_path("$target_gen_dir/$_output_name", root_build_dir),
- "-e=" + rebase_path(_entitlements_path, root_build_dir),
- rebase_path(bundle_root_dir, root_build_dir),
- ]
- } else {
- assert(_entitlements_path != "",
- "force usage of _entitlements_path to avoid unused variable error")
+ if (use_ios_simulator) {
+ if (!defined(data_deps)) {
+ data_deps = []
+ }
+ data_deps += [ "//testing/iossim" ]
+ }
+
+ if (defined(invoker.product_type)) {
+ product_type = invoker.product_type
+ } else {
+ product_type = "com.apple.product-type.application"
+ }
+
+ if (defined(invoker.bundle_extension)) {
+ _bundle_extension = invoker.bundle_extension
+ } else {
+ _bundle_extension = ".app"
+ }
+
+ bundle_root_dir = "$root_out_dir/$_output_name$_bundle_extension"
+ bundle_resources_dir = bundle_root_dir
+ bundle_executable_dir = bundle_root_dir
+ bundle_plugins_dir = "$bundle_root_dir/PlugIns"
+
+ if (ios_enable_code_signing) {
+ _entitlements_path = "$ios_sdk_path/Entitlements.plist"
+ if (defined(invoker.entitlements_path)) {
+ _entitlements_path = invoker.entitlements_path
+ }
+
+ code_signing_script = "//build/config/ios/codesign.py"
+ code_signing_sources = [
+ _entitlements_path,
+ "$target_out_dir/$_output_name",
+ ]
+ code_signing_outputs = [
+ "$bundle_root_dir/$_output_name",
+ "$bundle_root_dir/_CodeSignature/CodeResources",
+ "$bundle_root_dir/embedded.mobileprovision",
+ ]
+ code_signing_args = [
+ "-i=" + ios_code_signing_identity,
+ "-b=" + rebase_path("$target_out_dir/$_output_name", root_build_dir),
+ "-e=" + rebase_path(_entitlements_path, root_build_dir),
+ rebase_path(bundle_root_dir, root_build_dir),
+ ]
+ }
}
}
+
+ # TODO(crbug.com/395883): ensure those variables are marked as used to
+ # avoid errors while running "gn gen".
+ if (defined(invoker.entitlements_path)) {
+ assert(invoker.entitlements_path != "",
+ "mark invoker.entitlements_path as used")
+ }
+ if (defined(invoker.bundle_extension)) {
+ assert(invoker.bundle_extension != "",
+ "mark invoker.bundle_extension as used")
+ }
+ if (defined(invoker.bundle_extension)) {
+ assert(invoker.bundle_extension != "",
+ "mark invoker.bundle_extension as used")
+ }
+ if (defined(invoker.entitlements_path)) {
+ assert(invoker.entitlements_path != "",
+ "mark invoker.entitlements_path as used")
+ }
+ if (defined(invoker.extra_substitutions)) {
+ assert(invoker.extra_substitutions != [],
+ "mark invoker.extra_substitutions as used")
+ }
+ if (defined(invoker.info_plist)) {
+ assert(invoker.info_plist != "", "mark invoker.info_plist as used")
+ }
+ if (defined(invoker.info_plist_target)) {
+ assert(invoker.info_plist_target != "",
+ "mark invoker.info_plist_target as used")
+ }
+ if (defined(invoker.product_type)) {
+ assert(invoker.product_type != "", "mark product_type as used")
+ }
}
# Template to build an application extension bundle for iOS.
« no previous file with comments | « build/config/ios/ios_sdk.gni ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698