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 18HOST_PLATFORMS = ( 19 "@platforms//os:android", 20 "@platforms//os:chromiumos", 21 "@platforms//os:linux", 22 "@platforms//os:macos", 23 "@platforms//os:windows", 24) 25 26def host_backend_alias(name, backend): 27 """An alias that resolves to the backend for host platforms.""" 28 native.alias( 29 name = name, 30 actual = selects.with_or({ 31 HOST_PLATFORMS: backend, 32 "//conditions:default": str(Label("//pw_build:unspecified_backend")), 33 }), 34 ) 35 36def boolean_constraint_value(name, **kwargs): 37 """Syntactic sugar for a constraint with just two possible values. 38 39 Args: 40 name: The name of the "True" value of the generated constraint. 41 **kwargs: Passed on to native.constraint_value. 42 """ 43 constraint_setting_name = name + ".constraint_setting" 44 false_value_name = name + ".not" 45 46 native.constraint_setting( 47 name = constraint_setting_name, 48 default_constraint_value = ":" + false_value_name, 49 # Do not allow anyone to declare additional values for this setting. 50 # It's boolean, so by definition it's true or false, that's it! 51 visibility = ["//visibility:private"], 52 ) 53 54 native.constraint_value( 55 name = false_value_name, 56 constraint_setting = ":" + constraint_setting_name, 57 # The false value is not exposed at this time to avoid exposing more 58 # API surface than necessary, and for better compliance with 59 # https://bazel.build/rules/bzl-style#macros. But we may make it public 60 # in the future. 61 visibility = ["//visibility:private"], 62 ) 63 64 native.constraint_value( 65 name = name, 66 constraint_setting = ":" + constraint_setting_name, 67 **kwargs 68 ) 69 70def incompatible_with_mcu(unless_platform_has = None): 71 """Helper for expressing incompatibility with MCU platforms. 72 73 This helper should be used in `target_compatible_with` attributes to 74 express: 75 76 * That a target is only compatible with platforms that have a 77 full-featured OS, see 78 https://pigweed.dev/bazel_compatibility.html#cross-platform-modules-requiring-an-os 79 * That a target is compatible with platforms with a full-featured OS, and 80 also any platform that explicitly declares compatibility with it: 81 https://pigweed.dev/bazel_compatibility.html#special-case-host-compatible-platform-specific-modules 82 83 Args: 84 unless_platform_has: A constraint_value that the target is compatible with 85 by definition. Optional. 86 """ 87 return select({ 88 "@platforms//os:none": [unless_platform_has] if (unless_platform_has != None) else ["@platforms//:incompatible"], 89 "//conditions:default": [], 90 }) 91 92def minimum_cxx_20(): 93 """Helper for expressing a C++20 requirement. 94 95 This helper should be used in `target_compatible_with` attributes to express 96 that a target requires C++20 or newer. 97 """ 98 return select({ 99 "//pw_toolchain/cc:c++20_enabled": [], 100 "//conditions:default": ["@platforms//:incompatible"], 101 }) 102