blob: 34d02ad502d2648186a5bcb5fa36b9666a13d55c [file] [log] [blame]
# Copyright 2017 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
declare_args() {
# Controls whether the "imageset" template sets up the build to compile
# the asset catalogs (to generate an Assets.car file). If set to false,
# instead the assets will be copied verbatim to the generated bundle.
# As loading resources from the compiled asset catalog or unpacked is
# transparent to application code, this results in faster build but in
# a larger application.
#
# This requires that resources uses scale (like "@2x", "@3x") and idiom
# (like "~ipad", "~iphone") suffixes and use the same basename as the
# imageset directory in order for the correct resource to be loaded if
# ios_compile_asset_catalogs is set to false.
#
# Note: flipping this variable requires a clobber build (as there is no
# way to specify that unknown files are deleted as part of the build).
ios_compile_asset_catalogs = true
}
# This template declares a bundle_data target that references an .imageset
# so that it is compiled to the asset catalog of the generated bundle.
#
# The create_bundle target requires that all .imageset are part of an
# .xcasset bundle. This requirement comes from actool that only receives
# the path to the .xcasset bundle directory and not to the individual
# .imageset directories.
#
# The requirement is a bit problematic as it prevents compiling only a
# subset of the .imageset that are contained in a .xcasset. This template
# fixes that by instead copying the content of the .imageset to temporary
# .xcasset directory (below $root_out_dir) and defining a bundle_data
# target that refers to those copies (this is efficient as the "copy" is
# implemented by hardlinking if possible on macOS).
#
# Since the create_data target will only refer to the .xcasset directory
# and additional "action" target that runs a dummy script is defined. It
# does nothing but pretends to generate the .xcassets directory (while
# it is really created as a side-effect of the "copy" step). This allows
# to workaround the check in "gn" that all inputs below $root_out_dir have
# to be outputs of another target with a public dependency path.
#
# This template also ensures that the file are only copied once when the
# build targets multiple architectures at the same time (aka "fat build").
#
# If ios_compile_asset_catalogs is set to false, the resources will instead
# just be copied into the final bundles (they are still copied to a temporary
# location in gen/ to avoid accidentally compiling them if they are located
# in a .xcassets directory).
#
# Arguments
#
# sources:
# required, list of strings, paths to the file contained in the
# .imageset directory; this must contain the Contents.json file
# and all the image referenced by it (not enforced by the template).
#
template("imageset") {
assert(defined(invoker.sources) && invoker.sources != [],
"sources must be defined and not empty for $target_name")
if (current_toolchain != default_toolchain) {
group(target_name) {
public_deps = [
":$target_name($default_toolchain)",
]
}
} else {
_copy_target_name = target_name + "__copy"
_fake_target_name = target_name + "__fake"
_data_target_name = target_name
_sources = invoker.sources
foreach(_source, invoker.sources) {
_dir = get_path_info(_source, "dir")
assert(get_path_info(_dir, "extension") == "imageset",
"$_source dirname must have .imageset extension")
# If the compilation of asset catalogs is disabled, the Contents.json
# file must not be copied.
if (!ios_compile_asset_catalogs) {
if (get_path_info(_source, "file") == "Contents.json") {
_sources -= [ _source ]
}
}
}
# The compilation of resources into Assets.car is enabled automatically
# by the "create_bundle" target if any of the "bundle_data" sources's
# path matches *.xcassets/{Contents.json,*.imageset/{Contents.json,*}}.
#
# Copy the file to a directory that either matches that pattern if the
# compilation of asset catalogs is enabled or not. The detection will
# be performed by gn and the correct ninja rules generated. This is the
# main difference between the two variants for this template.
if (ios_compile_asset_catalogs) {
_xcassets_dir = "$target_gen_dir/${target_name}.xcassets"
} else {
_xcassets_dir = "$target_gen_dir/${target_name}_xcassets"
}
_imageset_dir = "$_xcassets_dir/" +
get_path_info(get_path_info(_sources[0], "dir"), "file")
copy(_copy_target_name) {
# Forward "deps", "public_deps" and "testonly" in case some of the
# source files are generated.
forward_variables_from(invoker,
[
"deps",
"public_deps",
"testonly",
])
visibility = [ ":$_fake_target_name" ]
sources = _sources
outputs = [
"$_imageset_dir/{{source_file_part}}",
]
}
action(_fake_target_name) {
forward_variables_from(invoker, [ "testonly" ])
visibility = [ ":$_data_target_name" ]
script = "//build/config/ios/dummy.py"
sources = _sources
outputs = [
"$_xcassets_dir",
]
public_deps = [
":$_copy_target_name",
]
args = rebase_path(sources, root_build_dir) +
rebase_path(outputs, root_build_dir)
}
bundle_data(_data_target_name) {
forward_variables_from(invoker,
"*",
[
"deps",
"outputs",
"public_deps",
"sources",
])
sources = get_target_outputs(":$_copy_target_name")
outputs = [
"{{bundle_resources_dir}}/{{source_file_part}}",
]
public_deps = [
":$_fake_target_name",
]
}
}
}