1# Copyright 2024 The Pigweed Authors 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); you may not 4# use this file except in compliance with the License. You may obtain a copy of 5# the License at 6# 7# https://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12# License for the specific language governing permissions and limitations under 13# the License. 14"""Rules and macros related to platform compatibility.""" 15 16load("@bazel_skylib//lib:selects.bzl", "selects") 17 18def host_backend_alias(name, backend): 19 """An alias that resolves to the backend for host platforms.""" 20 native.alias( 21 name = name, 22 actual = selects.with_or({ 23 ( 24 "@platforms//os:android", 25 "@platforms//os:chromiumos", 26 "@platforms//os:linux", 27 "@platforms//os:macos", 28 "@platforms//os:windows", 29 ): backend, 30 "//conditions:default": str(Label("//pw_build:unspecified_backend")), 31 }), 32 ) 33 34def boolean_constraint_value(name, **kwargs): 35 """Syntactic sugar for a constraint with just two possible values. 36 37 Args: 38 name: The name of the "True" value of the generated constraint. 39 **kwargs: Passed on to native.constraint_value. 40 """ 41 constraint_setting_name = name + ".constraint_setting" 42 false_value_name = name + ".not" 43 44 native.constraint_setting( 45 name = constraint_setting_name, 46 default_constraint_value = ":" + false_value_name, 47 # Do not allow anyone to declare additional values for this setting. 48 # It's boolean, so by definition it's true or false, that's it! 49 visibility = ["//visibility:private"], 50 ) 51 52 native.constraint_value( 53 name = false_value_name, 54 constraint_setting = ":" + constraint_setting_name, 55 # The false value is not exposed at this time to avoid exposing more 56 # API surface than necessary, and for better compliance with 57 # https://bazel.build/rules/bzl-style#macros. But we may make it public 58 # in the future. 59 visibility = ["//visibility:private"], 60 ) 61 62 native.constraint_value( 63 name = name, 64 constraint_setting = ":" + constraint_setting_name, 65 **kwargs 66 ) 67 68def incompatible_with_mcu(unless_platform_has = None): 69 """Helper for expressing incompatibility with MCU platforms. 70 71 This helper should be used in `target_compatible_with` attributes to 72 express: 73 74 * That a target is only compatible with platforms that have a 75 full-featured OS, see 76 https://pigweed.dev/bazel_compatibility.html#cross-platform-modules-requiring-an-os 77 * That a target is compatible with platforms with a full-featured OS, and 78 also any platform that explicitly declares compatibility with it: 79 https://pigweed.dev/bazel_compatibility.html#special-case-host-compatible-platform-specific-modules 80 81 Args: 82 unless_platform_has: A constraint_value that the target is compatible with 83 by definition. Optional. 84 """ 85 return select({ 86 "@platforms//os:none": [unless_platform_has] if (unless_platform_has != None) else ["@platforms//:incompatible"], 87 "//conditions:default": [], 88 }) 89 90def minimum_cxx_20(): 91 """Helper for expressing a C++20 requirement. 92 93 This helper should be used in `target_compatible_with` attributes to express 94 that a target requires C++20 or newer. 95 """ 96 return select({ 97 "//pw_toolchain/cc:c++20_enabled": [], 98 "//conditions:default": ["@platforms//:incompatible"], 99 }) 100