blob: 296c225c9f8229f5eda329c7c6994bbfd4645868 [file] [log] [blame]
# Copyright 2022 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.
"""
Defines the Android Split configuration transition for properly handling native
dependencies
The intended order of checks is:
- If `--android_platforms` is set:
- Split using the values of this flag as the target platform
- If this is unset, use the first value from `--platforms`.
- If this isn't a valid Android platform, an error will be thrown
during the build.
- Default
- This will not update the output path to include "-android".
- Don't split, using the same previously set `--cpu` value.
"""
load("//rules:visibility.bzl", "PROJECT_VISIBILITY")
load(":utils.bzl", "utils")
visibility(PROJECT_VISIBILITY)
def _android_split_transition_impl(settings, _):
# Always use `--android_platforms` when toolchain resolution is enabled.
platforms_to_split = utils.get_cls(settings, "android_platforms")
if not platforms_to_split:
# If `--android_platforms` is unset, instead use only the first
# value from `--platforms`.
target_platform = utils.only(utils.get_cls(settings, "platforms"))
platforms_to_split = [target_platform]
return _handle_android_platforms(settings, platforms_to_split)
# This transition exists so targets can be built in the same configuration as the deps of android_binary.
# The goal is to avoid unnecessarily building a dependency in two different configurations which wastes resources.
def _android_transition_impl(settings, attr):
# There are cases where an android_binary depends on another android_binary via an attribute
# we apply this transition to. In that case we end up applying this transition twice.
# The second transition will fail. Since the transition clears out --android_platforms we can
# use that as a signal to do nothing.
if not utils.get_cls(settings, "android_platforms"):
return None
configs = _android_split_transition_impl(settings, attr)
# Always pick the config based on the first value in --android_platforms
# This ensures the choice is consistent with the android_platforms_transition
return configs[utils.get_cls(settings, "android_platforms")[0].name]
def _handle_android_platforms(settings, platforms_to_split):
"""
Splits the configuration based on the values of --android_platforms.
Each split will set the --platforms flag to one value from
--android_platforms, as well as clean up a few other flags around native
CC builds.
"""
result = dict()
for platform in platforms_to_split:
name = platform.name
split_options = dict(settings)
# Disable fat APKs for the child configurations.
split_options[utils.add_cls_prefix("android_platforms")] = []
# The cpu flag will be set by platform mapping if a mapping exists.
split_options[utils.add_cls_prefix("platforms")] = [platform]
_cc_flags_from_android(settings, split_options)
result[name] = split_options
return result
def _cc_flags_from_android(settings, new_settings):
new_settings[utils.add_cls_prefix("compiler")] = utils.get_cls(settings, "android_compiler")
new_settings[utils.add_cls_prefix("dynamic_mode")] = utils.get_cls(settings, "android_dynamic_mode")
new_settings[utils.add_cls_prefix("Android configuration distinguisher")] = "android"
_INPUTS = [
"//command_line_option:Android configuration distinguisher",
"//command_line_option:android_compiler",
"//command_line_option:android_dynamic_mode",
"//command_line_option:android_platforms",
"//command_line_option:compiler",
"//command_line_option:dynamic_mode",
"//command_line_option:platforms",
]
_OUTPUTS = [
"//command_line_option:Android configuration distinguisher",
"//command_line_option:android_compiler",
"//command_line_option:android_dynamic_mode",
"//command_line_option:android_platforms",
"//command_line_option:compiler",
"//command_line_option:dynamic_mode",
"//command_line_option:platforms",
]
android_split_transition = transition(
implementation = _android_split_transition_impl,
inputs = _INPUTS,
outputs = _OUTPUTS,
)
android_transition = transition(
implementation = _android_transition_impl,
inputs = _INPUTS,
outputs = _OUTPUTS,
)