Skip to main content
Glama
configuration.bzl8.61 kB
# 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:cpu_filters.bzl", "ALL_CPU_FILTERS", "CPU_FILTER_FOR_DEFAULT_PLATFORM", "CPU_FILTER_FOR_PRIMARY_PLATFORM") load("@prelude//android:min_sdk_version.bzl", "get_min_sdk_version_constraint_value_name", "get_min_sdk_version_range") load("@prelude//cfg/modifier:name.bzl", "cfg_name") load("@prelude//utils:expect.bzl", "expect") # Android binaries (APKs or AABs) can be built for one or more different platforms. buck2 supports # building Android binaries for arm32, arm64, x86, and x86_64. The platform(s) that we are building # for are specified by the `cpu_filters` attribute on the binary rule. # In order to build our native libraries for the correct platform(s), we do a (split) transition # (https://www.internalfb.com/intern/staticdocs/buck2/docs/rule_authors/configuration_transitions) # on the `deps` of the binary, and have each of the resulting configured sub-graphs be responsible # for building the native libraries for one of the specified platforms. # We always create an "arm64" configured sub-graph and use it to build the non-native libraries (so # that we get cache hits for the non-native libraries even if we're building for different # platforms). We only use the "arm64" native libraries if it is one of the specified platforms. We # "throw away" the non-native libraries for all other configured sub-graphs. _REFS = { "arm64": "config//cpu/constraints:arm64", "armv7": "config//cpu/constraints:arm32", "build_only_native_code": "prelude//android/constraints:build_only_native_code", "building_android_binary": "prelude//os:building_android_binary", "cpu": "config//cpu/constraints:cpu", "maybe_build_only_native_code": "prelude//android/constraints:maybe_build_only_native_code", "maybe_building_android_binary": "prelude//os:maybe_building_android_binary", "min_sdk_version": "prelude//android/constraints:min_sdk_version", "x86": "config//cpu/constraints:x86_32", "x86_64": "config//cpu/constraints:x86_64", } _DEFAULT_PLATFORM = read_root_config("android", "primary_platform_for_build", None) if _DEFAULT_PLATFORM: _REFS["default_platform"] = _DEFAULT_PLATFORM 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] = "prelude//android/constraints:{}".format(constraint_value_name) def _cpu_split_transition_impl( platform: PlatformInfo, refs: struct, attrs: struct) -> dict[str, PlatformInfo]: cpu_filters = attrs.cpu_filters or ALL_CPU_FILTERS if attrs._is_force_single_cpu: cpu_filters = [CPU_FILTER_FOR_PRIMARY_PLATFORM] elif attrs._is_force_single_default_cpu: cpu_filters = ["default"] return _cpu_split_transition( platform, refs, cpu_filters, attrs.min_sdk_version, ) def _cpu_split_transition( platform: PlatformInfo, refs: struct, cpu_filters: list[str], min_sdk_version: [int, None]) -> dict[str, PlatformInfo]: cpu = refs.cpu x86 = refs.x86[ConstraintValueInfo] x86_64 = refs.x86_64[ConstraintValueInfo] armv7 = refs.armv7[ConstraintValueInfo] arm64 = refs.arm64[ConstraintValueInfo] if len(cpu_filters) == 1 and cpu_filters[0] == "default": default_platform = getattr(refs, "default_platform", None) expect( default_platform != None, "Cannot specify 'is_force_single_default_cpu' but not specify a default platform!", ) default = default_platform[PlatformInfo] # Use `cfg_name` function from modifier resolution so that we get the same cfg as default cfg # of android libraries. default = PlatformInfo( label = cfg_name(default.configuration), configuration = default.configuration, ) return {CPU_FILTER_FOR_DEFAULT_PLATFORM: default} expect(CPU_FILTER_FOR_PRIMARY_PLATFORM == "arm64") cpu_name_to_cpu_constraint = {"arm64": arm64} 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": # Always included as the primary platform pass 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: updated_constraints[refs.maybe_build_only_native_code[ConstraintSettingInfo].label] = refs.build_only_native_code[ConstraintValueInfo] cfg_info = ConfigurationInfo( constraints = updated_constraints, values = platform.configuration.values, ) # Use `cfg_name` function from modifier resolution so that we get the same cfg as default cfg # of android libraries. new_configs[platform_name] = PlatformInfo( label = cfg_name(cfg_info), configuration = cfg_info, ) return new_configs def _cpu_transition_impl( platform: PlatformInfo, refs: struct, attrs: struct) -> PlatformInfo: 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", "_is_force_single_cpu", "_is_force_single_default_cpu", ], 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", "_is_force_single_cpu", "_is_force_single_default_cpu", ], ) def get_deps_by_platform(ctx: AnalysisContext) -> dict[str, list[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, refs: struct) -> ConstraintValueInfo: 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() -> Select: return select( { "DEFAULT": False, "prelude//os:building_android_binary": True, }, ) def is_building_android_binary_attr() -> Attr: return attrs.default_only(attrs.bool(default = _is_building_android_binary()))

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/systeminit/si'

If you have feedback or need assistance with the MCP directory API, please join our Discord server