blob: 1fe84421978b67133e17c2d3b525deefc13cccbb [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"
Cole Faustc843b992022-08-02 18:06:50 -070019 "math"
20 "sort"
Liz Kammer9abd62d2021-05-21 08:37:59 -040021 "strings"
22)
23
24const (
25 // ArchType names in arch.go
Colin Crossf05b0d32022-07-14 18:10:34 -070026 archArm = "arm"
27 archArm64 = "arm64"
28 archRiscv64 = "riscv64"
29 archX86 = "x86"
30 archX86_64 = "x86_64"
Liz Kammer9abd62d2021-05-21 08:37:59 -040031
32 // OsType names in arch.go
Wei Li81852ca2022-07-27 00:22:06 -070033 OsAndroid = "android"
Spandan Dasfb04c412023-05-15 18:35:36 +000034 OsDarwin = "darwin"
35 OsLinux = "linux_glibc"
Colin Cross528d67e2021-07-23 22:23:07 +000036 osLinuxMusl = "linux_musl"
Liz Kammer9abd62d2021-05-21 08:37:59 -040037 osLinuxBionic = "linux_bionic"
Spandan Dasfb04c412023-05-15 18:35:36 +000038 OsWindows = "windows"
Liz Kammer9abd62d2021-05-21 08:37:59 -040039
40 // Targets in arch.go
41 osArchAndroidArm = "android_arm"
Yu Liu7ece4aa2023-08-25 16:56:33 -070042 OsArchAndroidArm64 = "android_arm64"
Colin Crossf05b0d32022-07-14 18:10:34 -070043 osArchAndroidRiscv64 = "android_riscv64"
Liz Kammer9abd62d2021-05-21 08:37:59 -040044 osArchAndroidX86 = "android_x86"
45 osArchAndroidX86_64 = "android_x86_64"
Dan Willemsen8528f4e2021-10-19 00:22:06 -070046 osArchDarwinArm64 = "darwin_arm64"
Liz Kammer9abd62d2021-05-21 08:37:59 -040047 osArchDarwinX86_64 = "darwin_x86_64"
Liz Kammer9abd62d2021-05-21 08:37:59 -040048 osArchLinuxX86 = "linux_glibc_x86"
49 osArchLinuxX86_64 = "linux_glibc_x86_64"
Colin Crossa9b2aac2022-06-15 17:25:51 -070050 osArchLinuxMuslArm = "linux_musl_arm"
51 osArchLinuxMuslArm64 = "linux_musl_arm64"
Colin Cross528d67e2021-07-23 22:23:07 +000052 osArchLinuxMuslX86 = "linux_musl_x86"
53 osArchLinuxMuslX86_64 = "linux_musl_x86_64"
Liz Kammer9abd62d2021-05-21 08:37:59 -040054 osArchLinuxBionicArm64 = "linux_bionic_arm64"
55 osArchLinuxBionicX86_64 = "linux_bionic_x86_64"
56 osArchWindowsX86 = "windows_x86"
57 osArchWindowsX86_64 = "windows_x86_64"
58
59 // This is the string representation of the default condition wherever a
60 // configurable attribute is used in a select statement, i.e.
61 // //conditions:default for Bazel.
62 //
63 // This is consistently named "conditions_default" to mirror the Soong
64 // config variable default key in an Android.bp file, although there's no
65 // integration with Soong config variables (yet).
Chris Parsons51f8c392021-08-03 21:01:05 -040066 ConditionsDefaultConfigKey = "conditions_default"
Liz Kammer9abd62d2021-05-21 08:37:59 -040067
68 ConditionsDefaultSelectKey = "//conditions:default"
69
Cole Faust87c0c332023-07-31 12:10:12 -070070 productVariableBazelPackage = "//build/bazel/product_config/config_settings"
Wei Li81852ca2022-07-27 00:22:06 -070071
Spandan Das6d4d9da2023-04-18 06:20:40 +000072 AndroidAndInApex = "android-in_apex"
73 AndroidPlatform = "system"
Vinh Tran85fb07c2022-09-16 16:17:48 -040074
75 InApex = "in_apex"
76 NonApex = "non_apex"
Alixc0dac522023-05-04 21:20:16 +000077
78 ErrorproneDisabled = "errorprone_disabled"
Trevor Radcliffed9b7f172023-08-09 22:21:38 +000079 // TODO: b/294868620 - Remove when completing the bug
80 SanitizersEnabled = "sanitizers_enabled"
Liz Kammer9abd62d2021-05-21 08:37:59 -040081)
82
Cole Faustc843b992022-08-02 18:06:50 -070083func PowerSetWithoutEmptySet[T any](items []T) [][]T {
84 resultSize := int(math.Pow(2, float64(len(items))))
85 powerSet := make([][]T, 0, resultSize-1)
86 for i := 1; i < resultSize; i++ {
87 combination := make([]T, 0)
88 for j := 0; j < len(items); j++ {
89 if (i>>j)%2 == 1 {
90 combination = append(combination, items[j])
91 }
92 }
93 powerSet = append(powerSet, combination)
94 }
95 return powerSet
96}
97
98func createPlatformArchMap() map[string]string {
99 // Copy of archFeatures from android/arch_list.go because the bazel
100 // package can't access the android package
101 archFeatures := map[string][]string{
102 "arm": {
103 "neon",
104 },
105 "arm64": {
106 "dotprod",
107 },
Colin Crossf05b0d32022-07-14 18:10:34 -0700108 "riscv64": {},
Cole Faustc843b992022-08-02 18:06:50 -0700109 "x86": {
110 "ssse3",
111 "sse4",
112 "sse4_1",
113 "sse4_2",
114 "aes_ni",
115 "avx",
116 "avx2",
117 "avx512",
118 "popcnt",
119 "movbe",
120 },
121 "x86_64": {
122 "ssse3",
123 "sse4",
124 "sse4_1",
125 "sse4_2",
126 "aes_ni",
127 "avx",
128 "avx2",
129 "avx512",
130 "popcnt",
131 },
132 }
133 result := make(map[string]string)
134 for arch, allFeatures := range archFeatures {
135 result[arch] = "//build/bazel/platforms/arch:" + arch
136 // Sometimes we want to select on multiple features being active, so
137 // add the power set of all possible features to the map. More details
138 // in android.ModuleBase.GetArchVariantProperties
139 for _, features := range PowerSetWithoutEmptySet(allFeatures) {
140 sort.Strings(features)
141 archFeaturesName := arch + "-" + strings.Join(features, "-")
142 result[archFeaturesName] = "//build/bazel/platforms/arch/variants:" + archFeaturesName
143 }
144 }
145 result[ConditionsDefaultConfigKey] = ConditionsDefaultSelectKey
146 return result
147}
148
Liz Kammer9abd62d2021-05-21 08:37:59 -0400149var (
150 // These are the list of OSes and architectures with a Bazel config_setting
151 // and constraint value equivalent. These exist in arch.go, but the android
152 // package depends on the bazel package, so a cyclic dependency prevents
153 // using those variables here.
154
155 // A map of architectures to the Bazel label of the constraint_value
156 // for the @platforms//cpu:cpu constraint_setting
Cole Faustc843b992022-08-02 18:06:50 -0700157 platformArchMap = createPlatformArchMap()
Liz Kammer9abd62d2021-05-21 08:37:59 -0400158
159 // A map of target operating systems to the Bazel label of the
160 // constraint_value for the @platforms//os:os constraint_setting
161 platformOsMap = map[string]string{
Wei Li81852ca2022-07-27 00:22:06 -0700162 OsAndroid: "//build/bazel/platforms/os:android",
Spandan Dasfb04c412023-05-15 18:35:36 +0000163 OsDarwin: "//build/bazel/platforms/os:darwin",
164 OsLinux: "//build/bazel/platforms/os:linux_glibc",
Chris Parsons51f8c392021-08-03 21:01:05 -0400165 osLinuxMusl: "//build/bazel/platforms/os:linux_musl",
166 osLinuxBionic: "//build/bazel/platforms/os:linux_bionic",
Spandan Dasfb04c412023-05-15 18:35:36 +0000167 OsWindows: "//build/bazel/platforms/os:windows",
Chris Parsons51f8c392021-08-03 21:01:05 -0400168 ConditionsDefaultConfigKey: ConditionsDefaultSelectKey, // The default condition of an os select map.
Liz Kammer9abd62d2021-05-21 08:37:59 -0400169 }
170
171 platformOsArchMap = map[string]string{
Chris Parsons51f8c392021-08-03 21:01:05 -0400172 osArchAndroidArm: "//build/bazel/platforms/os_arch:android_arm",
Yu Liu7ece4aa2023-08-25 16:56:33 -0700173 OsArchAndroidArm64: "//build/bazel/platforms/os_arch:android_arm64",
Colin Crossf05b0d32022-07-14 18:10:34 -0700174 osArchAndroidRiscv64: "//build/bazel/platforms/os_arch:android_riscv64",
Chris Parsons51f8c392021-08-03 21:01:05 -0400175 osArchAndroidX86: "//build/bazel/platforms/os_arch:android_x86",
176 osArchAndroidX86_64: "//build/bazel/platforms/os_arch:android_x86_64",
Dan Willemsen8528f4e2021-10-19 00:22:06 -0700177 osArchDarwinArm64: "//build/bazel/platforms/os_arch:darwin_arm64",
Chris Parsons51f8c392021-08-03 21:01:05 -0400178 osArchDarwinX86_64: "//build/bazel/platforms/os_arch:darwin_x86_64",
179 osArchLinuxX86: "//build/bazel/platforms/os_arch:linux_glibc_x86",
180 osArchLinuxX86_64: "//build/bazel/platforms/os_arch:linux_glibc_x86_64",
Colin Crossa9b2aac2022-06-15 17:25:51 -0700181 osArchLinuxMuslArm: "//build/bazel/platforms/os_arch:linux_musl_arm",
182 osArchLinuxMuslArm64: "//build/bazel/platforms/os_arch:linux_musl_arm64",
Chris Parsons51f8c392021-08-03 21:01:05 -0400183 osArchLinuxMuslX86: "//build/bazel/platforms/os_arch:linux_musl_x86",
184 osArchLinuxMuslX86_64: "//build/bazel/platforms/os_arch:linux_musl_x86_64",
185 osArchLinuxBionicArm64: "//build/bazel/platforms/os_arch:linux_bionic_arm64",
186 osArchLinuxBionicX86_64: "//build/bazel/platforms/os_arch:linux_bionic_x86_64",
187 osArchWindowsX86: "//build/bazel/platforms/os_arch:windows_x86",
188 osArchWindowsX86_64: "//build/bazel/platforms/os_arch:windows_x86_64",
189 ConditionsDefaultConfigKey: ConditionsDefaultSelectKey, // The default condition of an os select map.
Liz Kammer9abd62d2021-05-21 08:37:59 -0400190 }
Chris Parsons58852a02021-12-09 18:10:18 -0500191
192 // Map where keys are OsType names, and values are slices containing the archs
193 // that that OS supports.
194 // These definitions copied from arch.go.
195 // TODO(cparsons): Source from arch.go; this task is nontrivial, as it currently results
196 // in a cyclic dependency.
197 osToArchMap = map[string][]string{
Colin Crossf05b0d32022-07-14 18:10:34 -0700198 OsAndroid: {archArm, archArm64, archRiscv64, archX86, archX86_64},
Spandan Dasfb04c412023-05-15 18:35:36 +0000199 OsLinux: {archX86, archX86_64},
Chris Parsons58852a02021-12-09 18:10:18 -0500200 osLinuxMusl: {archX86, archX86_64},
Spandan Dasfb04c412023-05-15 18:35:36 +0000201 OsDarwin: {archArm64, archX86_64},
Chris Parsons58852a02021-12-09 18:10:18 -0500202 osLinuxBionic: {archArm64, archX86_64},
203 // TODO(cparsons): According to arch.go, this should contain archArm, archArm64, as well.
Spandan Dasfb04c412023-05-15 18:35:36 +0000204 OsWindows: {archX86, archX86_64},
Chris Parsons58852a02021-12-09 18:10:18 -0500205 }
Wei Li81852ca2022-07-27 00:22:06 -0700206
207 osAndInApexMap = map[string]string{
208 AndroidAndInApex: "//build/bazel/rules/apex:android-in_apex",
Spandan Das6d4d9da2023-04-18 06:20:40 +0000209 AndroidPlatform: "//build/bazel/rules/apex:system",
Spandan Dasfb04c412023-05-15 18:35:36 +0000210 OsDarwin: "//build/bazel/platforms/os:darwin",
211 OsLinux: "//build/bazel/platforms/os:linux_glibc",
Liz Kammerffc17e42022-11-23 09:42:05 -0500212 osLinuxMusl: "//build/bazel/platforms/os:linux_musl",
213 osLinuxBionic: "//build/bazel/platforms/os:linux_bionic",
Spandan Dasfb04c412023-05-15 18:35:36 +0000214 OsWindows: "//build/bazel/platforms/os:windows",
Wei Li81852ca2022-07-27 00:22:06 -0700215 ConditionsDefaultConfigKey: ConditionsDefaultSelectKey,
216 }
Vinh Tran85fb07c2022-09-16 16:17:48 -0400217
218 inApexMap = map[string]string{
219 InApex: "//build/bazel/rules/apex:in_apex",
220 NonApex: "//build/bazel/rules/apex:non_apex",
221 ConditionsDefaultConfigKey: ConditionsDefaultSelectKey,
222 }
Alixc0dac522023-05-04 21:20:16 +0000223
224 errorProneMap = map[string]string{
225 ErrorproneDisabled: "//build/bazel/rules/java/errorprone:errorprone_globally_disabled",
226 ConditionsDefaultConfigKey: ConditionsDefaultSelectKey,
227 }
Trevor Radcliffed9b7f172023-08-09 22:21:38 +0000228
229 // TODO: b/294868620 - Remove when completing the bug
230 sanitizersEnabledMap = map[string]string{
231 SanitizersEnabled: "//build/bazel/rules/cc:sanitizers_enabled",
232 ConditionsDefaultConfigKey: ConditionsDefaultSelectKey,
233 }
Liz Kammer9abd62d2021-05-21 08:37:59 -0400234)
235
236// basic configuration types
237type configurationType int
238
239const (
240 noConfig configurationType = iota
241 arch
242 os
243 osArch
244 productVariables
Wei Li81852ca2022-07-27 00:22:06 -0700245 osAndInApex
Vinh Tran85fb07c2022-09-16 16:17:48 -0400246 inApex
Alixc0dac522023-05-04 21:20:16 +0000247 errorProneDisabled
Trevor Radcliffed9b7f172023-08-09 22:21:38 +0000248 // TODO: b/294868620 - Remove when completing the bug
249 sanitizersEnabled
Liz Kammer9abd62d2021-05-21 08:37:59 -0400250)
251
Chris Parsons58852a02021-12-09 18:10:18 -0500252func osArchString(os string, arch string) string {
253 return fmt.Sprintf("%s_%s", os, arch)
254}
255
Liz Kammer9abd62d2021-05-21 08:37:59 -0400256func (ct configurationType) String() string {
257 return map[configurationType]string{
Alixc0dac522023-05-04 21:20:16 +0000258 noConfig: "no_config",
259 arch: "arch",
260 os: "os",
261 osArch: "arch_os",
262 productVariables: "product_variables",
263 osAndInApex: "os_in_apex",
264 inApex: "in_apex",
265 errorProneDisabled: "errorprone_disabled",
Trevor Radcliffed9b7f172023-08-09 22:21:38 +0000266 // TODO: b/294868620 - Remove when completing the bug
267 sanitizersEnabled: "sanitizers_enabled",
Liz Kammer9abd62d2021-05-21 08:37:59 -0400268 }[ct]
269}
270
271func (ct configurationType) validateConfig(config string) {
272 switch ct {
273 case noConfig:
274 if config != "" {
275 panic(fmt.Errorf("Cannot specify config with %s, but got %s", ct, config))
276 }
277 case arch:
278 if _, ok := platformArchMap[config]; !ok {
279 panic(fmt.Errorf("Unknown arch: %s", config))
280 }
281 case os:
282 if _, ok := platformOsMap[config]; !ok {
283 panic(fmt.Errorf("Unknown os: %s", config))
284 }
285 case osArch:
286 if _, ok := platformOsArchMap[config]; !ok {
287 panic(fmt.Errorf("Unknown os+arch: %s", config))
288 }
289 case productVariables:
290 // do nothing
Wei Li81852ca2022-07-27 00:22:06 -0700291 case osAndInApex:
Spandan Das4242f102023-04-19 22:31:54 +0000292 // do nothing
293 // this axis can contain additional per-apex keys
Vinh Tran85fb07c2022-09-16 16:17:48 -0400294 case inApex:
295 if _, ok := inApexMap[config]; !ok {
296 panic(fmt.Errorf("Unknown in_apex config: %s", config))
297 }
Alixc0dac522023-05-04 21:20:16 +0000298 case errorProneDisabled:
299 if _, ok := errorProneMap[config]; !ok {
300 panic(fmt.Errorf("Unknown errorprone config: %s", config))
301 }
Trevor Radcliffed9b7f172023-08-09 22:21:38 +0000302 // TODO: b/294868620 - Remove when completing the bug
303 case sanitizersEnabled:
304 if _, ok := sanitizersEnabledMap[config]; !ok {
305 panic(fmt.Errorf("Unknown sanitizers_enabled config: %s", config))
306 }
Liz Kammer9abd62d2021-05-21 08:37:59 -0400307 default:
308 panic(fmt.Errorf("Unrecognized ConfigurationType %d", ct))
309 }
310}
311
312// SelectKey returns the Bazel select key for a given configurationType and config string.
Jingwen Chena47f28d2021-11-02 16:43:57 +0000313func (ca ConfigurationAxis) SelectKey(config string) string {
314 ca.validateConfig(config)
315 switch ca.configurationType {
Liz Kammer9abd62d2021-05-21 08:37:59 -0400316 case noConfig:
317 panic(fmt.Errorf("SelectKey is unnecessary for noConfig ConfigurationType "))
318 case arch:
319 return platformArchMap[config]
320 case os:
321 return platformOsMap[config]
322 case osArch:
323 return platformOsArchMap[config]
324 case productVariables:
Cole Faust150f9a52023-04-26 10:52:24 -0700325 if config == ConditionsDefaultConfigKey {
Liz Kammer9abd62d2021-05-21 08:37:59 -0400326 return ConditionsDefaultSelectKey
327 }
Jingwen Chena47f28d2021-11-02 16:43:57 +0000328 return fmt.Sprintf("%s:%s", productVariableBazelPackage, config)
Wei Li81852ca2022-07-27 00:22:06 -0700329 case osAndInApex:
Spandan Das4242f102023-04-19 22:31:54 +0000330 if ret, exists := osAndInApexMap[config]; exists {
331 return ret
332 }
333 return config
Vinh Tran85fb07c2022-09-16 16:17:48 -0400334 case inApex:
335 return inApexMap[config]
Alixc0dac522023-05-04 21:20:16 +0000336 case errorProneDisabled:
337 return errorProneMap[config]
Trevor Radcliffed9b7f172023-08-09 22:21:38 +0000338 // TODO: b/294868620 - Remove when completing the bug
339 case sanitizersEnabled:
340 return sanitizersEnabledMap[config]
Liz Kammer9abd62d2021-05-21 08:37:59 -0400341 default:
Jingwen Chena47f28d2021-11-02 16:43:57 +0000342 panic(fmt.Errorf("Unrecognized ConfigurationType %d", ca.configurationType))
Liz Kammer9abd62d2021-05-21 08:37:59 -0400343 }
344}
345
346var (
347 // Indicating there is no configuration axis
348 NoConfigAxis = ConfigurationAxis{configurationType: noConfig}
349 // An axis for architecture-specific configurations
350 ArchConfigurationAxis = ConfigurationAxis{configurationType: arch}
351 // An axis for os-specific configurations
352 OsConfigurationAxis = ConfigurationAxis{configurationType: os}
353 // An axis for arch+os-specific configurations
354 OsArchConfigurationAxis = ConfigurationAxis{configurationType: osArch}
Wei Li81852ca2022-07-27 00:22:06 -0700355 // An axis for os+in_apex-specific configurations
356 OsAndInApexAxis = ConfigurationAxis{configurationType: osAndInApex}
Vinh Tran85fb07c2022-09-16 16:17:48 -0400357 // An axis for in_apex-specific configurations
358 InApexAxis = ConfigurationAxis{configurationType: inApex}
Alixc0dac522023-05-04 21:20:16 +0000359
360 ErrorProneAxis = ConfigurationAxis{configurationType: errorProneDisabled}
Trevor Radcliffed9b7f172023-08-09 22:21:38 +0000361
362 // TODO: b/294868620 - Remove when completing the bug
363 SanitizersEnabledAxis = ConfigurationAxis{configurationType: sanitizersEnabled}
Liz Kammer9abd62d2021-05-21 08:37:59 -0400364)
365
366// ProductVariableConfigurationAxis returns an axis for the given product variable
Cole Faust150f9a52023-04-26 10:52:24 -0700367func ProductVariableConfigurationAxis(archVariant bool, variable string) ConfigurationAxis {
Liz Kammer9abd62d2021-05-21 08:37:59 -0400368 return ConfigurationAxis{
369 configurationType: productVariables,
370 subType: variable,
Cole Faust150f9a52023-04-26 10:52:24 -0700371 archVariant: archVariant,
Liz Kammer9abd62d2021-05-21 08:37:59 -0400372 }
373}
374
375// ConfigurationAxis is an independent axis for configuration, there should be no overlap between
376// elements within an axis.
377type ConfigurationAxis struct {
378 configurationType
379 // some configuration types (e.g. productVariables) have multiple independent axes, subType helps
380 // distinguish between them without needing to list all 17 product variables.
381 subType string
Cole Faust150f9a52023-04-26 10:52:24 -0700382
383 archVariant bool
Liz Kammer9abd62d2021-05-21 08:37:59 -0400384}
385
386func (ca *ConfigurationAxis) less(other ConfigurationAxis) bool {
Chris Parsons7b3289b2023-01-26 17:30:44 -0500387 if ca.configurationType == other.configurationType {
388 return ca.subType < other.subType
Liz Kammer9abd62d2021-05-21 08:37:59 -0400389 }
Chris Parsons7b3289b2023-01-26 17:30:44 -0500390 return ca.configurationType < other.configurationType
Liz Kammer9abd62d2021-05-21 08:37:59 -0400391}