blob: d2d5647bee25399abf26f86526c11d7f7b6883b1 [file] [log] [blame] [edit]
# Copyright 2024 The Pigweed Authors
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy of
# the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under
# the License.
"""Rules and macros related to platform compatibility."""
load("@bazel_skylib//lib:selects.bzl", "selects")
HOST_PLATFORMS = (
"@platforms//os:android",
"@platforms//os:chromiumos",
"@platforms//os:linux",
"@platforms//os:macos",
"@platforms//os:windows",
)
def host_backend_alias(name, backend):
"""An alias that resolves to the backend for host platforms."""
native.alias(
name = name,
actual = selects.with_or({
HOST_PLATFORMS: backend,
"//conditions:default": str(Label("//pw_build:unspecified_backend")),
}),
)
def boolean_constraint_value(name, **kwargs):
"""Syntactic sugar for a constraint with just two possible values.
Args:
name: The name of the "True" value of the generated constraint.
**kwargs: Passed on to native.constraint_value.
"""
constraint_setting_name = name + ".constraint_setting"
false_value_name = name + ".not"
native.constraint_setting(
name = constraint_setting_name,
default_constraint_value = ":" + false_value_name,
# Do not allow anyone to declare additional values for this setting.
# It's boolean, so by definition it's true or false, that's it!
visibility = ["//visibility:private"],
)
native.constraint_value(
name = false_value_name,
constraint_setting = ":" + constraint_setting_name,
# The false value is not exposed at this time to avoid exposing more
# API surface than necessary, and for better compliance with
# https://bazel.build/rules/bzl-style#macros. But we may make it public
# in the future.
visibility = ["//visibility:private"],
)
native.constraint_value(
name = name,
constraint_setting = ":" + constraint_setting_name,
**kwargs
)
def incompatible_with_mcu(unless_platform_has = None):
"""Helper for expressing incompatibility with MCU platforms.
This helper should be used in `target_compatible_with` attributes to
express:
* That a target is only compatible with platforms that have a
full-featured OS, see
https://pigweed.dev/bazel_compatibility.html#cross-platform-modules-requiring-an-os
* That a target is compatible with platforms with a full-featured OS, and
also any platform that explicitly declares compatibility with it:
https://pigweed.dev/bazel_compatibility.html#special-case-host-compatible-platform-specific-modules
Args:
unless_platform_has: A constraint_value that the target is compatible with
by definition. Optional.
"""
return select({
"@platforms//os:none": [unless_platform_has] if (unless_platform_has != None) else ["@platforms//:incompatible"],
"//conditions:default": [],
})
def minimum_cxx_20():
"""Helper for expressing a C++20 requirement.
This helper should be used in `target_compatible_with` attributes to express
that a target requires C++20 or newer.
"""
return select({
"//pw_toolchain/cc:c++20_enabled": [],
"//conditions:default": ["@platforms//:incompatible"],
})