Skip to content

Commit 0bdc8f5

Browse files
committed
Adds ios_dylib rule
1 parent 14a8b6c commit 0bdc8f5

File tree

8 files changed

+339
-0
lines changed

8 files changed

+339
-0
lines changed

apple/internal/ios_rules.bzl

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ load("@build_bazel_rules_swift//swift:swift.bzl", "SwiftInfo")
2020
load(
2121
"//apple:providers.bzl",
2222
"AppleBundleInfo",
23+
"AppleBundleVersionInfo",
2324
"AppleFrameworkImportInfo",
2425
"ApplePlatformInfo",
2526
"IosAppClipBundleInfo",
@@ -86,6 +87,7 @@ load(
8687
load(
8788
"//apple/internal:providers.bzl",
8889
"merge_apple_framework_import_info",
90+
"new_applebinaryinfo",
8991
"new_appleexecutablebinaryinfo",
9092
"new_appleframeworkbundleinfo",
9193
"new_iosappclipbundleinfo",
@@ -1438,6 +1440,125 @@ def _ios_extension_impl(ctx):
14381440
link_result.debug_outputs_provider,
14391441
] + processor_result.providers
14401442

1443+
def _ios_dylib_impl(ctx):
1444+
"""Implementation of the ios_dylib rule."""
1445+
rule_descriptor = rule_support.rule_descriptor(
1446+
platform_type = ctx.attr.platform_type,
1447+
product_type = apple_product_type.dylib,
1448+
)
1449+
1450+
actions = ctx.actions
1451+
apple_mac_toolchain_info = ctx.attr._mac_toolchain[AppleMacToolsToolchainInfo]
1452+
apple_xplat_toolchain_info = ctx.attr._xplat_toolchain[AppleXPlatToolsToolchainInfo]
1453+
1454+
bundle_name, bundle_extension = bundling_support.bundle_full_name(
1455+
custom_bundle_name = None, # ios_dylib doesn't support this override.
1456+
label_name = ctx.label.name,
1457+
rule_descriptor = rule_descriptor,
1458+
)
1459+
cc_toolchain_forwarder = ctx.split_attr._cc_toolchain_forwarder
1460+
features = features_support.compute_enabled_features(
1461+
requested_features = ctx.features,
1462+
unsupported_features = ctx.disabled_features,
1463+
)
1464+
label = ctx.label
1465+
platform_prerequisites = platform_support.platform_prerequisites(
1466+
apple_fragment = ctx.fragments.apple,
1467+
build_settings = apple_xplat_toolchain_info.build_settings,
1468+
config_vars = ctx.var,
1469+
cpp_fragment = ctx.fragments.cpp,
1470+
device_families = rule_descriptor.allowed_device_families,
1471+
explicit_minimum_deployment_os = ctx.attr.minimum_deployment_os_version,
1472+
explicit_minimum_os = ctx.attr.minimum_os_version,
1473+
features = features,
1474+
objc_fragment = ctx.fragments.objc,
1475+
platform_type_string = ctx.attr.platform_type,
1476+
uses_swift = swift_support.uses_swift(ctx.attr.deps),
1477+
xcode_version_config = ctx.attr._xcode_config[apple_common.XcodeVersionConfig],
1478+
)
1479+
predeclared_outputs = ctx.outputs
1480+
provisioning_profile = ctx.file.provisioning_profile
1481+
1482+
link_result = linking_support.register_binary_linking_action(
1483+
ctx,
1484+
cc_toolchains = cc_toolchain_forwarder,
1485+
# dylibs do not have entitlements.
1486+
entitlements = None,
1487+
exported_symbols_lists = ctx.files.exported_symbols_lists,
1488+
extra_linkopts = ["-dynamiclib"],
1489+
platform_prerequisites = platform_prerequisites,
1490+
rule_descriptor = rule_descriptor,
1491+
stamp = ctx.attr.stamp,
1492+
)
1493+
binary_artifact = link_result.binary
1494+
debug_outputs = linking_support.debug_outputs_by_architecture(link_result.outputs)
1495+
1496+
debug_outputs_partial = partials.debug_symbols_partial(
1497+
actions = actions,
1498+
bundle_extension = bundle_extension,
1499+
bundle_name = bundle_name,
1500+
dsym_binaries = debug_outputs.dsym_binaries,
1501+
dsym_info_plist_template = apple_mac_toolchain_info.dsym_info_plist_template,
1502+
label_name = label.name,
1503+
linkmaps = debug_outputs.linkmaps,
1504+
platform_prerequisites = platform_prerequisites,
1505+
plisttool = apple_mac_toolchain_info.plisttool,
1506+
rule_label = label,
1507+
version = ctx.attr.version,
1508+
)
1509+
1510+
processor_result = processor.process(
1511+
actions = actions,
1512+
apple_mac_toolchain_info = apple_mac_toolchain_info,
1513+
apple_xplat_toolchain_info = apple_xplat_toolchain_info,
1514+
bundle_extension = bundle_extension,
1515+
bundle_name = bundle_name,
1516+
bundle_post_process_and_sign = False,
1517+
codesign_inputs = ctx.files.codesign_inputs,
1518+
codesignopts = codesigning_support.codesignopts_from_rule_ctx(ctx),
1519+
features = features,
1520+
ipa_post_processor = None,
1521+
partials = [debug_outputs_partial],
1522+
platform_prerequisites = platform_prerequisites,
1523+
predeclared_outputs = predeclared_outputs,
1524+
process_and_sign_template = apple_mac_toolchain_info.process_and_sign_template,
1525+
provisioning_profile = provisioning_profile,
1526+
rule_descriptor = rule_descriptor,
1527+
rule_label = label,
1528+
)
1529+
output_file = actions.declare_file(label.name + ".dylib")
1530+
codesigning_support.sign_binary_action(
1531+
actions = actions,
1532+
codesign_inputs = ctx.files.codesign_inputs,
1533+
codesigningtool = apple_mac_toolchain_info.codesigningtool,
1534+
codesignopts = codesigning_support.codesignopts_from_rule_ctx(ctx),
1535+
input_binary = binary_artifact,
1536+
output_binary = output_file,
1537+
platform_prerequisites = platform_prerequisites,
1538+
provisioning_profile = provisioning_profile,
1539+
rule_descriptor = rule_descriptor,
1540+
)
1541+
1542+
return [
1543+
new_applebinaryinfo(
1544+
binary = output_file,
1545+
product_type = rule_descriptor.product_type,
1546+
),
1547+
DefaultInfo(files = depset(transitive = [
1548+
depset([output_file]),
1549+
processor_result.output_files,
1550+
])),
1551+
OutputGroupInfo(
1552+
**outputs.merge_output_groups(
1553+
link_result.output_groups,
1554+
processor_result.output_groups,
1555+
{"dylib": depset(direct = [output_file])},
1556+
)
1557+
),
1558+
# TODO(b/228856372): Remove when downstream users are migrated off this provider.
1559+
link_result.debug_outputs_provider,
1560+
] + processor_result.providers
1561+
14411562
def _ios_dynamic_framework_impl(ctx):
14421563
"""Experimental implementation of ios_dynamic_framework."""
14431564
rule_descriptor = rule_support.rule_descriptor(
@@ -2881,6 +3002,44 @@ use only extension-safe APIs.
28813002
],
28823003
)
28833004

3005+
ios_dylib = rule_factory.create_apple_rule(
3006+
doc = "Builds a iOS Dylib binary.",
3007+
implementation = _ios_dylib_impl,
3008+
attrs = [
3009+
rule_attrs.binary_linking_attrs(
3010+
deps_cfg = transition_support.apple_platform_split_transition,
3011+
extra_deps_aspects = [
3012+
apple_resource_aspect,
3013+
framework_provider_aspect,
3014+
],
3015+
is_test_supporting_rule = False,
3016+
requires_legacy_cc_toolchain = True,
3017+
),
3018+
rule_attrs.common_tool_attrs(),
3019+
rule_attrs.device_family_attrs(
3020+
allowed_families = rule_attrs.defaults.allowed_families.ios,
3021+
),
3022+
rule_attrs.custom_transition_allowlist_attr(),
3023+
rule_attrs.platform_attrs(
3024+
add_environment_plist = True,
3025+
platform_type = "ios",
3026+
),
3027+
rule_attrs.signing_attrs(
3028+
supports_capabilities = False,
3029+
profile_extension = ".provisionprofile",
3030+
),
3031+
{
3032+
"version": attr.label(
3033+
providers = [[AppleBundleVersionInfo]],
3034+
doc = """
3035+
An `apple_bundle_version` target that represents the version for this target. See
3036+
[`apple_bundle_version`](https://github.com/bazelbuild/rules_apple/blob/master/doc/rules-general.md?cl=head#apple_bundle_version).
3037+
""",
3038+
),
3039+
},
3040+
],
3041+
)
3042+
28843043
ios_dynamic_framework = rule_factory.create_apple_rule(
28853044
doc = "Builds and bundles an iOS dynamic framework that is consumable by Xcode.",
28863045
implementation = _ios_dynamic_framework_impl,

apple/internal/rule_support.bzl

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,12 @@ _RULE_TYPE_DESCRIPTORS = {
176176
"@executable_path/Frameworks",
177177
],
178178
),
179+
apple_product_type.dylib: _describe_rule_type(
180+
allowed_device_families = ["iphone", "ipad"],
181+
bundle_extension = "",
182+
product_type = apple_product_type.dylib,
183+
requires_signing_for_device = True,
184+
),
179185
# ios_extension (NSExtension)
180186
apple_product_type.app_extension: _describe_rule_type(
181187
allowed_device_families = ["iphone", "ipad"],

apple/ios.bzl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ load(
1818
"//apple/internal:ios_rules.bzl",
1919
_ios_app_clip = "ios_app_clip",
2020
_ios_application = "ios_application",
21+
_ios_dylib = "ios_dylib",
2122
_ios_dynamic_framework = "ios_dynamic_framework",
2223
_ios_extension = "ios_extension",
2324
_ios_framework = "ios_framework",
@@ -47,6 +48,7 @@ ios_application = _ios_application
4748
ios_app_clip = _ios_app_clip
4849
ios_dynamic_framework = _ios_dynamic_framework
4950
ios_extension = _ios_extension
51+
ios_dylib = _ios_dylib
5052
ios_framework = _ios_framework
5153
ios_imessage_application = _ios_imessage_application
5254
ios_sticker_pack_extension = _ios_sticker_pack_extension

apple/ios.doc.bzl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ load(
2121
"//apple/internal:ios_rules.bzl",
2222
_ios_app_clip = "ios_app_clip",
2323
_ios_application = "ios_application",
24+
_ios_dylib = "ios_dylib",
2425
_ios_dynamic_framework = "ios_dynamic_framework",
2526
_ios_extension = "ios_extension",
2627
_ios_framework = "ios_framework",
@@ -52,6 +53,7 @@ load(
5253
ios_app_clip = _ios_app_clip
5354
ios_application = _ios_application
5455
ios_build_test = _ios_build_test
56+
ios_dylib = _ios_dylib
5557
ios_dynamic_framework = _ios_dynamic_framework
5658
ios_extension = _ios_extension
5759
ios_framework = _ios_framework

doc/rules-ios.md

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,43 @@ ios_build_test(
151151
| <a id="ios_build_test-targets"></a>targets | The targets to check for successful build. | <a href="https://bazel.build/concepts/labels">List of labels</a> | optional | `[]` |
152152

153153

154+
<a id="ios_dylib"></a>
155+
156+
## ios_dylib
157+
158+
<pre>
159+
ios_dylib(<a href="#ios_dylib-name">name</a>, <a href="#ios_dylib-deps">deps</a>, <a href="#ios_dylib-additional_linker_inputs">additional_linker_inputs</a>, <a href="#ios_dylib-base_bundle_id">base_bundle_id</a>, <a href="#ios_dylib-bundle_id">bundle_id</a>, <a href="#ios_dylib-bundle_id_suffix">bundle_id_suffix</a>,
160+
<a href="#ios_dylib-codesign_inputs">codesign_inputs</a>, <a href="#ios_dylib-codesignopts">codesignopts</a>, <a href="#ios_dylib-exported_symbols_lists">exported_symbols_lists</a>, <a href="#ios_dylib-families">families</a>, <a href="#ios_dylib-linkopts">linkopts</a>,
161+
<a href="#ios_dylib-minimum_deployment_os_version">minimum_deployment_os_version</a>, <a href="#ios_dylib-minimum_os_version">minimum_os_version</a>, <a href="#ios_dylib-platform_type">platform_type</a>, <a href="#ios_dylib-provisioning_profile">provisioning_profile</a>,
162+
<a href="#ios_dylib-stamp">stamp</a>, <a href="#ios_dylib-version">version</a>)
163+
</pre>
164+
165+
Builds a iOS Dylib binary.
166+
167+
**ATTRIBUTES**
168+
169+
170+
| Name | Description | Type | Mandatory | Default |
171+
| :------------- | :------------- | :------------- | :------------- | :------------- |
172+
| <a id="ios_dylib-name"></a>name | A unique name for this target. | <a href="https://bazel.build/concepts/labels#target-names">Name</a> | required | |
173+
| <a id="ios_dylib-deps"></a>deps | A list of dependent targets that will be linked into this target's binary(s). Any resources, such as asset catalogs, that are referenced by those targets will also be transitively included in the final bundle(s). | <a href="https://bazel.build/concepts/labels">List of labels</a> | optional | `[]` |
174+
| <a id="ios_dylib-additional_linker_inputs"></a>additional_linker_inputs | A list of input files to be passed to the linker. | <a href="https://bazel.build/concepts/labels">List of labels</a> | optional | `[]` |
175+
| <a id="ios_dylib-base_bundle_id"></a>base_bundle_id | The base bundle ID rule to dictate the form that a given bundle rule's bundle ID prefix should take. | <a href="https://bazel.build/concepts/labels">Label</a> | optional | `None` |
176+
| <a id="ios_dylib-bundle_id"></a>bundle_id | The bundle ID (reverse-DNS path followed by app name) for this target. Only use this attribute if the bundle ID is not intended to be composed through an assigned base bundle ID referenced by `base_bundle_id`. | String | optional | `""` |
177+
| <a id="ios_dylib-bundle_id_suffix"></a>bundle_id_suffix | A string to act as the suffix of the composed bundle ID. If this target's bundle ID is composed from the base bundle ID rule referenced by `base_bundle_id`, then this string will be appended to the end of the bundle ID following a "." separator. | String | optional | `"_"` |
178+
| <a id="ios_dylib-codesign_inputs"></a>codesign_inputs | A list of dependencies targets that provide inputs that will be used by `codesign` (referenced with `codesignopts`). | <a href="https://bazel.build/concepts/labels">List of labels</a> | optional | `[]` |
179+
| <a id="ios_dylib-codesignopts"></a>codesignopts | A list of strings representing extra flags that should be passed to `codesign`. | List of strings | optional | `[]` |
180+
| <a id="ios_dylib-exported_symbols_lists"></a>exported_symbols_lists | A list of targets containing exported symbols lists files for the linker to control symbol resolution.<br><br>Each file is expected to have a list of global symbol names that will remain as global symbols in the compiled binary owned by this framework. All other global symbols will be treated as if they were marked as `__private_extern__` (aka `visibility=hidden`) and will not be global in the output file.<br><br>See the man page documentation for `ld(1)` on macOS for more details. | <a href="https://bazel.build/concepts/labels">List of labels</a> | optional | `[]` |
181+
| <a id="ios_dylib-families"></a>families | A list of device families supported by this rule. At least one must be specified. | List of strings | optional | `["iphone", "ipad"]` |
182+
| <a id="ios_dylib-linkopts"></a>linkopts | A list of strings representing extra flags that should be passed to the linker. | List of strings | optional | `[]` |
183+
| <a id="ios_dylib-minimum_deployment_os_version"></a>minimum_deployment_os_version | A required string indicating the minimum deployment OS version supported by the target, represented as a dotted version number (for example, "9.0"). This is different from `minimum_os_version`, which is effective at compile time. Ensure version specific APIs are guarded with `available` clauses. | String | optional | `""` |
184+
| <a id="ios_dylib-minimum_os_version"></a>minimum_os_version | A required string indicating the minimum OS version supported by the target, represented as a dotted version number (for example, "9.0"). | String | required | |
185+
| <a id="ios_dylib-platform_type"></a>platform_type | - | String | optional | `"ios"` |
186+
| <a id="ios_dylib-provisioning_profile"></a>provisioning_profile | The provisioning profile (`.provisionprofile` file) to use when creating the bundle. This value is optional for simulator builds as the simulator doesn't fully enforce entitlements, but is required for device builds. | <a href="https://bazel.build/concepts/labels">Label</a> | optional | `None` |
187+
| <a id="ios_dylib-stamp"></a>stamp | Enable link stamping. Whether to encode build information into the binary. Possible values:<br><br>* `stamp = 1`: Stamp the build information into the binary. Stamped binaries are only rebuilt when their dependencies change. Use this if there are tests that depend on the build information. * `stamp = 0`: Always replace build information by constant values. This gives good build result caching. * `stamp = -1`: Embedding of build information is controlled by the `--[no]stamp` flag. | Integer | optional | `-1` |
188+
| <a id="ios_dylib-version"></a>version | An `apple_bundle_version` target that represents the version for this target. See [`apple_bundle_version`](https://github.com/bazelbuild/rules_apple/blob/master/doc/rules-general.md?cl=head#apple_bundle_version). | <a href="https://bazel.build/concepts/labels">Label</a> | optional | `None` |
189+
190+
154191
<a id="ios_dynamic_framework"></a>
155192

156193
## ios_dynamic_framework

test/starlark_tests/BUILD

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ load(":generate_import_framework_tests.bzl", "generate_import_framework_test_sui
1818
load(":ios_app_clip_tests.bzl", "ios_app_clip_test_suite")
1919
load(":ios_application_resources_test.bzl", "ios_application_resources_test_suite")
2020
load(":ios_application_tests.bzl", "ios_application_test_suite")
21+
load(":ios_dylib_tests.bzl", "ios_dylib_test_suite")
2122
load(":ios_dynamic_framework_tests.bzl", "ios_dynamic_framework_test_suite")
2223
load(":ios_extension_tests.bzl", "ios_extension_test_suite")
2324
load(":ios_framework_tests.bzl", "ios_framework_test_suite")
@@ -103,6 +104,8 @@ ios_extension_test_suite(name = "ios_extension")
103104

104105
ios_framework_test_suite(name = "ios_framework")
105106

107+
ios_dylib_test_suite(name = "ios_dylib")
108+
106109
ios_dynamic_framework_test_suite(name = "ios_dynamic_framework")
107110

108111
ios_imessage_application_test_suite(name = "ios_imessage_application")
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
# Copyright 2020 The Bazel Authors. All rights reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
"""ios_dylib Starlark tests."""
16+
17+
load(
18+
"//test/starlark_tests/rules:analysis_output_group_info_files_test.bzl",
19+
"analysis_output_group_info_files_test",
20+
)
21+
load(
22+
"//test/starlark_tests/rules:apple_dsym_bundle_info_test.bzl",
23+
"apple_dsym_bundle_info_test",
24+
)
25+
load(
26+
"//test/starlark_tests/rules:apple_verification_test.bzl",
27+
"apple_verification_test",
28+
)
29+
load(
30+
"//test/starlark_tests/rules:common_verification_tests.bzl",
31+
"binary_contents_test",
32+
)
33+
load(
34+
"//test/starlark_tests/rules:output_group_test.bzl",
35+
"output_group_test",
36+
)
37+
38+
def ios_dylib_test_suite(name):
39+
"""Test suite for ios_dylib.
40+
41+
Args:
42+
name: the base name to be used in things created by this macro
43+
"""
44+
apple_verification_test(
45+
name = "{}_codesign_test".format(name),
46+
build_type = "simulator",
47+
target_under_test = "//test/starlark_tests/targets_under_test/ios:dylib",
48+
verifier_script = "verifier_scripts/codesign_verifier.sh",
49+
tags = [name],
50+
)
51+
52+
binary_contents_test(
53+
name = "{}_exported_symbols_list_test".format(name),
54+
build_type = "simulator",
55+
target_under_test = "//test/starlark_tests/targets_under_test/ios:dylib_dead_stripped",
56+
binary_test_file = "$BINARY",
57+
compilation_mode = "opt",
58+
binary_test_architecture = "x86_64",
59+
binary_contains_symbols = ["_anotherFunctionShared"],
60+
binary_not_contains_symbols = ["_dontCallMeShared"],
61+
tags = [name],
62+
)
63+
64+
analysis_output_group_info_files_test(
65+
name = "{}_dsyms_output_group_files_test".format(name),
66+
target_under_test = "//test/starlark_tests/targets_under_test/ios:dylib",
67+
output_group_name = "dsyms",
68+
expected_outputs = [
69+
"dylib.dSYM/Contents/Resources/DWARF/dylib",
70+
],
71+
tags = [name],
72+
)
73+
apple_dsym_bundle_info_test(
74+
name = "{}_dsym_bundle_info_files_test".format(name),
75+
target_under_test = "//test/starlark_tests/targets_under_test/ios:dylib",
76+
expected_direct_dsyms = ["dSYMs/dylib.dSYM"],
77+
expected_transitive_dsyms = ["dSYMs/dylib.dSYM"],
78+
tags = [name],
79+
)
80+
81+
output_group_test(
82+
name = "{}_output_group_test".format(name),
83+
target_under_test = "//test/starlark_tests/targets_under_test/ios:dylib",
84+
expected_output_groups = ["dylib"],
85+
tags = [name],
86+
)
87+
88+
native.test_suite(
89+
name = name,
90+
tags = [name],
91+
)

0 commit comments

Comments
 (0)