diff --git a/apple/BUILD b/apple/BUILD
index ca64340da8..a1ab32657f 100644
--- a/apple/BUILD
+++ b/apple/BUILD
@@ -175,6 +175,7 @@ bzl_library(
"//apple/internal/resource_rules:apple_core_ml_library",
"//apple/internal/resource_rules:apple_intent_library",
"//apple/internal/resource_rules:apple_metal_library",
+ "//apple/internal/resource_rules:apple_precompiled_resource_bundle",
"//apple/internal/resource_rules:apple_resource_bundle",
"//apple/internal/resource_rules:apple_resource_group",
],
diff --git a/apple/internal/aspects/resource_aspect.bzl b/apple/internal/aspects/resource_aspect.bzl
index 73db6f31ef..cefa971ea0 100644
--- a/apple/internal/aspects/resource_aspect.bzl
+++ b/apple/internal/aspects/resource_aspect.bzl
@@ -201,6 +201,17 @@ def _apple_resource_aspect_impl(target, ctx):
process_args["bundle_id"] = ctx.rule.attr.bundle_id or None
bundle_name = "{}.bundle".format(ctx.rule.attr.bundle_name or ctx.label.name)
+ elif ctx.rule.kind == "apple_precompiled_resource_bundle":
+ # If the target already propagates a AppleResourceInfo, do nothing.
+ if AppleResourceInfo in target:
+ return []
+ default_action = apple_resource_hint_action.resources
+ collect_infoplists_args["res_attrs"] = ["infoplists"]
+ collect_args["res_attrs"] = ["resources"]
+ collect_structured_args["res_attrs"] = ["structured_resources"]
+ process_args["bundle_id"] = ctx.rule.attr.bundle_id or None
+ bundle_name = "{}.bundle".format(ctx.rule.attr.bundle_name or ctx.label.name)
+
if hint_action:
default_action = hint_action
diff --git a/apple/internal/resource_rules/BUILD b/apple/internal/resource_rules/BUILD
index 05fe91a762..89d875c318 100644
--- a/apple/internal/resource_rules/BUILD
+++ b/apple/internal/resource_rules/BUILD
@@ -100,6 +100,29 @@ bzl_library(
],
)
+bzl_library(
+ name = "apple_precompiled_resource_bundle",
+ srcs = ["apple_precompiled_resource_bundle.bzl"],
+ visibility = [
+ "//apple:__subpackages__",
+ ],
+ deps = [
+ "//apple/internal:apple_product_type",
+ "//apple/internal:apple_toolchains",
+ "//apple/internal:codesigning_support",
+ "//apple/internal:features_support",
+ "//apple/internal:partials",
+ "//apple/internal:platform_support",
+ "//apple/internal:processor",
+ "//apple/internal:providers",
+ "//apple/internal:resources",
+ "//apple/internal:rule_attrs",
+ "//apple/internal:rule_support",
+ "@bazel_skylib//lib:dicts",
+ "@bazel_skylib//lib:partial",
+ ],
+)
+
bzl_library(
name = "apple_resource_group",
srcs = ["apple_resource_group.bzl"],
diff --git a/apple/internal/resource_rules/Info.plist b/apple/internal/resource_rules/Info.plist
new file mode 100644
index 0000000000..ef2d9f5f5e
--- /dev/null
+++ b/apple/internal/resource_rules/Info.plist
@@ -0,0 +1,16 @@
+
+
+
+
+ CFBundleName
+ $(BUNDLE_NAME)
+ CFBundleVersion
+ 1
+ CFBundleShortVersionString
+ 1.0
+ CFBundleIdentifier
+ $(PRODUCT_BUNDLE_IDENTIFIER)
+ CFBundlePackageType
+ BNDL
+
+
diff --git a/apple/internal/resource_rules/apple_precompiled_resource_bundle.bzl b/apple/internal/resource_rules/apple_precompiled_resource_bundle.bzl
new file mode 100644
index 0000000000..bda6968785
--- /dev/null
+++ b/apple/internal/resource_rules/apple_precompiled_resource_bundle.bzl
@@ -0,0 +1,273 @@
+# Copyright 2024 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Implementation of apple_precompiled_resource_bundle rule."""
+
+load(
+ "@bazel_skylib//lib:dicts.bzl",
+ "dicts",
+)
+load(
+ "@bazel_skylib//lib:partial.bzl",
+ "partial",
+)
+load(
+ "@build_bazel_rules_apple//apple/internal:apple_toolchains.bzl",
+ "AppleMacToolsToolchainInfo",
+ "AppleXPlatToolsToolchainInfo",
+)
+load(
+ "@build_bazel_rules_apple//apple/internal:features_support.bzl",
+ "features_support",
+)
+load(
+ "@build_bazel_rules_apple//apple/internal:platform_support.bzl",
+ "platform_support",
+)
+load(
+ "@build_bazel_rules_apple//apple/internal:resources.bzl",
+ "resources",
+)
+load(
+ "@build_bazel_rules_apple//apple/internal:rule_attrs.bzl",
+ "rule_attrs",
+)
+load(
+ "@build_bazel_rules_apple//apple/internal:rule_support.bzl",
+ "rule_support",
+)
+load(
+ "//apple/internal:apple_product_type.bzl",
+ "apple_product_type",
+)
+
+def _apple_precompiled_resource_bundle_impl(ctx):
+ # Owner to attach to the resources as they're being bucketed.
+ owner = str(ctx.label)
+ bucketize_args = {}
+
+ rule_descriptor = rule_support.rule_descriptor(
+ platform_type = str(ctx.fragments.apple.single_arch_platform.platform_type),
+ product_type = apple_product_type.application,
+ )
+
+ features = features_support.compute_enabled_features(
+ requested_features = ctx.features,
+ unsupported_features = ctx.disabled_features,
+ )
+
+ apple_xplat_toolchain_info = ctx.attr._xplat_toolchain[AppleXPlatToolsToolchainInfo]
+
+ platform_prerequisites = platform_support.platform_prerequisites(
+ apple_fragment = ctx.fragments.apple,
+ build_settings = apple_xplat_toolchain_info.build_settings,
+ config_vars = ctx.var,
+ cpp_fragment = ctx.fragments.cpp,
+ device_families = rule_descriptor.allowed_device_families,
+ explicit_minimum_deployment_os = None,
+ explicit_minimum_os = None,
+ features = features,
+ objc_fragment = ctx.fragments.objc,
+ platform_type_string = str(ctx.fragments.apple.single_arch_platform.platform_type),
+ uses_swift = False,
+ xcode_version_config = ctx.attr._xcode_config[apple_common.XcodeVersionConfig],
+ )
+
+ bundle_name = "{}.bundle".format(ctx.attr.bundle_name or ctx.label.name)
+ bundle_id = ctx.attr.bundle_id or "com.bazel.apple_precompiled_resource_bundle_".format(ctx.attr.bundle_name or ctx.label.name)
+
+ apple_resource_infos = []
+ process_args = {
+ "actions": ctx.actions,
+ "apple_mac_toolchain_info": ctx.attr._mac_toolchain[AppleMacToolsToolchainInfo],
+ "bundle_id": bundle_id,
+ "product_type": rule_descriptor.product_type,
+ "rule_label": ctx.label,
+ }
+
+ resource_files = resources.collect(
+ attr = ctx.attr,
+ res_attrs = ["resources"],
+ )
+
+ if resource_files:
+ bucketized_owners, unowned_resources, buckets = resources.bucketize_data(
+ resources = resource_files,
+ owner = owner,
+ parent_dir_param = bundle_name,
+ **bucketize_args
+ )
+ apple_resource_infos.append(
+ resources.process_bucketized_data(
+ bucketized_owners = bucketized_owners,
+ buckets = buckets,
+ platform_prerequisites = platform_prerequisites,
+ processing_owner = owner,
+ unowned_resources = unowned_resources,
+ **process_args
+ ),
+ )
+
+ structured_files = resources.collect(
+ attr = ctx.attr,
+ res_attrs = ["structured_resources"],
+ )
+ if structured_files:
+ if bundle_name:
+ structured_parent_dir_param = partial.make(
+ resources.structured_resources_parent_dir,
+ parent_dir = bundle_name,
+ )
+ else:
+ structured_parent_dir_param = partial.make(
+ resources.structured_resources_parent_dir,
+ )
+
+ # Avoid processing PNG files that are referenced through the structured_resources
+ # attribute. This is mostly for legacy reasons and should get cleaned up in the future.
+ bucketized_owners, unowned_resources, buckets = resources.bucketize_data(
+ allowed_buckets = ["strings", "plists"],
+ owner = owner,
+ parent_dir_param = structured_parent_dir_param,
+ resources = structured_files,
+ **bucketize_args
+ )
+ apple_resource_infos.append(
+ resources.process_bucketized_data(
+ bucketized_owners = bucketized_owners,
+ buckets = buckets,
+ platform_prerequisites = platform_prerequisites,
+ processing_owner = owner,
+ unowned_resources = unowned_resources,
+ **process_args
+ ),
+ )
+
+ infoplists = resources.collect(
+ attr = ctx.attr,
+ res_attrs = ["infoplists", "_fallback_infoplist"],
+ )
+
+ if infoplists and apple_resource_infos:
+ bucketized_owners, unowned_resources, buckets = resources.bucketize_typed_data(
+ bucket_type = "infoplists",
+ owner = owner,
+ parent_dir_param = bundle_name,
+ resources = infoplists,
+ **bucketize_args
+ )
+ apple_resource_infos.append(
+ resources.process_bucketized_data(
+ bucketized_owners = bucketized_owners,
+ buckets = buckets,
+ platform_prerequisites = platform_prerequisites,
+ processing_owner = owner,
+ unowned_resources = unowned_resources,
+ **process_args
+ ),
+ )
+
+ providers = []
+ if apple_resource_infos:
+ # If any providers were collected, merge them.
+ providers.append(
+ resources.merge_providers(
+ default_owner = owner,
+ providers = apple_resource_infos,
+ ),
+ )
+
+ return providers
+
+apple_precompiled_resource_bundle = rule(
+ implementation = _apple_precompiled_resource_bundle_impl,
+ fragments = ["apple", "cpp", "objc"],
+ attrs = dicts.add(
+ {
+ "bundle_id": attr.string(
+ doc = """
+The bundle ID for this target. It will replace `$(PRODUCT_BUNDLE_IDENTIFIER)` found in the files
+from defined in the `infoplists` paramter.
+""",
+ ),
+ "bundle_name": attr.string(
+ doc = """
+The desired name of the bundle (without the `.bundle` extension). If this attribute is not set,
+then the `name` of the target will be used instead.
+""",
+ ),
+ "infoplists": attr.label_list(
+ allow_empty = True,
+ allow_files = True,
+ doc = """
+A list of `.plist` files that will be merged to form the `Info.plist` that represents the extension.
+At least one file must be specified.
+Please see [Info.plist Handling](/doc/common_info.md#infoplist-handling") for what is supported.
+
+Duplicate keys between infoplist files
+will cause an error if and only if the values conflict.
+Bazel will perform variable substitution on the Info.plist file for the following values (if they
+are strings in the top-level dict of the plist):
+
+${BUNDLE_NAME}: This target's name and bundle suffix (.bundle or .app) in the form name.suffix.
+${PRODUCT_NAME}: This target's name.
+${TARGET_NAME}: This target's name.
+The key in ${} may be suffixed with :rfc1034identifier (for example
+${PRODUCT_NAME::rfc1034identifier}) in which case Bazel will replicate Xcode's behavior and replace
+non-RFC1034-compliant characters with -.
+""",
+ ),
+ "resources": attr.label_list(
+ allow_empty = True,
+ allow_files = True,
+ doc = """
+Files to include in the resource bundle. Files that are processable resources, like .xib,
+.storyboard, .strings, .png, and others, will be processed by the Apple bundling rules that have
+those files as dependencies. Other file types that are not processed will be copied verbatim. These
+files are placed in the root of the resource bundle (e.g. `Payload/foo.app/bar.bundle/...`) in most
+cases. However, if they appear to be localized (i.e. are contained in a directory called *.lproj),
+they will be placed in a directory of the same name in the app bundle.
+
+You can also add other `apple_precompiled_resource_bundle` and `apple_bundle_import` targets into `resources`,
+and the resource bundle structures will be propagated into the final bundle.
+""",
+ ),
+ "structured_resources": attr.label_list(
+ allow_empty = True,
+ allow_files = True,
+ doc = """
+Files to include in the final resource bundle. They are not processed or compiled in any way
+besides the processing done by the rules that actually generate them. These files are placed in the
+bundle root in the same structure passed to this argument, so `["res/foo.png"]` will end up in
+`res/foo.png` inside the bundle.
+""",
+ ),
+ "_environment_plist": attr.label(
+ allow_single_file = True,
+ default = "@build_bazel_rules_apple//apple/internal:environment_plist_ios",
+ ),
+ "_fallback_infoplist": attr.label(
+ allow_single_file = True,
+ default = "@build_bazel_rules_apple//apple/internal/resource_rules:Info.plist",
+ ),
+ },
+ rule_attrs.common_tool_attrs(),
+ ),
+ doc = """
+This rule encapsulates a target which is provided to dependers as a bundle. An
+`apple_precompiled_resource_bundle`'s resources are put in a resource bundle in the top
+level Apple bundle dependent. `apple_precompiled_resource_bundle` targets need to be added to
+library targets through the `data` attribute.
+""",
+)
diff --git a/apple/resources.bzl b/apple/resources.bzl
index c927345642..17a5deb5ba 100644
--- a/apple/resources.bzl
+++ b/apple/resources.bzl
@@ -38,6 +38,10 @@ load(
"@build_bazel_rules_apple//apple/internal/resource_rules:apple_metal_library.bzl",
_apple_metal_library = "apple_metal_library",
)
+load(
+ "@build_bazel_rules_apple//apple/internal/resource_rules:apple_precompiled_resource_bundle.bzl",
+ _apple_precompiled_resource_bundle = "apple_precompiled_resource_bundle",
+)
load(
"@build_bazel_rules_apple//apple/internal/resource_rules:apple_resource_bundle.bzl",
_apple_resource_bundle = "apple_resource_bundle",
@@ -51,6 +55,7 @@ load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library")
apple_bundle_import = _apple_bundle_import
apple_intent_library = _apple_intent_library
apple_metal_library = _apple_metal_library
+apple_precompiled_resource_bundle = _apple_precompiled_resource_bundle
apple_resource_bundle = _apple_resource_bundle
apple_resource_group = _apple_resource_group
apple_core_data_model = _apple_core_data_model
diff --git a/doc/rules-resources.md b/doc/rules-resources.md
index cc648b302e..50472359cf 100644
--- a/doc/rules-resources.md
+++ b/doc/rules-resources.md
@@ -100,6 +100,33 @@ Compiles Metal shader language sources into a Metal library.
| includes | A list of header search paths. | List of strings | optional | `[]` |
+
+
+## apple_precompiled_resource_bundle
+
+
+apple_precompiled_resource_bundle(name, resources, bundle_id, bundle_name, infoplists,
+ structured_resources)
+
+
+This rule encapsulates a target which is provided to dependers as a bundle. An
+`apple_precompiled_resource_bundle`'s resources are put in a resource bundle in the top
+level Apple bundle dependent. `apple_precompiled_resource_bundle` targets need to be added to
+library targets through the `data` attribute.
+
+**ATTRIBUTES**
+
+
+| Name | Description | Type | Mandatory | Default |
+| :------------- | :------------- | :------------- | :------------- | :------------- |
+| name | A unique name for this target. | Name | required | |
+| resources | Files to include in the resource bundle. Files that are processable resources, like .xib, .storyboard, .strings, .png, and others, will be processed by the Apple bundling rules that have those files as dependencies. Other file types that are not processed will be copied verbatim. These files are placed in the root of the resource bundle (e.g. `Payload/foo.app/bar.bundle/...`) in most cases. However, if they appear to be localized (i.e. are contained in a directory called *.lproj), they will be placed in a directory of the same name in the app bundle.
You can also add other `apple_precompiled_resource_bundle` and `apple_bundle_import` targets into `resources`, and the resource bundle structures will be propagated into the final bundle. | List of labels | optional | `[]` |
+| bundle_id | The bundle ID for this target. It will replace `$(PRODUCT_BUNDLE_IDENTIFIER)` found in the files from defined in the `infoplists` paramter. | String | optional | `""` |
+| bundle_name | The desired name of the bundle (without the `.bundle` extension). If this attribute is not set, then the `name` of the target will be used instead. | String | optional | `""` |
+| infoplists | A list of `.plist` files that will be merged to form the `Info.plist` that represents the extension. At least one file must be specified. Please see [Info.plist Handling](/doc/common_info.md#infoplist-handling") for what is supported.
Duplicate keys between infoplist files will cause an error if and only if the values conflict. Bazel will perform variable substitution on the Info.plist file for the following values (if they are strings in the top-level dict of the plist):
${BUNDLE_NAME}: This target's name and bundle suffix (.bundle or .app) in the form name.suffix. ${PRODUCT_NAME}: This target's name. ${TARGET_NAME}: This target's name. The key in ${} may be suffixed with :rfc1034identifier (for example ${PRODUCT_NAME::rfc1034identifier}) in which case Bazel will replicate Xcode's behavior and replace non-RFC1034-compliant characters with -. | List of labels | optional | `[]` |
+| structured_resources | Files to include in the final resource bundle. They are not processed or compiled in any way besides the processing done by the rules that actually generate them. These files are placed in the bundle root in the same structure passed to this argument, so `["res/foo.png"]` will end up in `res/foo.png` inside the bundle. | List of labels | optional | `[]` |
+
+
## apple_resource_bundle
diff --git a/test/starlark_tests/ios_application_resources_test.bzl b/test/starlark_tests/ios_application_resources_test.bzl
index 1e8eef0cf9..2ec629bcf8 100644
--- a/test/starlark_tests/ios_application_resources_test.bzl
+++ b/test/starlark_tests/ios_application_resources_test.bzl
@@ -115,6 +115,19 @@ def ios_application_resources_test_suite(name):
tags = [name],
)
+ analysis_failure_message_test(
+ name = "{}_precompiled_resource_bundle_invalid_resources_in_structured_resources".format(name),
+ target_under_test = "//test/starlark_tests/targets_under_test/ios:app_with_precompiled_resource_bundle_processed_resources_in_structured_resources",
+ expected_error = (
+ "Error: Found ignored resource providers for target {target}. Check " +
+ "that there are no processed resource targets being referenced by " +
+ "structured_resources."
+ ).format(
+ target = Label("//test/starlark_tests/resources:precompiled_processed_resources_in_structured_resources"),
+ ),
+ tags = [name],
+ )
+
# Tests that various localized resource types are bundled correctly with the
# application (preserving their parent .lproj directory).
archive_contents_test(
@@ -232,6 +245,21 @@ app_icons was assigned the following: [
tags = [name],
)
+ archive_contents_test(
+ name = "{}_precompiled_resource_bundle_apple_bundle_test".format(name),
+ build_type = "device",
+ compilation_mode = "opt",
+ is_binary_plist = [
+ "$BUNDLE_ROOT/basic.bundle/should_be_binary.strings",
+ "$BUNDLE_ROOT/basic.bundle/should_be_binary.plist",
+ ],
+ contains = [
+ "$BUNDLE_ROOT/basic.bundle/nested/should_be_nested.strings",
+ ],
+ target_under_test = "//test/starlark_tests/targets_under_test/ios:app_precompiled_resource_bundle",
+ tags = [name],
+ )
+
# Tests that apple_bundle_import files are bundled correctly with the
# application if the files have an owner-relative path that begins with
# something other than the bundle name (for example, "foo/Bar.bundle/..."
@@ -255,6 +283,24 @@ app_icons was assigned the following: [
tags = [name],
)
+ archive_contents_test(
+ name = "{}_precompiled_resource_bundle_nested_apple_bundle_test".format(name),
+ build_type = "simulator",
+ compilation_mode = "opt",
+ is_binary_plist = [
+ "$BUNDLE_ROOT/nested.bundle/should_be_binary.strings",
+ ],
+ contains = [
+ "$BUNDLE_ROOT/nested.bundle/nested/should_be_nested.strings",
+ ],
+ not_contains = [
+ "$BUNDLE_ROOT/nested_bundle/nested.bundle/should_be_binary.strings",
+ "$BUNDLE_ROOT/nested_bundle/nested.bundle/nested/should_be_nested.strings",
+ ],
+ target_under_test = "//test/starlark_tests/targets_under_test/ios:app_precompiled_resource_bundle",
+ tags = [name],
+ )
+
# Tests that apple_resource_bundle resources are compiled and bundled correctly
# with the application. This test uses a bundle library with many types of
# resources, both localized and nonlocalized, and also a nested bundle.
@@ -295,6 +341,46 @@ app_icons was assigned the following: [
tags = [name],
)
+ # Tests that apple_precompiled_resource_bundle resources are compiled and bundled correctly
+ # with the application. This test uses a bundle library with many types of
+ # resources, both localized and nonlocalized, and also a nested bundle.
+ archive_contents_test(
+ name = "{}_apple_precompiled_resource_bundle_test".format(name),
+ build_type = "device",
+ compilation_mode = "opt",
+ plist_test_file = "$CONTENT_ROOT/bundle_library_ios.bundle/Info.plist",
+ plist_test_values = {
+ "CFBundleIdentifier": "org.bazel.bundle-library-ios",
+ "CFBundleName": "bundle_library_ios.bundle",
+ "CFBundlePackageType": "BNDL",
+ "TargetName": "bundle_library_ios",
+ },
+ contains = [
+ "$BUNDLE_ROOT/bundle_library_ios.bundle/basic.bundle/basic_bundle.txt",
+ "$BUNDLE_ROOT/bundle_library_ios.bundle/default.metallib",
+ "$BUNDLE_ROOT/bundle_library_ios.bundle/it.lproj/localized.strings",
+ "$BUNDLE_ROOT/bundle_library_ios.bundle/it.lproj/localized.txt",
+ "$BUNDLE_ROOT/bundle_library_ios.bundle/it.lproj/storyboard_ios.storyboardc/",
+ "$BUNDLE_ROOT/bundle_library_ios.bundle/it.lproj/view_ios.nib",
+ "$BUNDLE_ROOT/bundle_library_ios.bundle/mapping_model.cdm",
+ "$BUNDLE_ROOT/bundle_library_ios.bundle/nonlocalized_resource.txt",
+ "$BUNDLE_ROOT/bundle_library_ios.bundle/storyboard_ios.storyboardc/",
+ "$BUNDLE_ROOT/bundle_library_ios.bundle/unversioned_datamodel.mom",
+ "$BUNDLE_ROOT/bundle_library_ios.bundle/versioned_datamodel.momd/v1.mom",
+ "$BUNDLE_ROOT/bundle_library_ios.bundle/versioned_datamodel.momd/v2.mom",
+ "$BUNDLE_ROOT/bundle_library_ios.bundle/versioned_datamodel.momd/VersionInfo.plist",
+ "$BUNDLE_ROOT/bundle_library_ios.bundle/view_ios.nib",
+ "$BUNDLE_ROOT/bundle_library_ios.bundle/structured/nested.txt",
+ ],
+ is_binary_plist = [
+ "$BUNDLE_ROOT/bundle_library_ios.bundle/structured/generated.strings",
+ "$BUNDLE_ROOT/bundle_library_ios.bundle/structured/should_be_binary.plist",
+ "$BUNDLE_ROOT/bundle_library_ios.bundle/structured/should_be_binary.strings",
+ ],
+ target_under_test = "//test/starlark_tests/targets_under_test/ios:app_precompiled_resource_bundle",
+ tags = [name],
+ )
+
# Tests that apple_resource_bundle resources are compiled and bundled correctly
# with the application. This test uses a bundle library with many types of
# resources, both localized and nonlocalized, and also a nested bundle.
@@ -308,9 +394,22 @@ app_icons was assigned the following: [
tags = [name],
)
+ # Tests that apple_precompiled_resource_bundle resources are compiled and bundled correctly
+ # with the application. This test uses a bundle library with many types of
+ # resources, both localized and nonlocalized, and also a nested bundle.
+ archive_contents_test(
+ name = "{}_apple_precompiled_resource_bundle_depending_on_AppleResourceInfo_and_DefaultInfo_rule_test".format(name),
+ build_type = "simulator",
+ contains = [
+ "$BUNDLE_ROOT/precompiled_resource_bundle.bundle/custom_apple_resource_info.out",
+ ],
+ target_under_test = "//test/starlark_tests/targets_under_test/ios:app_precompiled_resource_bundle",
+ tags = [name],
+ )
+
# Tests that structured processed generated strings have correct values.
archive_contents_test(
- name = "{}_generated_stromgs_test".format(name),
+ name = "{}_generated_strings_test".format(name),
build_type = "simulator",
plist_test_file = "$CONTENT_ROOT/bundle_library_ios.bundle/structured/generated.strings",
plist_test_values = {
@@ -320,6 +419,18 @@ app_icons was assigned the following: [
tags = [name],
)
+ # Tests that structured processed generated strings have correct values.
+ archive_contents_test(
+ name = "{}_precompiled_resource_bundle_generated_strings_test".format(name),
+ build_type = "simulator",
+ plist_test_file = "$CONTENT_ROOT/bundle_library_ios.bundle/structured/generated.strings",
+ plist_test_values = {
+ "generated_structured_string": "I like turtles too!",
+ },
+ target_under_test = "//test/starlark_tests/targets_under_test/ios:app_precompiled_resource_bundle",
+ tags = [name],
+ )
+
# Tests that the Settings.bundle is bundled correctly with the application.
archive_contents_test(
name = "{}_settings_bundle_test".format(name),
@@ -626,6 +737,17 @@ app_icons was assigned the following: [
tags = [name],
)
+ archive_contents_test(
+ name = "{}_with_precompiled_resource_bundle_with_structured_resource_group_test".format(name),
+ build_type = "device",
+ compilation_mode = "opt",
+ target_under_test = "//test/starlark_tests/targets_under_test/ios:app_with_precompiled_resource_bundle_with_structured_resource_group",
+ contains = [
+ "$BUNDLE_ROOT/precompiled_resource_bundle_with_structured_resource_group.bundle/Another.plist",
+ ],
+ tags = [name],
+ )
+
archive_contents_test(
name = "{}_with_resource_bundle_with_bundle_id".format(name),
build_type = "device",
@@ -641,6 +763,67 @@ app_icons was assigned the following: [
tags = [name],
)
+ archive_contents_test(
+ name = "{}_with_precompiled_resource_bundle_with_bundle_id".format(name),
+ build_type = "device",
+ compilation_mode = "opt",
+ target_under_test = "//test/starlark_tests/targets_under_test/ios:app_with_precompiled_resource_bundle_with_bundle_id",
+ contains = [
+ "$BUNDLE_ROOT/precompiled_resource_bundle_with_bundle_id.bundle/Info.plist",
+ "$BUNDLE_ROOT/precompiled_resource_bundle_with_bundle_id.bundle/en.lproj/files.stringsdict",
+ "$BUNDLE_ROOT/precompiled_resource_bundle_with_bundle_id.bundle/en.lproj/greetings.strings",
+ ],
+ not_contains = [
+ "$BUNDLE_ROOT/en.lproj/files.stringsdict",
+ "$BUNDLE_ROOT/en.lproj/greetings.strings",
+ ],
+ plist_test_file = "$BUNDLE_ROOT/precompiled_resource_bundle_with_bundle_id.bundle/Info.plist",
+ plist_test_values = {
+ "CFBundleIdentifier": "org.bazel.rules_apple.precompiled_resource_bundle",
+ },
+ tags = [name],
+ )
+
+ archive_contents_test(
+ name = "{}_with_precompiled_resource_bundle_with_bundle_id_no_infoplist".format(name),
+ build_type = "device",
+ compilation_mode = "opt",
+ target_under_test = "//test/starlark_tests/targets_under_test/ios:app_with_precompiled_resource_bundle_with_bundle_id_no_infoplist",
+ contains = [
+ "$BUNDLE_ROOT/precompiled_resource_bundle_with_bundle_id_no_infoplist.bundle/Info.plist",
+ "$BUNDLE_ROOT/precompiled_resource_bundle_with_bundle_id_no_infoplist.bundle/en.lproj/files.stringsdict",
+ "$BUNDLE_ROOT/precompiled_resource_bundle_with_bundle_id_no_infoplist.bundle/en.lproj/greetings.strings",
+ ],
+ not_contains = [
+ "$BUNDLE_ROOT/en.lproj/files.stringsdict",
+ "$BUNDLE_ROOT/en.lproj/greetings.strings",
+ ],
+ plist_test_file = "$BUNDLE_ROOT/precompiled_resource_bundle_with_bundle_id_no_infoplist.bundle/Info.plist",
+ plist_test_values = {
+ "CFBundleIdentifier": "org.bazel.rules_apple.precompiled_resource_bundle",
+ },
+ tags = [name],
+ )
+
+ archive_contents_test(
+ name = "{}_with_transitive_precompiled_resource_bundle_with_bundle_id".format(name),
+ build_type = "device",
+ compilation_mode = "opt",
+ target_under_test = "//test/starlark_tests/targets_under_test/ios:app_with_transitive_precompiled_resource_bundle_with_bundle_id",
+ contains = [
+ "$BUNDLE_ROOT/simple_precompiled_bundle_library.bundle/Info.plist",
+ "$BUNDLE_ROOT/simple_precompiled_bundle_library.bundle/it.lproj/localized.strings",
+ ],
+ not_contains = [
+ "$BUNDLE_ROOT/it.lproj/localized.strings",
+ ],
+ plist_test_file = "$BUNDLE_ROOT/simple_precompiled_bundle_library.bundle/Info.plist",
+ plist_test_values = {
+ "CFBundleIdentifier": "org.bazel.simple-precompiled-bundle-library",
+ },
+ tags = [name],
+ )
+
archive_contents_test(
name = "{}_with_resource_group_with_resource_bundle".format(name),
build_type = "device",
diff --git a/test/starlark_tests/resources/BUILD b/test/starlark_tests/resources/BUILD
index dca76ca038..e7c83733bd 100644
--- a/test/starlark_tests/resources/BUILD
+++ b/test/starlark_tests/resources/BUILD
@@ -5,6 +5,7 @@ load(
load(
"//apple:resources.bzl",
"apple_bundle_import",
+ "apple_precompiled_resource_bundle",
"apple_resource_bundle",
"apple_resource_group",
)
@@ -171,6 +172,17 @@ objc_library(
],
)
+objc_library(
+ name = "objc_shared_lib_with_precompiled_resource_bundles",
+ srcs = [
+ "shared.h",
+ "shared.m",
+ ],
+ data = [
+ "//test/testdata/resources:simple_precompiled_bundle_library",
+ ],
+)
+
# --------------------------------------------------------------------------------
# Objective-C main.m libraries
@@ -206,6 +218,15 @@ objc_library(
],
)
+objc_library(
+ name = "objc_main_lib_with_transitive_precompiled_resource_bundles",
+ srcs = ["main.m"],
+ tags = common.fixture_tags,
+ deps = [
+ ":objc_shared_lib_with_precompiled_resource_bundles",
+ ],
+)
+
swift_library(
name = "swift_main_lib",
srcs = ["//test/testdata/sources:main.swift"],
@@ -372,12 +393,26 @@ apple_resource_bundle(
tags = common.fixture_tags,
)
+apple_precompiled_resource_bundle(
+ name = "precompiled_resource_bundle",
+ bundle_id = "org.bazel.rules_apple.precompiled_resource_bundle",
+ infoplists = ["Another.plist"],
+ resources = [":custom_apple_resource_info"],
+ tags = common.fixture_tags,
+)
+
apple_resource_bundle(
name = "resource_bundle_with_structured_resource_group",
resources = [":structured_resources"],
tags = common.fixture_tags,
)
+apple_precompiled_resource_bundle(
+ name = "precompiled_resource_bundle_with_structured_resource_group",
+ resources = [":structured_resources"],
+ tags = common.fixture_tags,
+)
+
apple_resource_bundle(
name = "resource_bundle_with_bundle_id",
bundle_id = "org.bazel.rules_apple.resource_bundle",
@@ -389,6 +424,27 @@ apple_resource_bundle(
tags = common.fixture_tags,
)
+apple_precompiled_resource_bundle(
+ name = "precompiled_resource_bundle_with_bundle_id",
+ bundle_id = "org.bazel.rules_apple.precompiled_resource_bundle",
+ infoplists = ["Info-noversion.plist"],
+ resources = [
+ "en.lproj/files.stringsdict",
+ "en.lproj/greetings.strings",
+ ],
+ tags = common.fixture_tags,
+)
+
+apple_precompiled_resource_bundle(
+ name = "precompiled_resource_bundle_with_bundle_id_no_infoplist",
+ bundle_id = "org.bazel.rules_apple.precompiled_resource_bundle",
+ resources = [
+ "en.lproj/files.stringsdict",
+ "en.lproj/greetings.strings",
+ ],
+ tags = common.fixture_tags,
+)
+
apple_resource_bundle(
name = "localization",
resources = [
@@ -398,6 +454,15 @@ apple_resource_bundle(
tags = common.fixture_tags,
)
+apple_precompiled_resource_bundle(
+ name = "precompiled_resource_bundle_localization",
+ resources = [
+ "en.lproj/files.stringsdict",
+ "en.lproj/greetings.strings",
+ ],
+ tags = common.fixture_tags,
+)
+
filegroup(
name = "example_filegroup",
srcs = [
@@ -465,6 +530,20 @@ objc_library(
],
)
+apple_resource_group(
+ name = "precompiled_processed_resources_in_structured_resources",
+ structured_resources = [
+ ":precompiled_resource_bundle_localization",
+ ],
+)
+
+objc_library(
+ name = "precompiled_resource_bundle_processed_resources_in_structured_resources_lib",
+ data = [
+ ":precompiled_processed_resources_in_structured_resources",
+ ],
+)
+
filegroup(
name = "localized_plists",
srcs = glob(["*.lproj/*.plist"]),
diff --git a/test/starlark_tests/resources/Info-noversion.plist b/test/starlark_tests/resources/Info-noversion.plist
index 5cd1050e14..51ae42569f 100644
--- a/test/starlark_tests/resources/Info-noversion.plist
+++ b/test/starlark_tests/resources/Info-noversion.plist
@@ -3,7 +3,7 @@
CFBundleName
- $(PRODUCT_NAME)
+ $(BUNDLE_NAME)
CFBundleIdentifier
$(PRODUCT_BUNDLE_IDENTIFIER)
diff --git a/test/starlark_tests/targets_under_test/ios/BUILD b/test/starlark_tests/targets_under_test/ios/BUILD
index f3688d3b81..aa1198635c 100644
--- a/test/starlark_tests/targets_under_test/ios/BUILD
+++ b/test/starlark_tests/targets_under_test/ios/BUILD
@@ -158,6 +158,42 @@ ios_application(
],
)
+ios_application(
+ name = "app_precompiled_resource_bundle",
+ app_icons = ["//test/starlark_tests/resources:app_icons_ios"],
+ bundle_id = "com.google.example",
+ entitlements = "//test/starlark_tests/resources:entitlements.plist",
+ families = ["iphone"],
+ infoplists = [
+ "//test/starlark_tests/resources:Info.plist",
+ ],
+ launch_storyboard = "//test/starlark_tests/resources:launch_screen_ios.storyboard",
+ minimum_os_version = common.min_os_ios.baseline,
+ provisioning_profile = "//test/testdata/provisioning:integration_testing_ios.mobileprovision",
+ resources = [
+ "//test/starlark_tests/resources:example_filegroup",
+ "//test/starlark_tests/resources:localization",
+ "//test/starlark_tests/resources:precompiled_resource_bundle",
+ ],
+ settings_bundle = "//test/starlark_tests/resources:settings_bundle_ios",
+ tags = common.fixture_tags,
+ visibility = [
+ "//test/starlark_tests:__subpackages__",
+ "//tools/dossier_codesigningtool:__pkg__",
+ ],
+ deps = [
+ "//test/starlark_tests/resources:basic_bundle_lib",
+ "//test/starlark_tests/resources:bundle_library_ios_lib",
+ "//test/starlark_tests/resources:empty_strings_file_lib",
+ "//test/starlark_tests/resources:ios_localized_assets_lib",
+ "//test/starlark_tests/resources:ios_non_localized_assets_lib",
+ "//test/starlark_tests/resources:nested_bundle_lib",
+ "//test/starlark_tests/resources:objc_linkopt_lib",
+ "//test/starlark_tests/resources:objc_main_lib",
+ "//test/starlark_tests/resources:sticker_pack_ios_lib",
+ ],
+)
+
ios_application(
name = "app_multiple_infoplists",
bundle_id = "com.google.example",
@@ -247,6 +283,27 @@ ios_application(
],
)
+ios_application(
+ name = "app_with_precompiled_resource_bundle_processed_resources_in_structured_resources",
+ bundle_id = "com.google.example",
+ families = [
+ "iphone",
+ "ipad",
+ ],
+ infoplists = [
+ "//test/starlark_tests/resources:Info.plist",
+ ],
+ minimum_os_version = common.min_os_ios.baseline,
+ provisioning_profile = "//test/testdata/provisioning:integration_testing_ios.mobileprovision",
+ tags = [
+ "manual",
+ "notap",
+ ],
+ deps = [
+ "//test/starlark_tests/resources:precompiled_resource_bundle_processed_resources_in_structured_resources_lib",
+ ],
+)
+
ios_application(
name = "app_launch_images",
app_icons = ["//test/starlark_tests/resources:app_icons_ios"],
@@ -1026,6 +1083,22 @@ ios_application(
],
)
+ios_application(
+ name = "app_with_precompiled_resource_bundle_with_structured_resource_group",
+ bundle_id = "com.google.example",
+ families = ["iphone"],
+ infoplists = [
+ "//test/starlark_tests/resources:Info.plist",
+ ],
+ minimum_os_version = common.min_os_ios.baseline,
+ provisioning_profile = "//test/testdata/provisioning:integration_testing_ios.mobileprovision",
+ resources = ["//test/starlark_tests/resources:precompiled_resource_bundle_with_structured_resource_group"],
+ tags = common.fixture_tags,
+ deps = [
+ "//test/starlark_tests/resources:objc_main_lib",
+ ],
+)
+
ios_application(
name = "app_with_resource_bundle_with_bundle_id",
bundle_id = "com.google.example",
@@ -1042,6 +1115,53 @@ ios_application(
],
)
+ios_application(
+ name = "app_with_precompiled_resource_bundle_with_bundle_id",
+ bundle_id = "com.google.example",
+ families = ["iphone"],
+ infoplists = [
+ "//test/starlark_tests/resources:Info.plist",
+ ],
+ minimum_os_version = common.min_os_ios.baseline,
+ provisioning_profile = "//test/testdata/provisioning:integration_testing_ios.mobileprovision",
+ resources = ["//test/starlark_tests/resources:precompiled_resource_bundle_with_bundle_id"],
+ tags = common.fixture_tags,
+ deps = [
+ "//test/starlark_tests/resources:objc_main_lib",
+ ],
+)
+
+ios_application(
+ name = "app_with_precompiled_resource_bundle_with_bundle_id_no_infoplist",
+ bundle_id = "com.google.example",
+ families = ["iphone"],
+ infoplists = [
+ "//test/starlark_tests/resources:Info.plist",
+ ],
+ minimum_os_version = common.min_os_ios.baseline,
+ provisioning_profile = "//test/testdata/provisioning:integration_testing_ios.mobileprovision",
+ resources = ["//test/starlark_tests/resources:precompiled_resource_bundle_with_bundle_id_no_infoplist"],
+ tags = common.fixture_tags,
+ deps = [
+ "//test/starlark_tests/resources:objc_main_lib",
+ ],
+)
+
+ios_application(
+ name = "app_with_transitive_precompiled_resource_bundle_with_bundle_id",
+ bundle_id = "com.google.example",
+ families = ["iphone"],
+ infoplists = [
+ "//test/starlark_tests/resources:Info.plist",
+ ],
+ minimum_os_version = common.min_os_ios.baseline,
+ provisioning_profile = "//test/testdata/provisioning:integration_testing_ios.mobileprovision",
+ tags = common.fixture_tags,
+ deps = [
+ "//test/starlark_tests/resources:objc_main_lib_with_transitive_precompiled_resource_bundles",
+ ],
+)
+
ios_application(
name = "app_with_resource_group_with_resource_bundle",
bundle_id = "com.google.example",
diff --git a/test/testdata/resources/BUILD b/test/testdata/resources/BUILD
index a06fb021da..6a02acdb22 100644
--- a/test/testdata/resources/BUILD
+++ b/test/testdata/resources/BUILD
@@ -1,6 +1,7 @@
load(
"//apple:resources.bzl",
"apple_bundle_import",
+ "apple_precompiled_resource_bundle",
"apple_resource_bundle",
)
@@ -242,6 +243,30 @@ apple_resource_bundle(
],
)
+apple_precompiled_resource_bundle(
+ name = "simple_precompiled_bundle_library",
+ bundle_id = "org.bazel.simple-precompiled-bundle-library",
+ bundle_name = "simple_precompiled_bundle_library",
+ infoplists = [
+ "Info-template.plist",
+ ],
+ resources = [
+ "generated.strings",
+ "nonlocalized.plist",
+ "nonlocalized.strings",
+ "nonlocalized_resource.txt",
+ "sample.png",
+ ":basic_bundle",
+ ":localized_generic_resources",
+ ":localized_plists",
+ ":localized_strings",
+ ],
+ structured_resources = [
+ ":generate_structured_strings",
+ ":structured",
+ ],
+)
+
filegroup(
name = "launch_images_ios",
srcs = glob(["launch_images_ios.xcassets/**"]),