• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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