blob: 35f194dfe8f2d225d14b02ee57410ac0f270dabd [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
30 osAndroid = "android"
31 osDarwin = "darwin"
32 osFuchsia = "fuchsia"
33 osLinux = "linux_glibc"
34 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"
42 osArchDarwinX86_64 = "darwin_x86_64"
43 osArchFuchsiaArm64 = "fuchsia_arm64"
44 osArchFuchsiaX86_64 = "fuchsia_x86_64"
45 osArchLinuxX86 = "linux_glibc_x86"
46 osArchLinuxX86_64 = "linux_glibc_x86_64"
47 osArchLinuxBionicArm64 = "linux_bionic_arm64"
48 osArchLinuxBionicX86_64 = "linux_bionic_x86_64"
49 osArchWindowsX86 = "windows_x86"
50 osArchWindowsX86_64 = "windows_x86_64"
51
52 // This is the string representation of the default condition wherever a
53 // configurable attribute is used in a select statement, i.e.
54 // //conditions:default for Bazel.
55 //
56 // This is consistently named "conditions_default" to mirror the Soong
57 // config variable default key in an Android.bp file, although there's no
58 // integration with Soong config variables (yet).
Liz Kammer74deed42021-06-02 13:02:03 -040059 conditionsDefault = "conditions_default"
Liz Kammer9abd62d2021-05-21 08:37:59 -040060
61 ConditionsDefaultSelectKey = "//conditions:default"
62
63 productVariableBazelPackage = "//build/bazel/product_variables"
64)
65
66var (
67 // These are the list of OSes and architectures with a Bazel config_setting
68 // and constraint value equivalent. These exist in arch.go, but the android
69 // package depends on the bazel package, so a cyclic dependency prevents
70 // using those variables here.
71
72 // A map of architectures to the Bazel label of the constraint_value
73 // for the @platforms//cpu:cpu constraint_setting
74 platformArchMap = map[string]string{
75 archArm: "//build/bazel/platforms/arch:arm",
76 archArm64: "//build/bazel/platforms/arch:arm64",
77 archX86: "//build/bazel/platforms/arch:x86",
78 archX86_64: "//build/bazel/platforms/arch:x86_64",
Liz Kammer74deed42021-06-02 13:02:03 -040079 conditionsDefault: ConditionsDefaultSelectKey, // The default condition of as arch select map.
Liz Kammer9abd62d2021-05-21 08:37:59 -040080 }
81
82 // A map of target operating systems to the Bazel label of the
83 // constraint_value for the @platforms//os:os constraint_setting
84 platformOsMap = map[string]string{
85 osAndroid: "//build/bazel/platforms/os:android",
86 osDarwin: "//build/bazel/platforms/os:darwin",
87 osFuchsia: "//build/bazel/platforms/os:fuchsia",
88 osLinux: "//build/bazel/platforms/os:linux",
89 osLinuxBionic: "//build/bazel/platforms/os:linux_bionic",
90 osWindows: "//build/bazel/platforms/os:windows",
Liz Kammer74deed42021-06-02 13:02:03 -040091 conditionsDefault: ConditionsDefaultSelectKey, // The default condition of an os select map.
Liz Kammer9abd62d2021-05-21 08:37:59 -040092 }
93
Liz Kammer01a16e82021-07-16 16:33:47 -040094 platformBionicMap = map[string]string{
95 "bionic": "//build/bazel/platforms/os:bionic",
96 conditionsDefault: ConditionsDefaultSelectKey, // The default condition of an os select map.
97 }
98
Liz Kammer9abd62d2021-05-21 08:37:59 -040099 platformOsArchMap = map[string]string{
100 osArchAndroidArm: "//build/bazel/platforms/os_arch:android_arm",
101 osArchAndroidArm64: "//build/bazel/platforms/os_arch:android_arm64",
102 osArchAndroidX86: "//build/bazel/platforms/os_arch:android_x86",
103 osArchAndroidX86_64: "//build/bazel/platforms/os_arch:android_x86_64",
104 osArchDarwinX86_64: "//build/bazel/platforms/os_arch:darwin_x86_64",
105 osArchFuchsiaArm64: "//build/bazel/platforms/os_arch:fuchsia_arm64",
106 osArchFuchsiaX86_64: "//build/bazel/platforms/os_arch:fuchsia_x86_64",
107 osArchLinuxX86: "//build/bazel/platforms/os_arch:linux_glibc_x86",
108 osArchLinuxX86_64: "//build/bazel/platforms/os_arch:linux_glibc_x86_64",
109 osArchLinuxBionicArm64: "//build/bazel/platforms/os_arch:linux_bionic_arm64",
110 osArchLinuxBionicX86_64: "//build/bazel/platforms/os_arch:linux_bionic_x86_64",
111 osArchWindowsX86: "//build/bazel/platforms/os_arch:windows_x86",
112 osArchWindowsX86_64: "//build/bazel/platforms/os_arch:windows_x86_64",
Liz Kammer74deed42021-06-02 13:02:03 -0400113 conditionsDefault: ConditionsDefaultSelectKey, // The default condition of an os select map.
Liz Kammer9abd62d2021-05-21 08:37:59 -0400114 }
115)
116
117// basic configuration types
118type configurationType int
119
120const (
121 noConfig configurationType = iota
122 arch
123 os
124 osArch
Liz Kammer01a16e82021-07-16 16:33:47 -0400125 bionic
Liz Kammer9abd62d2021-05-21 08:37:59 -0400126 productVariables
127)
128
129func (ct configurationType) String() string {
130 return map[configurationType]string{
131 noConfig: "no_config",
132 arch: "arch",
133 os: "os",
134 osArch: "arch_os",
Liz Kammer01a16e82021-07-16 16:33:47 -0400135 bionic: "bionic",
Liz Kammer9abd62d2021-05-21 08:37:59 -0400136 productVariables: "product_variables",
137 }[ct]
138}
139
140func (ct configurationType) validateConfig(config string) {
141 switch ct {
142 case noConfig:
143 if config != "" {
144 panic(fmt.Errorf("Cannot specify config with %s, but got %s", ct, config))
145 }
146 case arch:
147 if _, ok := platformArchMap[config]; !ok {
148 panic(fmt.Errorf("Unknown arch: %s", config))
149 }
150 case os:
151 if _, ok := platformOsMap[config]; !ok {
152 panic(fmt.Errorf("Unknown os: %s", config))
153 }
154 case osArch:
155 if _, ok := platformOsArchMap[config]; !ok {
156 panic(fmt.Errorf("Unknown os+arch: %s", config))
157 }
Liz Kammer01a16e82021-07-16 16:33:47 -0400158 case bionic:
159 if _, ok := platformBionicMap[config]; !ok {
160 panic(fmt.Errorf("Unknown for %s: %s", ct.String(), config))
161 }
Liz Kammer9abd62d2021-05-21 08:37:59 -0400162 case productVariables:
163 // do nothing
164 default:
165 panic(fmt.Errorf("Unrecognized ConfigurationType %d", ct))
166 }
167}
168
169// SelectKey returns the Bazel select key for a given configurationType and config string.
170func (ct configurationType) SelectKey(config string) string {
171 ct.validateConfig(config)
172 switch ct {
173 case noConfig:
174 panic(fmt.Errorf("SelectKey is unnecessary for noConfig ConfigurationType "))
175 case arch:
176 return platformArchMap[config]
177 case os:
178 return platformOsMap[config]
179 case osArch:
180 return platformOsArchMap[config]
Liz Kammer01a16e82021-07-16 16:33:47 -0400181 case bionic:
182 return platformBionicMap[config]
Liz Kammer9abd62d2021-05-21 08:37:59 -0400183 case productVariables:
Liz Kammer74deed42021-06-02 13:02:03 -0400184 if config == conditionsDefault {
Liz Kammer9abd62d2021-05-21 08:37:59 -0400185 return ConditionsDefaultSelectKey
186 }
187 return fmt.Sprintf("%s:%s", productVariableBazelPackage, strings.ToLower(config))
188 default:
189 panic(fmt.Errorf("Unrecognized ConfigurationType %d", ct))
190 }
191}
192
193var (
194 // Indicating there is no configuration axis
195 NoConfigAxis = ConfigurationAxis{configurationType: noConfig}
196 // An axis for architecture-specific configurations
197 ArchConfigurationAxis = ConfigurationAxis{configurationType: arch}
198 // An axis for os-specific configurations
199 OsConfigurationAxis = ConfigurationAxis{configurationType: os}
200 // An axis for arch+os-specific configurations
201 OsArchConfigurationAxis = ConfigurationAxis{configurationType: osArch}
Liz Kammer01a16e82021-07-16 16:33:47 -0400202 // An axis for bionic os-specific configurations
203 BionicConfigurationAxis = ConfigurationAxis{configurationType: bionic}
Liz Kammer9abd62d2021-05-21 08:37:59 -0400204)
205
206// ProductVariableConfigurationAxis returns an axis for the given product variable
207func ProductVariableConfigurationAxis(variable string) ConfigurationAxis {
208 return ConfigurationAxis{
209 configurationType: productVariables,
210 subType: variable,
211 }
212}
213
214// ConfigurationAxis is an independent axis for configuration, there should be no overlap between
215// elements within an axis.
216type ConfigurationAxis struct {
217 configurationType
218 // some configuration types (e.g. productVariables) have multiple independent axes, subType helps
219 // distinguish between them without needing to list all 17 product variables.
220 subType string
221}
222
223func (ca *ConfigurationAxis) less(other ConfigurationAxis) bool {
224 if ca.configurationType < other.configurationType {
225 return true
226 }
227 return ca.subType < other.subType
228}