fwd/vendor/cxx/tools/buck/prelude/android/configuration.bzl
John Doty 9c435dc440 Vendor dependencies
Let's see how I like this workflow.
2022-12-19 08:38:22 -08:00

190 lines
8.1 KiB
Python

# Copyright (c) Meta Platforms, Inc. and affiliates.
#
# This source code is licensed under both the MIT license found in the
# LICENSE-MIT file in the root directory of this source tree and the Apache
# License, Version 2.0 found in the LICENSE-APACHE file in the root directory
# of this source tree.
load("@prelude//android:android_providers.bzl", "CPU_FILTER_TO_ABI_DIRECTORY")
load("@prelude//android:min_sdk_version.bzl", "get_min_sdk_version_constraint_value_name", "get_min_sdk_version_range")
# FIXME: prelude// should be standalone (not refer to ovr_config//)
_REFS = {
"arm64": "ovr_config//cpu/constraints:arm64",
"armv7": "ovr_config//cpu/constraints:arm32",
"build_only_native_code": "fbsource//xplat/buck2/platform/android:build_only_native_code",
"building_android_binary": "prelude//os:building_android_binary",
"cpu": "ovr_config//cpu/constraints:cpu",
"do_not_build_only_native_code": "fbsource//xplat/buck2/platform/android:do_not_build_only_native_code",
"maybe_build_only_native_code": "fbsource//xplat/buck2/platform/android:maybe_build_only_native_code",
"maybe_building_android_binary": "prelude//os:maybe_building_android_binary",
"min_sdk_version": "fbsource//xplat/buck2/platform/android:min_sdk_version",
"x86": "ovr_config//cpu/constraints:x86_32",
"x86_64": "ovr_config//cpu/constraints:x86_64",
}
for min_sdk in get_min_sdk_version_range():
constraint_value_name = get_min_sdk_version_constraint_value_name(min_sdk)
_REFS[constraint_value_name] = "fbsource//xplat/buck2/platform/android:{}".format(constraint_value_name)
def _cpu_split_transition_instrumentation_test_apk_impl(
platform: PlatformInfo.type,
refs: struct.type,
attrs: struct.type) -> {str.type: PlatformInfo.type}:
cpu_filters = attrs.cpu_filters or CPU_FILTER_TO_ABI_DIRECTORY.keys()
return _cpu_split_transition(platform, refs, cpu_filters, attrs.min_sdk_version, build_only_native_code_on_secondary_platforms = False)
def _cpu_split_transition_impl(
platform: PlatformInfo.type,
refs: struct.type,
attrs: struct.type) -> {str.type: PlatformInfo.type}:
cpu_filters = attrs.cpu_filters or CPU_FILTER_TO_ABI_DIRECTORY.keys()
do_not_build_only_native_code = refs.do_not_build_only_native_code[ConstraintValueInfo].label in [constraint.label for constraint in platform.configuration.constraints.values()]
return _cpu_split_transition(platform, refs, cpu_filters, attrs.min_sdk_version, build_only_native_code_on_secondary_platforms = not do_not_build_only_native_code)
def _cpu_split_transition(
platform: PlatformInfo.type,
refs: struct.type,
cpu_filters: [str.type],
min_sdk_version: [int.type, None],
build_only_native_code_on_secondary_platforms: bool.type) -> {str.type: PlatformInfo.type}:
cpu = refs.cpu
x86 = refs.x86[ConstraintValueInfo]
x86_64 = refs.x86_64[ConstraintValueInfo]
armv7 = refs.armv7[ConstraintValueInfo]
arm64 = refs.arm64[ConstraintValueInfo]
cpu_name_to_cpu_constraint = {}
for cpu_filter in cpu_filters:
if cpu_filter == "x86":
cpu_name_to_cpu_constraint["x86"] = x86
elif cpu_filter == "armv7":
cpu_name_to_cpu_constraint["armv7"] = armv7
elif cpu_filter == "x86_64":
cpu_name_to_cpu_constraint["x86_64"] = x86_64
elif cpu_filter == "arm64":
cpu_name_to_cpu_constraint["arm64"] = arm64
else:
fail("Unexpected cpu_filter: {}".format(cpu_filter))
base_constraints = {
constraint_setting_label: constraint_setting_value
for (constraint_setting_label, constraint_setting_value) in platform.configuration.constraints.items()
if constraint_setting_label != cpu[ConstraintSettingInfo].label and constraint_setting_label != refs.maybe_build_only_native_code[ConstraintSettingInfo].label
}
base_constraints[refs.maybe_building_android_binary[ConstraintSettingInfo].label] = refs.building_android_binary[ConstraintValueInfo]
if min_sdk_version:
base_constraints[refs.min_sdk_version[ConstraintSettingInfo].label] = _get_min_sdk_constraint_value(min_sdk_version, refs)
new_configs = {}
for platform_name, cpu_constraint in cpu_name_to_cpu_constraint.items():
updated_constraints = dict(base_constraints)
updated_constraints[refs.cpu[ConstraintSettingInfo].label] = cpu_constraint
if len(new_configs) > 0 and build_only_native_code_on_secondary_platforms:
updated_constraints[refs.maybe_build_only_native_code[ConstraintSettingInfo].label] = refs.build_only_native_code[ConstraintValueInfo]
new_configs[platform_name] = PlatformInfo(
label = platform_name,
configuration = ConfigurationInfo(
constraints = updated_constraints,
values = platform.configuration.values,
),
)
return new_configs
def _cpu_transition_impl(
platform: PlatformInfo.type,
refs: struct.type,
attrs: struct.type) -> PlatformInfo.type:
return _cpu_split_transition_impl(platform, refs, attrs).values()[0]
cpu_split_transition = transition(
impl = _cpu_split_transition_impl,
refs = _REFS,
attrs = [
"cpu_filters",
"min_sdk_version",
],
split = True,
)
cpu_split_transition_instrumentation_test_apk = transition(
impl = _cpu_split_transition_instrumentation_test_apk_impl,
refs = _REFS,
attrs = [
"cpu_filters",
"min_sdk_version",
],
split = True,
)
# If our deps have been split-transitioned by CPU then we are already analyzing the dependency
# graph using the resulting configurations. If there are any other attributes on the same target
# that also need to analyze the dependency graph, then we want to use one of the configurations
# from the split transition so that we don't end up analyzing the graph again using a different
# configuration. This rule just picks the first configuration from the split-transition.
#
# This is used for the `manifest` attribute of `android_binary`.
cpu_transition = transition(
impl = _cpu_transition_impl,
refs = _REFS,
attrs = [
"cpu_filters",
"min_sdk_version",
],
)
def _do_not_build_only_native_code_transition(
platform: PlatformInfo.type,
refs: struct.type) -> PlatformInfo.type:
constraints = dict(platform.configuration.constraints.items())
constraints[refs.maybe_build_only_native_code[ConstraintSettingInfo].label] = refs.do_not_build_only_native_code[ConstraintValueInfo]
return PlatformInfo(
label = platform.label,
configuration = ConfigurationInfo(
constraints = constraints,
values = platform.configuration.values,
),
)
do_not_build_only_native_code_transition = transition(
impl = _do_not_build_only_native_code_transition,
refs = {
"do_not_build_only_native_code": "fbsource//xplat/buck2/platform/android:do_not_build_only_native_code",
"maybe_build_only_native_code": "fbsource//xplat/buck2/platform/android:maybe_build_only_native_code",
},
)
def get_deps_by_platform(ctx: "context") -> {str.type: ["dependency"]}:
deps_by_platform = {}
for dep_dict in ctx.attrs.deps:
for platform, dep in dep_dict.items():
deps = deps_by_platform.get(platform, [])
deps.append(dep)
deps_by_platform[platform] = deps
return deps_by_platform
def _get_min_sdk_constraint_value(min_sdk_version: int.type, refs: struct.type) -> ConstraintValueInfo.type:
constraint_name = get_min_sdk_version_constraint_value_name(min_sdk_version)
constraint = getattr(refs, constraint_name, None)
if not constraint:
fail("Unsupported min_sdk_version {}, please report!".format(min_sdk_version))
return constraint[ConstraintValueInfo]
def _is_building_android_binary() -> "selector":
return select(
{
"DEFAULT": False,
"prelude//os:building_android_binary": True,
},
)
def is_building_android_binary_attr() -> "attribute":
return attrs.default_only(attrs.bool(default = _is_building_android_binary()))