Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ios_bundle rule #2318

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
338 changes: 335 additions & 3 deletions apple/internal/ios_rules.bzl

Large diffs are not rendered by default.

61 changes: 61 additions & 0 deletions apple/internal/partials/embedded_bundles.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,14 @@ load(
"@build_bazel_rules_apple//apple/internal:processor.bzl",
"processor",
)
load(
"@bazel_skylib//lib:new_sets.bzl",
"sets",
)
load(
"@bazel_skylib//lib:paths.bzl",
"paths",
)
load(
"@bazel_skylib//lib:partial.bzl",
"partial",
Expand Down Expand Up @@ -57,6 +65,7 @@ def _embedded_bundles_partial_impl(
"xpc_services": processor.location.xpc_service,
}

config_vars = platform_prerequisites.config_vars
transitive_bundles = dict()
bundles_to_embed = []
embeddedable_info_fields = {}
Expand Down Expand Up @@ -102,6 +111,54 @@ def _embedded_bundles_partial_impl(
input_bundles_by_type.get(bundle_type, []),
transitive = transitive_bundles.get(bundle_type, []),
)

# Process custom bundle locations
transitive_custom_bundles = dict()
for provider in embeddable_providers:
if hasattr(provider, "custom_bundles"):
custom_bundles = getattr(provider, "custom_bundles")
for bundle_location, input_bundles in custom_bundles.items():
transitive_custom_bundles.setdefault(
bundle_location,
default = [],
).append(input_bundles)

if bundle_embedded_bundles:
# If this partial is configured to embed the transitive embeddable partials, collect
# them into a list to be returned by this partial.
for bundle_location, input_bundles_array in transitive_custom_bundles.items():
transitive_depset = depset(transitive = input_bundles_array)

# With tree artifacts, we need to set the parent_dir of the file to be the basename
# of the file. Expanding these depsets shouldn't be too much work as there shouldn't
# be too many embedded targets per top-level bundle.
if is_experimental_tree_artifact_enabled(config_vars = config_vars):
for bundle in transitive_depset.to_list():
bundles_to_embed.append((
processor.location.loadable_bundle,
paths.join(bundle_location, bundle.basename),
depset([bundle])
))
else:
bundles_to_embed.append((processor.location.loadable_bundle, bundle_location, transitive_depset))

# Clear the transitive list of custom bundles since they will be packaged
# in the bundle processing this partial and do not need to be propagated.
transitive_custom_bundles = dict()

# Construct the _AppleEmbeddableInfo provider field for the bundle type being processed.
# At this step, we inject the bundles that are inputs to this partial, since that propagates
# the info for a higher level bundle to embed this bundle.
direct_custom_bundles = input_bundles_by_type.get("custom_bundles", {})
bundle_locations = sets.to_list(sets.make(direct_custom_bundles.keys() + transitive_custom_bundles.keys()))
if bundle_locations:
embeddedable_info_fields["custom_bundles"] = {
bundle_location: depset(
direct_custom_bundles.get(bundle_location, []),
transitive = transitive_custom_bundles.get(bundle_location, []),
)
for bundle_location in bundle_locations
}

# Construct the output files fields. If tree artifacts is enabled, propagate the bundles to
# package into bundle_files. Otherwise, propagate through bundle_zips so that they can be
Expand Down Expand Up @@ -148,6 +205,7 @@ def embedded_bundles_partial(
*,
app_clips = [],
bundle_embedded_bundles = False,
custom_bundles = {},
embeddable_targets = [],
extensions = [],
frameworks = [],
Expand All @@ -169,6 +227,8 @@ def embedded_bundles_partial(
bundle_embedded_bundles: If True, this target will embed all transitive embeddable_bundles
_only_ propagated through the targets given in embeddable_targets. If False, the
embeddable bundles will be propagated downstream for a top level target to bundle them.
custom_bundles: Dictionary of list of bundles that should be propagated downstream for a
top level target to bundle inside directories named by the dictionary key.
embeddable_targets: The list of targets that propagate embeddable bundles to bundle or
propagate.
extensions: List of ExtensionKit extension bundles that should be propagated downstream for
Expand All @@ -192,6 +252,7 @@ def embedded_bundles_partial(
_embedded_bundles_partial_impl,
app_clips = app_clips,
bundle_embedded_bundles = bundle_embedded_bundles,
custom_bundles = custom_bundles,
embeddable_targets = embeddable_targets,
extensions = extensions,
frameworks = frameworks,
Expand Down
2 changes: 2 additions & 0 deletions apple/internal/processor.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ _LOCATION_ENUM = struct(
content = "content",
extension = "extension",
framework = "framework",
loadable_bundle = "loadable_bundle",
plugin = "plugin",
resource = "resource",
watch = "watch",
Expand Down Expand Up @@ -205,6 +206,7 @@ def _archive_paths(
contents_path,
rule_descriptor.bundle_locations.contents_relative_frameworks,
),
_LOCATION_ENUM.loadable_bundle: contents_path,
_LOCATION_ENUM.plugin: paths.join(
contents_path,
rule_descriptor.bundle_locations.contents_relative_plugins,
Expand Down
14 changes: 14 additions & 0 deletions apple/internal/providers.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -535,6 +535,20 @@ is an iOS app clip should use this provider to describe that requirement.
init = _make_banned_init(provider_name = "IosAppClipBundleInfo"),
)

IosBundleBundleInfo, new_iosbundlebundleinfo = provider(
doc = """
Denotes that a target is an iOS loadable bundle.

This provider does not contain any fields of its own at this time but is used as
a "marker" to indicate that a target is specifically an iOS loadable bundle
(and not some other Apple bundle). Rule authors who wish to require that a
dependency is an iOS loadable bundle should use this provider to describe that
requirement.
""",
fields = {},
init = _make_banned_init(provider_name = "IosBundleBundleInfo"),
)

IosExtensionBundleInfo, new_iosextensionbundleinfo = provider(
doc = """
Denotes that a target is an iOS application extension.
Expand Down
4 changes: 4 additions & 0 deletions apple/internal/providers/embeddable_info.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ _APPLE_EMBEDDABLE_INFO_FIELDS = {
"app_clips": """
A depset with the zipped archives of bundles that need to be expanded into the
AppClips section of the packaging bundle.""",
"custom_bundles": """
A dict of depsets of zipped archives of bundles that need to be expanded into
custom locations of the packaging bundle, where the key is the path to the
custom location.""",
"extensions": """
A depset with the zipped archives of bundles that need to be expanded into the
Extensions section of the packaging bundle.""",
Expand Down
13 changes: 13 additions & 0 deletions apple/internal/rule_support.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,19 @@ _RULE_TYPE_DESCRIPTORS = {
"@executable_path/Frameworks",
],
),
# ios_bundle
apple_product_type.bundle: _describe_rule_type(
allowed_device_families = ["iphone", "ipad"],
bundle_extension = ".bundle",
bundle_package_type = bundle_package_type.bundle,
product_type = apple_product_type.bundle,
rpaths = [
# Bundle binaries are loaded from the executable location and application binaries
# live in Application.app/Application
# Frameworks are packaged in Application.app/Frameworks
"@executable_path/Frameworks",
],
),
# ios_extension (NSExtension)
apple_product_type.app_extension: _describe_rule_type(
allowed_device_families = ["iphone", "ipad"],
Expand Down
1 change: 1 addition & 0 deletions apple/internal/testing/ios_rules.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ load(
"@build_bazel_rules_apple//apple:providers.bzl",
"AppleBundleInfo",
"IosApplicationBundleInfo",
"IosBundleBundleInfo",
"IosExtensionBundleInfo",
"IosFrameworkBundleInfo",
"IosImessageApplicationBundleInfo",
Expand Down
2 changes: 2 additions & 0 deletions apple/ios.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ load(
"@build_bazel_rules_apple//apple/internal:ios_rules.bzl",
_ios_app_clip = "ios_app_clip",
_ios_application = "ios_application",
_ios_bundle = "ios_bundle",
_ios_dynamic_framework = "ios_dynamic_framework",
_ios_extension = "ios_extension",
_ios_framework = "ios_framework",
Expand All @@ -45,6 +46,7 @@ load(
# TODO(b/118104491): Remove these re-exports and move the rule definitions into this file.
ios_application = _ios_application
ios_app_clip = _ios_app_clip
ios_bundle = _ios_bundle
ios_dynamic_framework = _ios_dynamic_framework
ios_extension = _ios_extension
ios_framework = _ios_framework
Expand Down
2 changes: 2 additions & 0 deletions apple/providers.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ load(
_AppleXcframeworkBundleInfo = "AppleXcframeworkBundleInfo",
_IosAppClipBundleInfo = "IosAppClipBundleInfo",
_IosApplicationBundleInfo = "IosApplicationBundleInfo",
_IosBundleBundleInfo = "IosBundleBundleInfo",
_IosExtensionBundleInfo = "IosExtensionBundleInfo",
_IosFrameworkBundleInfo = "IosFrameworkBundleInfo",
_IosImessageApplicationBundleInfo = "IosImessageApplicationBundleInfo",
Expand Down Expand Up @@ -98,6 +99,7 @@ AppleTestInfo = _AppleTestInfo
AppleTestRunnerInfo = _AppleTestRunnerInfo
AppleXcframeworkBundleInfo = _AppleXcframeworkBundleInfo
IosAppClipBundleInfo = _IosAppClipBundleInfo
IosBundleBundleInfo = _IosBundleBundleInfo
IosApplicationBundleInfo = _IosApplicationBundleInfo
IosExtensionBundleInfo = _IosExtensionBundleInfo
IosFrameworkBundleInfo = _IosFrameworkBundleInfo
Expand Down