Skip to content

Adds ios_dylib rule #2698

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

Open
wants to merge 1 commit 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
159 changes: 159 additions & 0 deletions apple/internal/ios_rules.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ load("@build_bazel_rules_swift//swift:swift.bzl", "SwiftInfo")
load(
"//apple:providers.bzl",
"AppleBundleInfo",
"AppleBundleVersionInfo",
"AppleFrameworkImportInfo",
"ApplePlatformInfo",
"IosAppClipBundleInfo",
Expand Down Expand Up @@ -86,6 +87,7 @@ load(
load(
"//apple/internal:providers.bzl",
"merge_apple_framework_import_info",
"new_applebinaryinfo",
"new_appleexecutablebinaryinfo",
"new_appleframeworkbundleinfo",
"new_iosappclipbundleinfo",
Expand Down Expand Up @@ -1438,6 +1440,125 @@ def _ios_extension_impl(ctx):
link_result.debug_outputs_provider,
] + processor_result.providers

def _ios_dylib_impl(ctx):
"""Implementation of the ios_dylib rule."""
rule_descriptor = rule_support.rule_descriptor(
platform_type = ctx.attr.platform_type,
product_type = apple_product_type.dylib,
)

actions = ctx.actions
apple_mac_toolchain_info = ctx.attr._mac_toolchain[AppleMacToolsToolchainInfo]
apple_xplat_toolchain_info = ctx.attr._xplat_toolchain[AppleXPlatToolsToolchainInfo]

bundle_name, bundle_extension = bundling_support.bundle_full_name(
custom_bundle_name = None, # ios_dylib doesn't support this override.
label_name = ctx.label.name,
rule_descriptor = rule_descriptor,
)
cc_toolchain_forwarder = ctx.split_attr._cc_toolchain_forwarder
features = features_support.compute_enabled_features(
requested_features = ctx.features,
unsupported_features = ctx.disabled_features,
)
label = ctx.label
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 = ctx.attr.minimum_deployment_os_version,
explicit_minimum_os = ctx.attr.minimum_os_version,
features = features,
objc_fragment = ctx.fragments.objc,
platform_type_string = ctx.attr.platform_type,
uses_swift = swift_support.uses_swift(ctx.attr.deps),
xcode_version_config = ctx.attr._xcode_config[apple_common.XcodeVersionConfig],
)
predeclared_outputs = ctx.outputs
provisioning_profile = ctx.file.provisioning_profile

link_result = linking_support.register_binary_linking_action(
ctx,
cc_toolchains = cc_toolchain_forwarder,
# dylibs do not have entitlements.
entitlements = None,
exported_symbols_lists = ctx.files.exported_symbols_lists,
extra_linkopts = ["-dynamiclib"],
platform_prerequisites = platform_prerequisites,
rule_descriptor = rule_descriptor,
stamp = ctx.attr.stamp,
)
binary_artifact = link_result.binary
debug_outputs = linking_support.debug_outputs_by_architecture(link_result.outputs)

debug_outputs_partial = partials.debug_symbols_partial(
actions = actions,
bundle_extension = bundle_extension,
bundle_name = bundle_name,
dsym_binaries = debug_outputs.dsym_binaries,
dsym_info_plist_template = apple_mac_toolchain_info.dsym_info_plist_template,
label_name = label.name,
linkmaps = debug_outputs.linkmaps,
platform_prerequisites = platform_prerequisites,
plisttool = apple_mac_toolchain_info.plisttool,
rule_label = label,
version = ctx.attr.version,
)

processor_result = processor.process(
actions = actions,
apple_mac_toolchain_info = apple_mac_toolchain_info,
apple_xplat_toolchain_info = apple_xplat_toolchain_info,
bundle_extension = bundle_extension,
bundle_name = bundle_name,
bundle_post_process_and_sign = False,
codesign_inputs = ctx.files.codesign_inputs,
codesignopts = codesigning_support.codesignopts_from_rule_ctx(ctx),
features = features,
ipa_post_processor = None,
partials = [debug_outputs_partial],
platform_prerequisites = platform_prerequisites,
predeclared_outputs = predeclared_outputs,
process_and_sign_template = apple_mac_toolchain_info.process_and_sign_template,
provisioning_profile = provisioning_profile,
rule_descriptor = rule_descriptor,
rule_label = label,
)
output_file = actions.declare_file(label.name + ".dylib")
codesigning_support.sign_binary_action(
actions = actions,
codesign_inputs = ctx.files.codesign_inputs,
codesigningtool = apple_mac_toolchain_info.codesigningtool,
codesignopts = codesigning_support.codesignopts_from_rule_ctx(ctx),
input_binary = binary_artifact,
output_binary = output_file,
platform_prerequisites = platform_prerequisites,
provisioning_profile = provisioning_profile,
rule_descriptor = rule_descriptor,
)

return [
new_applebinaryinfo(
binary = output_file,
product_type = rule_descriptor.product_type,
),
DefaultInfo(files = depset(transitive = [
depset([output_file]),
processor_result.output_files,
])),
OutputGroupInfo(
**outputs.merge_output_groups(
link_result.output_groups,
processor_result.output_groups,
{"dylib": depset(direct = [output_file])},
)
),
# TODO(b/228856372): Remove when downstream users are migrated off this provider.
link_result.debug_outputs_provider,
] + processor_result.providers

def _ios_dynamic_framework_impl(ctx):
"""Experimental implementation of ios_dynamic_framework."""
rule_descriptor = rule_support.rule_descriptor(
Expand Down Expand Up @@ -2881,6 +3002,44 @@ use only extension-safe APIs.
],
)

