blob: d9b0a12b4b7ce48d4f3dec4d54627538fdc637ec [file] [log] [blame]
Liz Kammer9abd62d2021-05-21 08:37:59 -04001// Copyright 2021 Google Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://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,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package bazel
16
17import (
18 "fmt"
19 "strings"
20)
21
22const (
23 // ArchType names in arch.go
24 archArm = "arm"
25 archArm64 = "arm64"
26 archX86 = "x86"
27 archX86_64 = "x86_64"
28
29 // OsType names in arch.go
Wei Li81852ca2022-07-27 00:22:06 -070030 OsAndroid = "android"
Liz Kammer9abd62d2021-05-21 08:37:59 -040031 osDarwin = "darwin"
Liz Kammer9abd62d2021-05-21 08:37:59 -040032 osLinux = "linux_glibc"
Colin Cross528d67e2021-07-23 22:23:07 +000033 osLinuxMusl = "linux_musl"
Liz Kammer9abd62d2021-05-21 08:37:59 -040034 osLinuxBionic = "linux_bionic"
35 osWindows = "windows"
36
37 // Targets in arch.go
38 osArchAndroidArm = "android_arm"
39 osArchAndroidArm64 = "android_arm64"
40 osArchAndroidX86 = "android_x86"
41 osArchAndroidX86_64 = "android_x86_64"
Dan Willemsen8528f4e2021-10-19 00:22:06 -070042 osArchDarwinArm64 = "darwin_arm64"
Liz Kammer9abd62d2021-05-21 08:37:59 -040043 osArchDarwinX86_64 = "darwin_x86_64"
Liz Kammer9abd62d2021-05-21 08:37:59 -040044 osArchLinuxX86 = "linux_glibc_x86"
45 osArchLinuxX86_64 = "linux_glibc_x86_64"
Colin Crossa9b2aac2022-06-15 17:25:51 -070046 osArchLinuxMuslArm = "linux_musl_arm"
47 osArchLinuxMuslArm64 = "linux_musl_arm64"
Colin Cross528d67e2021-07-23 22:23:07 +000048 osArchLinuxMuslX86 = "linux_musl_x86"
49 osArchLinuxMuslX86_64 = "linux_musl_x86_64"
Liz Kammer9abd62d2021-05-21 08:37:59 -040050 osArchLinuxBionicArm64 = "linux_bionic_arm64"
51 osArchLinuxBionicX86_64 = "linux_bionic_x86_64"
52 osArchWindowsX86 = "windows_x86"
53 osArchWindowsX86_64 = "windows_x86_64"
54
55 // This is the string representation of the default condition wherever a
56 // configurable attribute is used in a select statement, i.e.
57 // //conditions:default for Bazel.
58 //
59 // This is consistently named "conditions_default" to mirror the Soong
60 // config variable default key in an Android.bp file, although there's no
61 // integration with Soong config variables (yet).
Chris Parsons51f8c392021-08-03 21:01:05 -040062 ConditionsDefaultConfigKey = "conditions_default"
Liz Kammer9abd62d2021-05-21 08:37:59 -040063
64 ConditionsDefaultSelectKey = "//conditions:default"
65
66 productVariableBazelPackage = "//build/bazel/product_variables"
Wei Li81852ca2022-07-27 00:22:06 -070067
68 AndroidAndInApex = "android-in_apex"
69 AndroidAndNonApex = "android-non_apex"
Liz Kammer9abd62d2021-05-21 08:37:59 -040070)
71
72var (
73 // These are the list of OSes and architectures with a Bazel config_setting
74 // and constraint value equivalent. These exist in arch.go, but the android
75 // package depends on the bazel package, so a cyclic dependency prevents
76 // using those variables here.
77
78 // A map of architectures to the Bazel label of the constraint_value
79 // for the @platforms//cpu:cpu constraint_setting
80 platformArchMap = map[string]string{
Chris Parsons51f8c392021-08-03 21:01:05 -040081 archArm: "//build/bazel/platforms/arch:arm",
82 archArm64: "//build/bazel/platforms/arch:arm64",
83 archX86: "//build/bazel/platforms/arch:x86",
84 archX86_64: "//build/bazel/platforms/arch:x86_64",
85 ConditionsDefaultConfigKey: ConditionsDefaultSelectKey, // The default condition of as arch select map.
Liz Kammer9abd62d2021-05-21 08:37:59 -040086 }
87
88 // A map of target operating systems to the Bazel label of the
89 // constraint_value for the @platforms//os:os constraint_setting
90 platformOsMap = map[string]string{
Wei Li81852ca2022-07-27 00:22:06 -070091 OsAndroid: "//build/bazel/platforms/os:android",
Chris Parsons51f8c392021-08-03 21:01:05 -040092 osDarwin: "//build/bazel/platforms/os:darwin",
93 osLinux: "//build/bazel/platforms/os:linux",
94 osLinuxMusl: "//build/bazel/platforms/os:linux_musl",
95 osLinuxBionic: "//build/bazel/platforms/os:linux_bionic",
96 osWindows: "//build/bazel/platforms/os:windows",
97 ConditionsDefaultConfigKey: ConditionsDefaultSelectKey, // The default condition of an os select map.
Liz Kammer9abd62d2021-05-21 08:37:59 -040098 }
99
100 platformOsArchMap = map[string]string{
Chris Parsons51f8c392021-08-03 21:01:05 -0400101 osArchAndroidArm: "//build/bazel/platforms/os_arch:android_arm",
102 osArchAndroidArm64: "//build/bazel/platforms/os_arch:android_arm64",
103 osArchAndroidX86: "//build/bazel/platforms/os_arch:android_x86",
104 osArchAndroidX86_64: "//build/bazel/platforms/os_arch:android_x86_64",
Dan Willemsen8528f4e2021-10-19 00:22:06 -0700105 osArchDarwinArm64: "//build/bazel/platforms/os_arch:darwin_arm64",
Chris Parsons51f8c392021-08-03 21:01:05 -0400106 osArchDarwinX86_64: "//build/bazel/platforms/os_arch:darwin_x86_64",
107 osArchLinuxX86: "//build/bazel/platforms/os_arch:linux_glibc_x86",
108 osArchLinuxX86_64: "//build/bazel/platforms/os_arch:linux_glibc_x86_64",
Colin Crossa9b2aac2022-06-15 17:25:51 -0700109 osArchLinuxMuslArm: "//build/bazel/platforms/os_arch:linux_musl_arm",
110 osArchLinuxMuslArm64: "//build/bazel/platforms/os_arch:linux_musl_arm64",
Chris Parsons51f8c392021-08-03 21:01:05 -0400111 osArchLinuxMuslX86: "//build/bazel/platforms/os_arch:linux_musl_x86",
112 osArchLinuxMuslX86_64: "//build/bazel/platforms/os_arch:linux_musl_x86_64",
113 osArchLinuxBionicArm64: "//build/bazel/platforms/os_arch:linux_bionic_arm64",
114 osArchLinuxBionicX86_64: "//build/bazel/platforms/os_arch:linux_bionic_x86_64",
115 osArchWindowsX86: "//build/bazel/platforms/os_arch:windows_x86",
116 osArchWindowsX86_64: "//build/bazel/platforms/os_arch:windows_x86_64",
117 ConditionsDefaultConfigKey: ConditionsDefaultSelectKey, // The default condition of an os select map.
Liz Kammer9abd62d2021-05-21 08:37:59 -0400118 }
Chris Parsons58852a02021-12-09 18:10:18 -0500119
120 // Map where keys are OsType names, and values are slices containing the archs
121 // that that OS supports.
122 // These definitions copied from arch.go.
123 // TODO(cparsons): Source from arch.go; this task is nontrivial, as it currently results
124 // in a cyclic dependency.
125 osToArchMap = map[string][]string{
Wei Li81852ca2022-07-27 00:22:06 -0700126 OsAndroid: {archArm, archArm64, archX86, archX86_64},
Chris Parsons58852a02021-12-09 18:10:18 -0500127 osLinux: {archX86, archX86_64},
128 osLinuxMusl: {archX86, archX86_64},
129 osDarwin: {archArm64, archX86_64},
130 osLinuxBionic: {archArm64, archX86_64},
131 // TODO(cparsons): According to arch.go, this should contain archArm, archArm64, as well.
132 osWindows: {archX86, archX86_64},
133 }
Wei Li81852ca2022-07-27 00:22:06 -0700134
135 osAndInApexMap = map[string]string{
136 AndroidAndInApex: "//build/bazel/rules/apex:android-in_apex",
137 AndroidAndNonApex: "//build/bazel/rules/apex:android-non_apex",
138 ConditionsDefaultConfigKey: ConditionsDefaultSelectKey,
139 }
Liz Kammer9abd62d2021-05-21 08:37:59 -0400140)
141
142// basic configuration types
143type configurationType int
144
145const (
146 noConfig configurationType = iota
147 arch
148 os
149 osArch
150 productVariables
Wei Li81852ca2022-07-27 00:22:06 -0700151 osAndInApex
Liz Kammer9abd62d2021-05-21 08:37:59 -0400152)
153
Chris Parsons58852a02021-12-09 18:10:18 -0500154func osArchString(os string, arch string) string {
155 return fmt.Sprintf("%s_%s", os, arch)
156}
157
Liz Kammer9abd62d2021-05-21 08:37:59 -0400158func (ct configurationType) String() string {
159 return map[configurationType]string{
160 noConfig: "no_config",
161 arch: "arch",
162 os: "os",
163 osArch: "arch_os",
164 productVariables: "product_variables",
Wei Li81852ca2022-07-27 00:22:06 -0700165 osAndInApex: "os_in_apex",
Liz Kammer9abd62d2021-05-21 08:37:59 -0400166 }[ct]
167}
168
169func (ct configurationType) validateConfig(config string) {
170 switch ct {
171 case noConfig:
172 if config != "" {
173 panic(fmt.Errorf("Cannot specify config with %s, but got %s", ct, config))
174 }
175 case arch:
176 if _, ok := platformArchMap[config]; !ok {
177 panic(fmt.Errorf("Unknown arch: %s", config))
178 }
179 case os:
180 if _, ok := platformOsMap[config]; !ok {
181 panic(fmt.Errorf("Unknown os: %s", config))
182 }
183 case osArch:
184 if _, ok := platformOsArchMap[config]; !ok {
185 panic(fmt.Errorf("Unknown os+arch: %s", config))
186 }
187 case productVariables:
188 // do nothing
Wei Li81852ca2022-07-27 00:22:06 -0700189 case osAndInApex:
190 if _, ok := osAndInApexMap[config]; !ok {
191 panic(fmt.Errorf("Unknown os+in_apex config: %s", config))
192 }
Liz Kammer9abd62d2021-05-21 08:37:59 -0400193 default:
194 panic(fmt.Errorf("Unrecognized ConfigurationType %d", ct))
195 }
196}
197
198// SelectKey returns the Bazel select key for a given configurationType and config string.
Jingwen Chena47f28d2021-11-02 16:43:57 +0000199func (ca ConfigurationAxis) SelectKey(config string) string {
200 ca.validateConfig(config)
201 switch ca.configurationType {
Liz Kammer9abd62d2021-05-21 08:37:59 -0400202 case noConfig:
203 panic(fmt.Errorf("SelectKey is unnecessary for noConfig ConfigurationType "))
204 case arch:
205 return platformArchMap[config]
206 case os:
207 return platformOsMap[config]
208 case osArch:
209 return platformOsArchMap[config]
210 case productVariables:
Jingwen Chena47f28d2021-11-02 16:43:57 +0000211 if strings.HasSuffix(config, ConditionsDefaultConfigKey) {
212 // e.g. "acme__feature1__conditions_default" or "android__board__conditions_default"
Liz Kammer9abd62d2021-05-21 08:37:59 -0400213 return ConditionsDefaultSelectKey
214 }
Jingwen Chena47f28d2021-11-02 16:43:57 +0000215 return fmt.Sprintf("%s:%s", productVariableBazelPackage, config)
Wei Li81852ca2022-07-27 00:22:06 -0700216 case osAndInApex:
217 return osAndInApexMap[config]
Liz Kammer9abd62d2021-05-21 08:37:59 -0400218 default:
Jingwen Chena47f28d2021-11-02 16:43:57 +0000219 panic(fmt.Errorf("Unrecognized ConfigurationType %d", ca.configurationType))
Liz Kammer9abd62d2021-05-21 08:37:59 -0400220 }
221}
222
223var (
224 // Indicating there is no configuration axis
225 NoConfigAxis = ConfigurationAxis{configurationType: noConfig}
226 // An axis for architecture-specific configurations
227 ArchConfigurationAxis = ConfigurationAxis{configurationType: arch}
228 // An axis for os-specific configurations
229 OsConfigurationAxis = ConfigurationAxis{configurationType: os}
230 // An axis for arch+os-specific configurations
231 OsArchConfigurationAxis = ConfigurationAxis{configurationType: osArch}
Wei Li81852ca2022-07-27 00:22:06 -0700232 // An axis for os+in_apex-specific configurations
233 OsAndInApexAxis = ConfigurationAxis{configurationType: osAndInApex}
Liz Kammer9abd62d2021-05-21 08:37:59 -0400234)
235
236// ProductVariableConfigurationAxis returns an axis for the given product variable
237func ProductVariableConfigurationAxis(variable string) ConfigurationAxis {
238 return ConfigurationAxis{
239 configurationType: productVariables,
240 subType: variable,
241 }
242}
243
244// ConfigurationAxis is an independent axis for configuration, there should be no overlap between
245// elements within an axis.
246type ConfigurationAxis struct {
247 configurationType
248 // some configuration types (e.g. productVariables) have multiple independent axes, subType helps
249 // distinguish between them without needing to list all 17 product variables.
250 subType string
251}
252
253func (ca *ConfigurationAxis) less(other ConfigurationAxis) bool {
254 if ca.configurationType < other.configurationType {
255 return true
256 }
257 return ca.subType < other.subType
258}