blob: 2c9a5364a3908954bd5a9b0060cd0c9c4fbdc2d7 [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"
Spandan Das1f65f9e2023-09-15 01:08:23 +000074 Unbundled_app = "unbundled_app"
Vinh Tran85fb07c2022-09-16 16:17:48 -040075
76 InApex = "in_apex"
77 NonApex = "non_apex"
Alixc0dac522023-05-04 21:20:16 +000078
79 ErrorproneDisabled = "errorprone_disabled"
Trevor Radcliffed9b7f172023-08-09 22:21:38 +000080 // TODO: b/294868620 - Remove when completing the bug
81 SanitizersEnabled = "sanitizers_enabled"
Liz Kammer9abd62d2021-05-21 08:37:59 -040082)
83
Cole Faustc843b992022-08-02 18:06:50 -070084func PowerSetWithoutEmptySet[T any](items []T) [][]T {
85 resultSize := int(math.Pow(2, float64(len(items))))
86 powerSet := make([][]T, 0, resultSize-1)
87 for i := 1; i < resultSize; i++ {
88 combination := make([]T, 0)
89 for j := 0; j < len(items); j++ {
90 if (i>>j)%2 == 1 {
91 combination = append(combination, items[j])
92 }
93 }
94 powerSet = append(powerSet, combination)
95 }
96 return powerSet
97}
98
99func createPlatformArchMap() map[string]string {
100 // Copy of archFeatures from android/arch_list.go because the bazel
101 // package can't access the android package
102 archFeatures := map[string][]string{
103 "arm": {
104 "neon",
105 },
106 "arm64": {
107 "dotprod",
108 },
Colin Crossf05b0d32022-07-14 18:10:34 -0700109 "riscv64": {},
Cole Faustc843b992022-08-02 18:06:50 -0700110 "x86": {
111 "ssse3",
112 "sse4",
113 "sse4_1",
114 "sse4_2",
115 "aes_ni",
116 "avx",
117 "avx2",
118 "avx512",
119 "popcnt",
120 "movbe",
121 },
122 "x86_64": {
123 "ssse3",
124 "sse4",
125 "sse4_1",
126 "sse4_2",
127 "aes_ni",
128 "avx",
129 "avx2",
130 "avx512",
131 "popcnt",
132 },
133 }
134 result := make(map[string]string)
135 for arch, allFeatures := range archFeatures {
Jingwen Chen9c2e3ee2023-10-11 10:51:28 +0000136 result[arch] = "//build/bazel_common_rules/platforms/arch:" + arch
Cole Faustc843b992022-08-02 18:06:50 -0700137 // Sometimes we want to select on multiple features being active, so
138 // add the power set of all possible features to the map. More details
139 // in android.ModuleBase.GetArchVariantProperties
140 for _, features := range PowerSetWithoutEmptySet(allFeatures) {
141 sort.Strings(features)
142 archFeaturesName := arch + "-" + strings.Join(features, "-")
143 result[archFeaturesName] = "//build/bazel/platforms/arch/variants:" + archFeaturesName
144 }
145 }
146 result[ConditionsDefaultConfigKey] = ConditionsDefaultSelectKey
147 return result
148}
149
Liz Kammer9abd62d2021-05-21 08:37:59 -0400150var (
151 // These are the list of OSes and architectures with a Bazel config_setting
152 // and constraint value equivalent. These exist in arch.go, but the android
153 // package depends on the bazel package, so a cyclic dependency prevents
154 // using those variables here.
155
156 // A map of architectures to the Bazel label of the constraint_value
157 // for the @platforms//cpu:cpu constraint_setting
Cole Faustc843b992022-08-02 18:06:50 -0700158 platformArchMap = createPlatformArchMap()
Liz Kammer9abd62d2021-05-21 08:37:59 -0400159
160 // A map of target operating systems to the Bazel label of the
161 // constraint_value for the @platforms//os:os constraint_setting
162 platformOsMap = map[string]string{
Jingwen Chen9c2e3ee2023-10-11 10:51:28 +0000163 OsAndroid: "//build/bazel_common_rules/platforms/os:android",
164 OsDarwin: "//build/bazel_common_rules/platforms/os:darwin",
165 OsLinux: "//build/bazel_common_rules/platforms/os:linux_glibc",
166 osLinuxMusl: "//build/bazel_common_rules/platforms/os:linux_musl",
167 osLinuxBionic: "//build/bazel_common_rules/platforms/os:linux_bionic",
168 OsWindows: "//build/bazel_common_rules/platforms/os:windows",
Chris Parsons51f8c392021-08-03 21:01:05 -0400169 ConditionsDefaultConfigKey: ConditionsDefaultSelectKey, // The default condition of an os select map.
Liz Kammer9abd62d2021-05-21 08:37:59 -0400170 }
171
172 platformOsArchMap = map[string]string{
Jingwen Chen9c2e3ee2023-10-11 10:51:28 +0000173 osArchAndroidArm: "//build/bazel_common_rules/platforms/os_arch:android_arm",
174 OsArchAndroidArm64: "//build/bazel_common_rules/platforms/os_arch:android_arm64",
175 osArchAndroidRiscv64: "//build/bazel_common_rules/platforms/os_arch:android_riscv64",
176 osArchAndroidX86: "//build/bazel_common_rules/platforms/os_arch:android_x86",
177 osArchAndroidX86_64: "//build/bazel_common_rules/platforms/os_arch:android_x86_64",
178 osArchDarwinArm64: "//build/bazel_common_rules/platforms/os_arch:darwin_arm64",
179 osArchDarwinX86_64: "//build/bazel_common_rules/platforms/os_arch:darwin_x86_64",
180 osArchLinuxX86: "//build/bazel_common_rules/platforms/os_arch:linux_glibc_x86",
181 osArchLinuxX86_64: "//build/bazel_common_rules/platforms/os_arch:linux_glibc_x86_64",
182 osArchLinuxMuslArm: "//build/bazel_common_rules/platforms/os_arch:linux_musl_arm",
183 osArchLinuxMuslArm64: "//build/bazel_common_rules/platforms/os_arch:linux_musl_arm64",
184 osArchLinuxMuslX86: "//build/bazel_common_rules/platforms/os_arch:linux_musl_x86",
185 osArchLinuxMuslX86_64: "//build/bazel_common_rules/platforms/os_arch:linux_musl_x86_64",
186 osArchLinuxBionicArm64: "//build/bazel_common_rules/platforms/os_arch:linux_bionic_arm64",
187 osArchLinuxBionicX86_64: "//build/bazel_common_rules/platforms/os_arch:linux_bionic_x86_64",
188 osArchWindowsX86: "//build/bazel_common_rules/platforms/os_arch:windows_x86",
189 osArchWindowsX86_64: "//build/bazel_common_rules/platforms/os_arch:windows_x86_64",
Chris Parsons51f8c392021-08-03 21:01:05 -0400190 ConditionsDefaultConfigKey: ConditionsDefaultSelectKey, // The default condition of an os select map.
Liz Kammer9abd62d2021-05-21 08:37:59 -0400191 }
Chris Parsons58852a02021-12-09 18:10:18 -0500192
193 // Map where keys are OsType names, and values are slices containing the archs
194 // that that OS supports.
195 // These definitions copied from arch.go.
196 // TODO(cparsons): Source from arch.go; this task is nontrivial, as it currently results
197 // in a cyclic dependency.
198 osToArchMap = map[string][]string{
Colin Crossf05b0d32022-07-14 18:10:34 -0700199 OsAndroid: {archArm, archArm64, archRiscv64, archX86, archX86_64},
Spandan Dasfb04c412023-05-15 18:35:36 +0000200 OsLinux: {archX86, archX86_64},
Chris Parsons58852a02021-12-09 18:10:18 -0500201 osLinuxMusl: {archX86, archX86_64},
Spandan Dasfb04c412023-05-15 18:35:36 +0000202 OsDarwin: {archArm64, archX86_64},
Chris Parsons58852a02021-12-09 18:10:18 -0500203 osLinuxBionic: {archArm64, archX86_64},
204 // TODO(cparsons): According to arch.go, this should contain archArm, archArm64, as well.
Spandan Dasfb04c412023-05-15 18:35:36 +0000205 OsWindows: {archX86, archX86_64},
Chris Parsons58852a02021-12-09 18:10:18 -0500206 }
Wei Li81852ca2022-07-27 00:22:06 -0700207
208 osAndInApexMap = map[string]string{
209 AndroidAndInApex: "//build/bazel/rules/apex:android-in_apex",
Spandan Das6d4d9da2023-04-18 06:20:40 +0000210 AndroidPlatform: "//build/bazel/rules/apex:system",
Spandan Das1f65f9e2023-09-15 01:08:23 +0000211 Unbundled_app: "//build/bazel/rules/apex:unbundled_app",
Jingwen Chen9c2e3ee2023-10-11 10:51:28 +0000212 OsDarwin: "//build/bazel_common_rules/platforms/os:darwin",
213 OsLinux: "//build/bazel_common_rules/platforms/os:linux_glibc",
214 osLinuxMusl: "//build/bazel_common_rules/platforms/os:linux_musl",
215 osLinuxBionic: "//build/bazel_common_rules/platforms/os:linux_bionic",
216 OsWindows: "//build/bazel_common_rules/platforms/os:windows",
Wei Li81852ca2022-07-27 00:22:06 -0700217 ConditionsDefaultConfigKey: ConditionsDefaultSelectKey,
218 }
Vinh Tran85fb07c2022-09-16 16:17:48 -0400219
220 inApexMap = map[string]string{
221 InApex: "//build/bazel/rules/apex:in_apex",
222 NonApex: "//build/bazel/rules/apex:non_apex",
223 ConditionsDefaultConfigKey: ConditionsDefaultSelectKey,
224 }
Alixc0dac522023-05-04 21:20:16 +0000225
226 errorProneMap = map[string]string{
227 ErrorproneDisabled: "//build/bazel/rules/java/errorprone:errorprone_globally_disabled",
228 ConditionsDefaultConfigKey: ConditionsDefaultSelectKey,
229 }
Trevor Radcliffed9b7f172023-08-09 22:21:38 +0000230
231 // TODO: b/294868620 - Remove when completing the bug
232 sanitizersEnabledMap = map[string]string{
233 SanitizersEnabled: "//build/bazel/rules/cc:sanitizers_enabled",
234 ConditionsDefaultConfigKey: ConditionsDefaultSelectKey,
235 }
Liz Kammer9abd62d2021-05-21 08:37:59 -0400236)
237
238// basic configuration types
239type configurationType int
240
241const (
242 noConfig configurationType = iota
243 arch
244 os
245 osArch
246 productVariables
Wei Li81852ca2022-07-27 00:22:06 -0700247 osAndInApex
Vinh Tran85fb07c2022-09-16 16:17:48 -0400248 inApex
Alixc0dac522023-05-04 21:20:16 +0000249 errorProneDisabled
Trevor Radcliffed9b7f172023-08-09 22:21:38 +0000250 // TODO: b/294868620 - Remove when completing the bug
251 sanitizersEnabled
Liz Kammer9abd62d2021-05-21 08:37:59 -0400252)
253
Chris Parsons58852a02021-12-09 18:10:18 -0500254func osArchString(os string, arch string) string {
255 return fmt.Sprintf("%s_%s", os, arch)
256}
257
Liz Kammer9abd62d2021-05-21 08:37:59 -0400258func (ct configurationType) String() string {
259 return map[configurationType]string{
Alixc0dac522023-05-04 21:20:16 +0000260 noConfig: "no_config",
261 arch: "arch",
262 os: "os",
263 osArch: "arch_os",
264 productVariables: "product_variables",
265 osAndInApex: "os_in_apex",
266 inApex: "in_apex",
267 errorProneDisabled: "errorprone_disabled",
Trevor Radcliffed9b7f172023-08-09 22:21:38 +0000268 // TODO: b/294868620 - Remove when completing the bug
269 sanitizersEnabled: "sanitizers_enabled",
Liz Kammer9abd62d2021-05-21 08:37:59 -0400270 }[ct]
271}
272
273func (ct configurationType) validateConfig(config string) {
274 switch ct {
275 case noConfig:
276 if config != "" {
277 panic(fmt.Errorf("Cannot specify config with %s, but got %s", ct, config))
278 }
279 case arch:
280 if _, ok := platformArchMap[config]; !ok {
281 panic(fmt.Errorf("Unknown arch: %s", config))
282 }
283 case os:
284 if _, ok := platformOsMap[config]; !ok {
285 panic(fmt.Errorf("Unknown os: %s", config))
286 }
287 case osArch:
288 if _, ok := platformOsArchMap[config]; !ok {
289 panic(fmt.Errorf("Unknown os+arch: %s", config))
290 }
291 case productVariables:
292 // do nothing
Wei Li81852ca2022-07-27 00:22:06 -0700293 case osAndInApex:
Spandan Das4242f102023-04-19 22:31:54 +0000294 // do nothing
295 // this axis can contain additional per-apex keys
Vinh Tran85fb07c2022-09-16 16:17:48 -0400296 case inApex:
297 if _, ok := inApexMap[config]; !ok {
298 panic(fmt.Errorf("Unknown in_apex config: %s", config))
299 }
Alixc0dac522023-05-04 21:20:16 +0000300 case errorProneDisabled:
301 if _, ok := errorProneMap[config]; !ok {
302 panic(fmt.Errorf("Unknown errorprone config: %s", config))
303 }
Trevor Radcliffed9b7f172023-08-09 22:21:38 +0000304 // TODO: b/294868620 - Remove when completing the bug
305 case sanitizersEnabled:
306 if _, ok := sanitizersEnabledMap[config]; !ok {
307 panic(fmt.Errorf("Unknown sanitizers_enabled config: %s", config))
308 }
Liz Kammer9abd62d2021-05-21 08:37:59 -0400309 default:
310 panic(fmt.Errorf("Unrecognized ConfigurationType %d", ct))
311 }
312}
313
314// SelectKey returns the Bazel select key for a given configurationType and config string.
Jingwen Chena47f28d2021-11-02 16:43:57 +0000315func (ca ConfigurationAxis) SelectKey(config string) string {
316 ca.validateConfig(config)
317 switch ca.configurationType {
Liz Kammer9abd62d2021-05-21 08:37:59 -0400318 case noConfig:
319 panic(fmt.Errorf("SelectKey is unnecessary for noConfig ConfigurationType "))
320 case arch:
321 return platformArchMap[config]
322 case os:
323 return platformOsMap[config]
324 case osArch:
325 return platformOsArchMap[config]
326 case productVariables:
Cole Faust150f9a52023-04-26 10:52:24 -0700327 if config == ConditionsDefaultConfigKey {
Liz Kammer9abd62d2021-05-21 08:37:59 -0400328 return ConditionsDefaultSelectKey
329 }
Jingwen Chena47f28d2021-11-02 16:43:57 +0000330 return fmt.Sprintf("%s:%s", productVariableBazelPackage, config)
Wei Li81852ca2022-07-27 00:22:06 -0700331 case osAndInApex:
Spandan Das4242f102023-04-19 22:31:54 +0000332 if ret, exists := osAndInApexMap[config]; exists {
333 return ret
334 }
335 return config
Vinh Tran85fb07c2022-09-16 16:17:48 -0400336 case inApex:
337 return inApexMap[config]
Alixc0dac522023-05-04 21:20:16 +0000338 case errorProneDisabled:
339 return errorProneMap[config]
Trevor Radcliffed9b7f172023-08-09 22:21:38 +0000340 // TODO: b/294868620 - Remove when completing the bug
341 case sanitizersEnabled:
342 return sanitizersEnabledMap[config]
Liz Kammer9abd62d2021-05-21 08:37:59 -0400343 default:
Jingwen Chena47f28d2021-11-02 16:43:57 +0000344 panic(fmt.Errorf("Unrecognized ConfigurationType %d", ca.configurationType))
Liz Kammer9abd62d2021-05-21 08:37:59 -0400345 }
346}
347
348var (
349 // Indicating there is no configuration axis
350 NoConfigAxis = ConfigurationAxis{configurationType: noConfig}
351 // An axis for architecture-specific configurations
352 ArchConfigurationAxis = ConfigurationAxis{configurationType: arch}
353 // An axis for os-specific configurations
354 OsConfigurationAxis = ConfigurationAxis{configurationType: os}
355 // An axis for arch+os-specific configurations
356 OsArchConfigurationAxis = ConfigurationAxis{configurationType: osArch}
Wei Li81852ca2022-07-27 00:22:06 -0700357 // An axis for os+in_apex-specific configurations
358 OsAndInApexAxis = ConfigurationAxis{configurationType: osAndInApex}
Vinh Tran85fb07c2022-09-16 16:17:48 -0400359 // An axis for in_apex-specific configurations
360 InApexAxis = ConfigurationAxis{configurationType: inApex}
Alixc0dac522023-05-04 21:20:16 +0000361
362 ErrorProneAxis = ConfigurationAxis{configurationType: errorProneDisabled}
Trevor Radcliffed9b7f172023-08-09 22:21:38 +0000363
364 // TODO: b/294868620 - Remove when completing the bug
365 SanitizersEnabledAxis = ConfigurationAxis{configurationType: sanitizersEnabled}
Liz Kammer9abd62d2021-05-21 08:37:59 -0400366)
367
368// ProductVariableConfigurationAxis returns an axis for the given product variable
Cole Faust150f9a52023-04-26 10:52:24 -0700369func ProductVariableConfigurationAxis(archVariant bool, variable string) ConfigurationAxis {
Liz Kammer9abd62d2021-05-21 08:37:59 -0400370 return ConfigurationAxis{
371 configurationType: productVariables,
372 subType: variable,
Cole Faust150f9a52023-04-26 10:52:24 -0700373 archVariant: archVariant,
Liz Kammer9abd62d2021-05-21 08:37:59 -0400374 }
375}
376
377// ConfigurationAxis is an independent axis for configuration, there should be no overlap between
378// elements within an axis.
379type ConfigurationAxis struct {
380 configurationType
381 // some configuration types (e.g. productVariables) have multiple independent axes, subType helps
382 // distinguish between them without needing to list all 17 product variables.
383 subType string
Cole Faust150f9a52023-04-26 10:52:24 -0700384
385 archVariant bool
Liz Kammer9abd62d2021-05-21 08:37:59 -0400386}
387
388func (ca *ConfigurationAxis) less(other ConfigurationAxis) bool {
Chris Parsons7b3289b2023-01-26 17:30:44 -0500389 if ca.configurationType == other.configurationType {
390 return ca.subType < other.subType
Liz Kammer9abd62d2021-05-21 08:37:59 -0400391 }
Chris Parsons7b3289b2023-01-26 17:30:44 -0500392 return ca.configurationType < other.configurationType
Liz Kammer9abd62d2021-05-21 08:37:59 -0400393}