bazelbuild / bazelbuild/rules_apple
ios_framework.hdrs does not use transitions
- Dominant language
- Starlark
- Stars
- 593
- Forks
- 334
- Avg merge
- 16h 48m
- Merged PRs (30d)
- 9
Description
When fetching `hdrs`, `ios_framework` and `ios_static_framework` do not use `apple_common.multiarch_split`.
This causes the headers to be fetch as default target. Which is fine and well when they are static files, but in my case they are generated by a rule that need compiled artifacts from downstream. This causes an extra invocation of that code generator to happen. This may not be a big problem but the tool fails because of wrong environment (no split at that point).
For instance, if I use `--ios_multi_cpus=arm64` then two invocation will happen on that tool instead or one.
My quick workaround was to have `hdrs` use the multi arch split and use the first split available. This works well and now my tool only runs once.
I'm wondering about the solution though, as I'm not sure I'm taking the problem in the right way or if it's upstream-able as is:
```diff
diff --git a/apple/internal/ios_rules.bzl b/apple/internal/ios_rules.bzl
index 00bb73b..0a53d0c 100644
--- a/apple/internal/ios_rules.bzl
+++ b/apple/internal/ios_rules.bzl
@@ -54,6 +54,10 @@ load(
"@build_bazel_rules_apple//apple/internal:stub_support.bzl",
"stub_support",
)
+load(
+ "@build_bazel_rules_apple//apple/internal/utils:split.bzl",
+ "split",
+)
load(
"@build_bazel_rules_apple//apple:providers.bzl",
"IosApplicationBundleInfo",
@@ -210,7 +214,7 @@ def _ios_framework_impl(ctx):
embeddable_targets = ctx.attr.frameworks,
),
partials.extension_safe_validation_partial(is_extension_safe = ctx.attr.extension_safe),
- partials.framework_headers_partial(hdrs = ctx.files.hdrs),
+ partials.framework_headers_partial(hdrs = split.files(ctx, "hdrs")),
partials.framework_provider_partial(
binary_provider = binary_target[apple_common.AppleDylibBinary],
),
@@ -310,7 +314,7 @@ def _ios_static_framework_impl(ctx):
partials.apple_bundle_info_partial(),
partials.binary_partial(binary_artifact = binary_artifact),
partials.static_framework_header_modulemap_partial(
- hdrs = ctx.files.hdrs,
+ hdrs = split.files(ctx, "hdrs"),
umbrella_header = ctx.file.umbrella_header,
binary_objc_provider = binary_target[apple_common.Objc],
),
diff --git a/apple/internal/rule_factory.bzl b/apple/internal/rule_factory.bzl
index b514ce4..7182b7f 100644
--- a/apple/internal/rule_factory.bzl
+++ b/apple/internal/rule_factory.bzl
@@ -508,6 +508,7 @@ Required.
# what to do with this.
"hdrs": attr.label_list(
allow_files = [".h"],
+ cfg = apple_common.multi_arch_split,
),
"extension_safe": attr.bool(
default = False,
@@ -521,6 +522,7 @@ use only extension-safe APIs.
attrs.append({
"hdrs": attr.label_list(
allow_files = [".h"],
+ cfg = apple_common.multi_arch_split,
doc = """
A list of `.h` files that will be publicly exposed by this framework. These headers should have
framework-relative imports, and if non-empty, an umbrella header named `%{bundle_name}.h` will also
@@ -529,6 +531,7 @@ be generated that imports all of the headers listed here.
),
"umbrella_header": attr.label(
allow_single_file = [".h"],
+ cfg = apple_common.multi_arch_split,
doc = """
An optional single .h file to use as the umbrella header for this framework. Usually, this header
will have the same name as this target, so that clients can load the header using the #import
@@ -691,6 +694,7 @@ def _get_tvos_attrs(rule_descriptor):
# what to do with this.
"hdrs": attr.label_list(
allow_files = [".h"],
+ cfg = apple_common.multi_arch_split,
),
"extension_safe": attr.bool(
default = False,
diff --git a/apple/internal/tvos_rules.bzl b/apple/internal/tvos_rules.bzl
index 1a5c803..78f1425 100644
--- a/apple/internal/tvos_rules.bzl
+++ b/apple/internal/tvos_rules.bzl
@@ -46,6 +46,10 @@ load(
"@build_bazel_rules_apple//apple/internal:run_support.bzl",
"run_support",
)
+load(
+ "@build_bazel_rules_apple//apple/internal/utils:split.bzl",
+ "split",
+)
load(
"@build_bazel_rules_apple//apple:providers.bzl",
"TvosApplicationBundleInfo",
@@ -168,7 +172,7 @@ def _tvos_framework_impl(ctx):
embeddable_targets = ctx.attr.frameworks,
),
partials.extension_safe_validation_partial(is_extension_safe = ctx.attr.extension_safe),
- partials.framework_headers_partial(hdrs = ctx.files.hdrs),
+ partials.framework_headers_partial(hdrs = split.files(ctx, "hdrs")),
partials.framework_provider_partial(binary_provider = binary_provider),
partials.resources_partial(
bundle_id = bundle_id,
diff --git a/apple/internal/utils/split.bzl b/apple/internal/utils/split.bzl
new file mode 100644
index 0000000..c6de763
--- /dev/null
+++ b/apple/internal/utils/split.bzl
@@ -0,0 +1,27 @@
+# Copyright 2017 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.
+
+"""Convenience functions for split_attr."""
+
+def _files(ctx, attr_name):
+ for attr in getattr(ctx.split_attr, attr_name).values():
+ return [
+ file
+ for target in attr
+ for file in target.files.to_list()
+ ]
+
+split = struct(
+ files = _files,
+)
```
Tested with Bazel 0.25.3
Contributor guide
Assessment
This issue has not been assessed yet.