xref: /aosp_15_r20/external/bazel-skylib/rules/common_settings.bzl (revision bcb5dc7965af6ee42bf2f21341a2ec00233a8c8a)
1*bcb5dc79SHONG Yifan# Copyright 2019 The Bazel Authors. All rights reserved.
2*bcb5dc79SHONG Yifan#
3*bcb5dc79SHONG Yifan# Licensed under the Apache License, Version 2.0 (the "License");
4*bcb5dc79SHONG Yifan# you may not use this file except in compliance with the License.
5*bcb5dc79SHONG Yifan# You may obtain a copy of the License at
6*bcb5dc79SHONG Yifan#
7*bcb5dc79SHONG Yifan#    http://www.apache.org/licenses/LICENSE-2.0
8*bcb5dc79SHONG Yifan#
9*bcb5dc79SHONG Yifan# Unless required by applicable law or agreed to in writing, software
10*bcb5dc79SHONG Yifan# distributed under the License is distributed on an "AS IS" BASIS,
11*bcb5dc79SHONG Yifan# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*bcb5dc79SHONG Yifan# See the License for the specific language governing permissions and
13*bcb5dc79SHONG Yifan# limitations under the License.
14*bcb5dc79SHONG Yifan
15*bcb5dc79SHONG Yifan"""Common build setting rules
16*bcb5dc79SHONG Yifan
17*bcb5dc79SHONG YifanThese rules return a BuildSettingInfo with the value of the build setting.
18*bcb5dc79SHONG YifanFor label-typed settings, use the native label_flag and label_setting rules.
19*bcb5dc79SHONG Yifan
20*bcb5dc79SHONG YifanMore documentation on how to use build settings at
21*bcb5dc79SHONG Yifanhttps://bazel.build/extending/config#user-defined-build-settings
22*bcb5dc79SHONG Yifan"""
23*bcb5dc79SHONG Yifan
24*bcb5dc79SHONG YifanBuildSettingInfo = provider(
25*bcb5dc79SHONG Yifan    doc = "A singleton provider that contains the raw value of a build setting",
26*bcb5dc79SHONG Yifan    fields = {
27*bcb5dc79SHONG Yifan        "value": "The value of the build setting in the current configuration. " +
28*bcb5dc79SHONG Yifan                 "This value may come from the command line or an upstream transition, " +
29*bcb5dc79SHONG Yifan                 "or else it will be the build setting's default.",
30*bcb5dc79SHONG Yifan    },
31*bcb5dc79SHONG Yifan)
32*bcb5dc79SHONG Yifan
33*bcb5dc79SHONG Yifan_MAKE_VARIABLE_ATTR = attr.string(
34*bcb5dc79SHONG Yifan    doc = "If set, the build setting's value will be available as a Make variable with this " +
35*bcb5dc79SHONG Yifan          "name in the attributes of rules that list this build setting in their 'toolchains' " +
36*bcb5dc79SHONG Yifan          "attribute.",
37*bcb5dc79SHONG Yifan)
38*bcb5dc79SHONG Yifan
39*bcb5dc79SHONG Yifandef _is_valid_make_variable_char(c):
40*bcb5dc79SHONG Yifan    # Restrict make variable names for consistency with predefined ones. There are no enforced
41*bcb5dc79SHONG Yifan    # restrictions on make variable names, but when they contain e.g. spaces or braces, they
42*bcb5dc79SHONG Yifan    # aren't expanded by e.g. cc_binary.
43*bcb5dc79SHONG Yifan    return c == "_" or c.isdigit() or (c.isalpha() and c.isupper())
44*bcb5dc79SHONG Yifan
45*bcb5dc79SHONG Yifandef _get_template_variable_info(ctx):
46*bcb5dc79SHONG Yifan    make_variable = getattr(ctx.attr, "make_variable", None)
47*bcb5dc79SHONG Yifan    if not make_variable:
48*bcb5dc79SHONG Yifan        return []
49*bcb5dc79SHONG Yifan
50*bcb5dc79SHONG Yifan    if not all([_is_valid_make_variable_char(c) for c in make_variable.elems()]):
51*bcb5dc79SHONG Yifan        fail("Error setting " + _no_at_str(ctx.label) + ": invalid make variable name '" + make_variable + "'. Make variable names may only contain uppercase letters, digits, and underscores.")
52*bcb5dc79SHONG Yifan
53*bcb5dc79SHONG Yifan    return [
54*bcb5dc79SHONG Yifan        platform_common.TemplateVariableInfo({
55*bcb5dc79SHONG Yifan            make_variable: str(ctx.build_setting_value),
56*bcb5dc79SHONG Yifan        }),
57*bcb5dc79SHONG Yifan    ]
58*bcb5dc79SHONG Yifan
59*bcb5dc79SHONG Yifandef _impl(ctx):
60*bcb5dc79SHONG Yifan    return [
61*bcb5dc79SHONG Yifan        BuildSettingInfo(value = ctx.build_setting_value),
62*bcb5dc79SHONG Yifan    ] + _get_template_variable_info(ctx)
63*bcb5dc79SHONG Yifan
64*bcb5dc79SHONG Yifanint_flag = rule(
65*bcb5dc79SHONG Yifan    implementation = _impl,
66*bcb5dc79SHONG Yifan    build_setting = config.int(flag = True),
67*bcb5dc79SHONG Yifan    attrs = {
68*bcb5dc79SHONG Yifan        "make_variable": _MAKE_VARIABLE_ATTR,
69*bcb5dc79SHONG Yifan    },
70*bcb5dc79SHONG Yifan    doc = "An int-typed build setting that can be set on the command line",
71*bcb5dc79SHONG Yifan)
72*bcb5dc79SHONG Yifan
73*bcb5dc79SHONG Yifanint_setting = rule(
74*bcb5dc79SHONG Yifan    implementation = _impl,
75*bcb5dc79SHONG Yifan    build_setting = config.int(),
76*bcb5dc79SHONG Yifan    attrs = {
77*bcb5dc79SHONG Yifan        "make_variable": _MAKE_VARIABLE_ATTR,
78*bcb5dc79SHONG Yifan    },
79*bcb5dc79SHONG Yifan    doc = "An int-typed build setting that cannot be set on the command line",
80*bcb5dc79SHONG Yifan)
81*bcb5dc79SHONG Yifan
82*bcb5dc79SHONG Yifanbool_flag = rule(
83*bcb5dc79SHONG Yifan    implementation = _impl,
84*bcb5dc79SHONG Yifan    build_setting = config.bool(flag = True),
85*bcb5dc79SHONG Yifan    doc = "A bool-typed build setting that can be set on the command line",
86*bcb5dc79SHONG Yifan)
87*bcb5dc79SHONG Yifan
88*bcb5dc79SHONG Yifanbool_setting = rule(
89*bcb5dc79SHONG Yifan    implementation = _impl,
90*bcb5dc79SHONG Yifan    build_setting = config.bool(),
91*bcb5dc79SHONG Yifan    doc = "A bool-typed build setting that cannot be set on the command line",
92*bcb5dc79SHONG Yifan)
93*bcb5dc79SHONG Yifan
94*bcb5dc79SHONG Yifanstring_list_flag = rule(
95*bcb5dc79SHONG Yifan    implementation = _impl,
96*bcb5dc79SHONG Yifan    build_setting = config.string_list(flag = True),
97*bcb5dc79SHONG Yifan    doc = "A string list-typed build setting that can be set on the command line",
98*bcb5dc79SHONG Yifan)
99*bcb5dc79SHONG Yifan
100*bcb5dc79SHONG Yifanstring_list_setting = rule(
101*bcb5dc79SHONG Yifan    implementation = _impl,
102*bcb5dc79SHONG Yifan    build_setting = config.string_list(),
103*bcb5dc79SHONG Yifan    doc = "A string list-typed build setting that cannot be set on the command line",
104*bcb5dc79SHONG Yifan)
105*bcb5dc79SHONG Yifan
106*bcb5dc79SHONG Yifandef _no_at_str(label):
107*bcb5dc79SHONG Yifan    """Strips any leading '@'s for labels in the main repo, so that the error string is more friendly."""
108*bcb5dc79SHONG Yifan    s = str(label)
109*bcb5dc79SHONG Yifan    if s.startswith("@@//"):
110*bcb5dc79SHONG Yifan        return s[2:]
111*bcb5dc79SHONG Yifan    if s.startswith("@//"):
112*bcb5dc79SHONG Yifan        return s[1:]
113*bcb5dc79SHONG Yifan    return s
114*bcb5dc79SHONG Yifan
115*bcb5dc79SHONG Yifandef _string_impl(ctx):
116*bcb5dc79SHONG Yifan    allowed_values = ctx.attr.values
117*bcb5dc79SHONG Yifan    value = ctx.build_setting_value
118*bcb5dc79SHONG Yifan    if len(allowed_values) == 0 or value in ctx.attr.values:
119*bcb5dc79SHONG Yifan        return [BuildSettingInfo(value = value)] + _get_template_variable_info(ctx)
120*bcb5dc79SHONG Yifan    else:
121*bcb5dc79SHONG Yifan        fail("Error setting " + _no_at_str(ctx.label) + ": invalid value '" + value + "'. Allowed values are " + str(allowed_values))
122*bcb5dc79SHONG Yifan
123*bcb5dc79SHONG Yifanstring_flag = rule(
124*bcb5dc79SHONG Yifan    implementation = _string_impl,
125*bcb5dc79SHONG Yifan    build_setting = config.string(flag = True),
126*bcb5dc79SHONG Yifan    attrs = {
127*bcb5dc79SHONG Yifan        "values": attr.string_list(
128*bcb5dc79SHONG Yifan            doc = "The list of allowed values for this setting. An error is raised if any other value is given.",
129*bcb5dc79SHONG Yifan        ),
130*bcb5dc79SHONG Yifan        "make_variable": _MAKE_VARIABLE_ATTR,
131*bcb5dc79SHONG Yifan    },
132*bcb5dc79SHONG Yifan    doc = "A string-typed build setting that can be set on the command line",
133*bcb5dc79SHONG Yifan)
134*bcb5dc79SHONG Yifan
135*bcb5dc79SHONG Yifanstring_setting = rule(
136*bcb5dc79SHONG Yifan    implementation = _string_impl,
137*bcb5dc79SHONG Yifan    build_setting = config.string(),
138*bcb5dc79SHONG Yifan    attrs = {
139*bcb5dc79SHONG Yifan        "values": attr.string_list(
140*bcb5dc79SHONG Yifan            doc = "The list of allowed values for this setting. An error is raised if any other value is given.",
141*bcb5dc79SHONG Yifan        ),
142*bcb5dc79SHONG Yifan        "make_variable": _MAKE_VARIABLE_ATTR,
143*bcb5dc79SHONG Yifan    },
144*bcb5dc79SHONG Yifan    doc = "A string-typed build setting that cannot be set on the command line",
145*bcb5dc79SHONG Yifan)
146