ios_dylib = rule_factory.create_apple_rule(
doc = "Builds a iOS Dylib binary.",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we add more info here, primarily what is a good use case for this rule, etc. This isnt intended to be used in deps of other targets right?

implementation = _ios_dylib_impl,
attrs = [
rule_attrs.binary_linking_attrs(
deps_cfg = transition_support.apple_platform_split_transition,
extra_deps_aspects = [
apple_resource_aspect,
framework_provider_aspect,
],
is_test_supporting_rule = False,
requires_legacy_cc_toolchain = True,
),
rule_attrs.common_tool_attrs(),
rule_attrs.device_family_attrs(
allowed_families = rule_attrs.defaults.allowed_families.ios,
),
rule_attrs.custom_transition_allowlist_attr(),
rule_attrs.platform_attrs(
add_environment_plist = True,
platform_type = "ios",
),
rule_attrs.signing_attrs(
supports_capabilities = False,
profile_extension = ".provisionprofile",
),
{
"version": attr.label(
providers = [[AppleBundleVersionInfo]],
doc = """
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).
""",
),
},
],
)

ios_dynamic_framework = rule_factory.create_apple_rule(
doc = "Builds and bundles an iOS dynamic framework that is consumable by Xcode.",
implementation = _ios_dynamic_framework_impl,
Expand Down
6 changes: 6 additions & 0 deletions apple/internal/rule_support.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,12 @@ _RULE_TYPE_DESCRIPTORS = {
"@executable_path/Frameworks",
],
),
apple_product_type.dylib: _describe_rule_type(
allowed_device_families = ["iphone", "ipad"],
bundle_extension = "",
product_type = apple_product_type.dylib,
requires_signing_for_device = True,
),
# ios_extension (NSExtension)
apple_product_type.app_extension: _describe_rule_type(
allowed_device_families = ["iphone", "ipad"],
Expand Down
2 changes: 2 additions & 0 deletions apple/ios.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ load(
"//apple/internal:ios_rules.bzl",
_ios_app_clip = "ios_app_clip",
_ios_application = "ios_application",
_ios_dylib = "ios_dylib",
_ios_dynamic_framework = "ios_dynamic_framework",
_ios_extension = "ios_extension",
_ios_framework = "ios_framework",
Expand Down Expand Up @@ -47,6 +48,7 @@ ios_application = _ios_application
ios_app_clip = _ios_app_clip
ios_dynamic_framework = _ios_dynamic_framework
ios_extension = _ios_extension
ios_dylib = _ios_dylib
ios_framework = _ios_framework
ios_imessage_application = _ios_imessage_application
ios_sticker_pack_extension = _ios_sticker_pack_extension
Expand Down
2 changes: 2 additions & 0 deletions apple/ios.doc.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ load(
"//apple/internal:ios_rules.bzl",
_ios_app_clip = "ios_app_clip",
_ios_application = "ios_application",
_ios_dylib = "ios_dylib",
_ios_dynamic_framework = "ios_dynamic_framework",
_ios_extension = "ios_extension",
_ios_framework = "ios_framework",
Expand Down Expand Up @@ -52,6 +53,7 @@ load(
ios_app_clip = _ios_app_clip
ios_application = _ios_application
ios_build_test = _ios_build_test
ios_dylib = _ios_dylib
ios_dynamic_framework = _ios_dynamic_framework
ios_extension = _ios_extension
ios_framework = _ios_framework
Expand Down
37 changes: 37 additions & 0 deletions doc/rules-ios.md
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,43 @@ ios_build_test(
| <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 | `[]` |


<a id="ios_dylib"></a>

## ios_dylib

<pre>
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>,
<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>,
<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>,
<a href="#ios_dylib-stamp">stamp</a>, <a href="#ios_dylib-version">version</a>)
</pre>

Builds a iOS Dylib binary.

**ATTRIBUTES**


| Name | Description | Type | Mandatory | Default |
| :------------- | :------------- | :------------- | :------------- | :------------- |
| <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 | |
| <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 | `[]` |
| <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 | `[]` |
| <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` |
| <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 | `""` |
| <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 | `"_"` |
| <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 | `[]` |
| <a id="ios_dylib-codesignopts"></a>codesignopts | A list of strings representing extra flags that should be passed to `codesign`. | List of strings | optional | `[]` |
| <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 | `[]` |
| <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"]` |
| <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 | `[]` |
| <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 | `""` |
| <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 | |
| <a id="ios_dylib-platform_type"></a>platform_type | - | String | optional | `"ios"` |
| <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` |
| <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` |
| <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` |


<a id="ios_dynamic_framework"></a>

## ios_dynamic_framework
Expand Down
3 changes: 3 additions & 0 deletions test/starlark_tests/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ load(":generate_import_framework_tests.bzl", "generate_import_framework_test_sui
load(":ios_app_clip_tests.bzl", "ios_app_clip_test_suite")
load(":ios_application_resources_test.bzl", "ios_application_resources_test_suite")
load(":ios_application_tests.bzl", "ios_application_test_suite")
load(":ios_dylib_tests.bzl", "ios_dylib_test_suite")
load(":ios_dynamic_framework_tests.bzl", "ios_dynamic_framework_test_suite")
load(":ios_extension_tests.bzl", "ios_extension_test_suite")
load(":ios_framework_tests.bzl", "ios_framework_test_suite")
Expand Down Expand Up @@ -103,6 +104,8 @@ ios_extension_test_suite(name = "ios_extension")

ios_framework_test_suite(name = "ios_framework")

ios_dylib_test_suite(name = "ios_dylib")

ios_dynamic_framework_test_suite(name = "ios_dynamic_framework")

ios_imessage_application_test_suite(name = "ios_imessage_application")
Expand Down
91 changes: 91 additions & 0 deletions test/starlark_tests/ios_dylib_tests.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
# Copyright 2020 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.

"""ios_dylib Starlark tests."""

load(
"//test/starlark_tests/rules:analysis_output_group_info_files_test.bzl",
"analysis_output_group_info_files_test",
)
load(
"//test/starlark_tests/rules:apple_dsym_bundle_info_test.bzl",
"apple_dsym_bundle_info_test",
)
load(
"//test/starlark_tests/rules:apple_verification_test.bzl",
"apple_verification_test",
)
load(
"//test/starlark_tests/rules:common_verification_tests.bzl",
"binary_contents_test",
)
load(
"//test/starlark_tests/rules:output_group_test.bzl",
"output_group_test",
)

def ios_dylib_test_suite(name):
"""Test suite for ios_dylib.

Args:
name: the base name to be used in things created by this macro
"""
apple_verification_test(
name = "{}_codesign_test".format(name),
build_type = "simulator",
target_under_test = "//test/starlark_tests/targets_under_test/ios:dylib",
verifier_script = "verifier_scripts/codesign_verifier.sh",
tags = [name],
)

binary_contents_test(
name = "{}_exported_symbols_list_test".format(name),
build_type = "simulator",
target_under_test = "//test/starlark_tests/targets_under_test/ios:dylib_dead_stripped",
binary_test_file = "$BINARY",
compilation_mode = "opt",
binary_test_architecture = "x86_64",
binary_contains_symbols = ["_anotherFunctionShared"],
binary_not_contains_symbols = ["_dontCallMeShared"],
tags = [name],
)

analysis_output_group_info_files_test(
name = "{}_dsyms_output_group_files_test".format(name),
target_under_test = "//test/starlark_tests/targets_under_test/ios:dylib",
output_group_name = "dsyms",
expected_outputs = [
"dylib.dSYM/Contents/Resources/DWARF/dylib",
],
tags = [name],
)
apple_dsym_bundle_info_test(
name = "{}_dsym_bundle_info_files_test".format(name),
target_under_test = "//test/starlark_tests/targets_under_test/ios:dylib",
expected_direct_dsyms = ["dSYMs/dylib.dSYM"],
expected_transitive_dsyms = ["dSYMs/dylib.dSYM"],
tags = [name],
)

output_group_test(
name = "{}_output_group_test".format(name),
target_under_test = "//test/starlark_tests/targets_under_test/ios:dylib",
expected_output_groups = ["dylib"],
tags = [name],
)

native.test_suite(
name = name,
tags = [name],
)
Loading