Skip to content
Closed
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
12 changes: 12 additions & 0 deletions apple/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,18 @@ bzl_library(
],
)

bzl_library(
name = "apple_static_library",
srcs = ["apple_static_library.bzl"],
deps = [
":providers",
"//apple/internal:linking_support",
"//apple/internal:rule_factory",
"//apple/internal:transition_support",
"@bazel_skylib//lib:dicts",
],
)

bzl_library(
name = "aspects",
srcs = ["aspects.bzl"],
Expand Down
174 changes: 174 additions & 0 deletions apple/apple_static_library.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
# 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.

"""apple_static_library Starlark implementation"""

load(
"@build_bazel_rules_apple//apple/internal:transition_support.bzl",
"transition_support",
)
load(
"@build_bazel_rules_apple//apple/internal:linking_support.bzl",
"linking_support",
)
load(
"@build_bazel_rules_apple//apple/internal:rule_factory.bzl",
"rule_factory",
)
load(
"@build_bazel_rules_apple//apple:providers.bzl",
"AppleBinaryInfo",
)
load(
"@bazel_skylib//lib:dicts.bzl",
"dicts",
)

def _apple_static_library_impl(ctx):
# Validation of the platform type and minimum version OS currently happen in
# `transition_support.apple_platform_transition`, either implicitly through native
# `dotted_version` or explicitly through `fail` on an unrecognized platform type value.

link_result = linking_support.register_static_library_linking_action(ctx = ctx)

files_to_build = [link_result.library]
runfiles = ctx.runfiles(
files = files_to_build,
collect_default = True,
collect_data = True,
)

return [
DefaultInfo(files = depset(files_to_build), runfiles = runfiles),
AppleBinaryInfo(
binary = link_result.library,
),
link_result.objc,
link_result.output_groups,
]

apple_static_library = rule(
implementation = _apple_static_library_impl,
attrs = dicts.add(
rule_factory.common_tool_attributes,
rule_factory.common_bazel_attributes.link_multi_arch_static_library_attrs(
cfg = apple_common.multi_arch_split,
),
{
"additional_linker_inputs": attr.label_list(
# Flag required for compile_one_dependency
flags = ["DIRECT_COMPILE_TIME_INPUT"],
allow_files = True,
doc = """
A list of input files to be passed to the linker.
""",
),
"avoid_deps": attr.label_list(
cfg = apple_common.multi_arch_split,
providers = [CcInfo],
# Flag required for compile_one_dependency
flags = ["DIRECT_COMPILE_TIME_INPUT"],
doc = """
A list of library targets on which this framework depends in order to compile, but the transitive
closure of which will not be linked into the framework's binary.
""",
),
"data": attr.label_list(
allow_files = True,
doc = """
Files to be made available to the library archive upon execution.
""",
),
"deps": attr.label_list(
cfg = apple_common.multi_arch_split,
providers = [CcInfo],
# Flag required for compile_one_dependency
flags = ["DIRECT_COMPILE_TIME_INPUT"],
doc = """
A list of dependencies targets that will be linked into this target's binary. Any resources, such as
asset catalogs, that are referenced by those targets will also be transitively included in the final
bundle.
""",
),
"linkopts": attr.string_list(
doc = """
A list of strings representing extra flags that should be passed to the linker.
""",
),
"minimum_os_version": attr.string(
mandatory = True,
doc = """
A required string indicating the minimum OS version supported by the target, represented as a
dotted version number (for example, "9.0").
""",
),
"platform_type": attr.string(
mandatory = True,
doc = """
The target Apple platform for which to create a binary. This dictates which SDK
is used for compilation/linking and which flag is used to determine the
architectures to target. For example, if `ios` is specified, then the output
binaries/libraries will be created combining all architectures specified by
`--ios_multi_cpus`. Options are:

* `ios`: architectures gathered from `--ios_multi_cpus`.
* `macos`: architectures gathered from `--macos_cpus`.
* `tvos`: architectures gathered from `--tvos_cpus`.
* `watchos`: architectures gathered from `--watchos_cpus`.
""",
),
"sdk_frameworks": attr.string_list(
doc = """
Names of SDK frameworks to link with (e.g., `AddressBook`, `QuartzCore`).
`UIKit` and `Foundation` are always included, even if this attribute is
provided and does not list them.

This attribute is discouraged; in general, targets should list system
framework dependencies in the library targets where that framework is used,
not in the top-level bundle.
""",
),
"sdk_dylibs": attr.string_list(
doc = """
Names of SDK `.dylib` libraries to link with (e.g., `libz` or `libarchive`).
`libc++` is included automatically if the binary has any C++ or Objective-C++
sources in its dependency tree. When linking a binary, all libraries named in
that binary's transitive dependency graph are used.
""",
),
"weak_sdk_frameworks": attr.string_list(
doc = """
Names of SDK frameworks to weakly link with (e.g., `MediaAccessibility`).
Unlike regularly linked SDK frameworks, symbols from weakly linked
frameworks do not cause the binary to fail to load if they are not present in
the version of the framework available at runtime.

This attribute is discouraged; in general, targets should list system
framework dependencies in the library targets where that framework is used,
not in the top-level bundle.
""",
),
"_allowlist_function_transition": attr.label(
default = "@bazel_tools//tools/allowlists/function_transition_allowlist",
),
},
),
outputs = {
"lipo_archive": "%{name}_lipo.a",
},
cfg = transition_support.apple_platform_transition,
fragments = ["objc", "apple", "cpp"],
toolchains = ["@bazel_tools//tools/cpp:toolchain_type"],
incompatible_use_toolchain_transition = True,
)
1 change: 1 addition & 0 deletions apple/internal/linking_support.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,7 @@ def _register_static_library_linking_action(ctx):

return struct(
library = fat_library,
objc = linking_outputs.objc,
outputs = linking_outputs.outputs,
output_groups = linking_outputs.output_groups,
)
Expand Down
39 changes: 39 additions & 0 deletions apple/internal/transition_support.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ def _command_line_options(
emit_swiftinterface = False,
minimum_os_version,
platform_type,
platforms = [],
settings):
"""Generates a dictionary of command line options suitable for the current target.

Expand All @@ -118,6 +119,8 @@ def _command_line_options(
platform, represented as a dotted version number (for example, `"9.0"`).
platform_type: The Apple platform for which the rule should build its targets (`"ios"`,
`"macos"`, `"tvos"`, or `"watchos"`).
platforms: A list of labels referencing platforms if any should be set by the current rule.
Defaults to an empty list so that platform mapping can take place.
settings: A dictionary whose set of keys is defined by the inputs parameter, typically from
the settings argument found on the implementation function of the current Starlark
transition.
Expand All @@ -141,6 +144,7 @@ def _command_line_options(
),
"//command_line_option:fission": [],
"//command_line_option:grte_top": settings["//command_line_option:apple_grte_top"],
"//command_line_option:platforms": platforms,
"//command_line_option:ios_minimum_os": _min_os_version_or_none(
minimum_os_version = minimum_os_version,
platform = "ios",
Expand Down Expand Up @@ -272,6 +276,11 @@ _apple_rule_base_transition_inputs = _apple_rule_common_transition_inputs + [
"//command_line_option:tvos_cpus",
"//command_line_option:watchos_cpus",
]
_apple_platform_transition_inputs = _apple_rule_base_transition_inputs + [
"//command_line_option:apple_platforms",
"//command_line_option:incompatible_enable_apple_toolchain_resolution",
"//command_line_option:platforms",
]
_apple_rule_base_transition_outputs = [
"//command_line_option:apple configuration distinguisher",
"//command_line_option:apple_platform_type",
Expand All @@ -283,6 +292,7 @@ _apple_rule_base_transition_outputs = [
"//command_line_option:grte_top",
"//command_line_option:ios_minimum_os",
"//command_line_option:macos_minimum_os",
"//command_line_option:platforms",
"//command_line_option:tvos_minimum_os",
"//command_line_option:watchos_minimum_os",
"@build_bazel_rules_swift//swift:emit_swiftinterface",
Expand Down Expand Up @@ -375,6 +385,34 @@ _static_framework_transition = transition(
],
)

def _apple_platform_transition_impl(settings, attr):
"""Rule transition to handle setting crosstool and platform flags for Apple rules."""
if settings["//command_line_option:incompatible_enable_apple_toolchain_resolution"]:
platforms = (
settings["//command_line_option:apple_platforms"] or
settings["//command_line_option:platforms"]
)
return _command_line_options(
minimum_os_version = attr.minimum_os_version,
platform_type = attr.platform_type,
platforms = platforms,
settings = settings,
)

# Ensure platforms aren't set so that platform mapping can take place.
return _command_line_options(
minimum_os_version = attr.minimum_os_version,
platform_type = attr.platform_type,
platforms = [],
settings = settings,
)

_apple_platform_transition = transition(
implementation = _apple_platform_transition_impl,
inputs = _apple_platform_transition_inputs,
outputs = _apple_rule_base_transition_outputs,
)

# TODO(b/230527536): Add support for Bazel platforms on ios/tvos_static_framework transition support method
def _apple_common_multi_arch_split_key(*, cpu, environment, platform_type):
"""Returns split key for the apple_common.multi_arch_split transition based on target triplet.
Expand Down Expand Up @@ -429,6 +467,7 @@ _xcframework_transition = transition(
)

transition_support = struct(
apple_platform_transition = _apple_platform_transition,
apple_rule_transition = _apple_rule_base_transition,
apple_rule_arm64_as_arm64e_transition = _apple_rule_arm64_as_arm64e_transition,
apple_universal_binary_rule_transition = _apple_universal_binary_rule_transition,
Expand Down
3 changes: 3 additions & 0 deletions test/starlark_tests/BUILD
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
load("@bazel_skylib//:bzl_library.bzl", "bzl_library")
load(":apple_bundle_version_tests.bzl", "apple_bundle_version_test_suite")
load(":apple_core_data_model_tests.bzl", "apple_core_data_model_test_suite")
load(":apple_static_library_tests.bzl", "apple_static_library_test_suite")
load(":apple_static_xcframework_tests.bzl", "apple_static_xcframework_test_suite")
load(":apple_universal_binary_tests.bzl", "apple_universal_binary_test_suite")
load(":apple_xcframework_import_tests.bzl", "apple_xcframework_import_test_suite")
Expand Down Expand Up @@ -48,6 +49,8 @@ apple_bundle_version_test_suite(name = "apple_bundle_version")

apple_core_data_model_test_suite(name = "apple_core_data_model")

apple_static_library_test_suite(name = "apple_static_library")

apple_static_xcframework_test_suite(name = "apple_static_xcframework")

apple_universal_binary_test_suite(name = "apple_universal_binary")
Expand Down
Loading