blob: 3277bd049cfaeacd29df23a7614214250745fe1a [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"
Liz Kammer9abd62d2021-05-21 08:37:59 -040032 osLinux = "linux_glibc"
33 osLinuxBionic = "linux_bionic"
34 osWindows = "windows"
35
36 // Targets in arch.go
37 osArchAndroidArm = "android_arm"
38 osArchAndroidArm64 = "android_arm64"
39 osArchAndroidX86 = "android_x86"
40 osArchAndroidX86_64 = "android_x86_64"
41 osArchDarwinX86_64 = "darwin_x86_64"
Liz Kammer9abd62d2021-05-21 08:37:59 -040042 osArchLinuxX86 = "linux_glibc_x86"
43 osArchLinuxX86_64 = "linux_glibc_x86_64"
44 osArchLinuxBionicArm64 = "linux_bionic_arm64"
45 osArchLinuxBionicX86_64 = "linux_bionic_x86_64"
46 osArchWindowsX86 = "windows_x86"
47 osArchWindowsX86_64 = "windows_x86_64"
48
49 // This is the string representation of the default condition wherever a
50 // configurable attribute is used in a select statement, i.e.
51 // //conditions:default for Bazel.
52 //
53 // This is consistently named "conditions_default" to mirror the Soong
54 // config variable default key in an Android.bp file, although there's no
55 // integration with Soong config variables (yet).
Liz Kammer74deed42021-06-02 13:02:03 -040056 conditionsDefault = "conditions_default"
Liz Kammer9abd62d2021-05-21 08:37:59 -040057
58 ConditionsDefaultSelectKey = "//conditions:default"
59
60 productVariableBazelPackage = "//build/bazel/product_variables"
61)
62
63var (
64 // These are the list of OSes and architectures with a Bazel config_setting
65 // and constraint value equivalent. These exist in arch.go, but the android
66 // package depends on the bazel package, so a cyclic dependency prevents
67 // using those variables here.
68
69 // A map of architectures to the Bazel label of the constraint_value
70 // for the @platforms//cpu:cpu constraint_setting
71 platformArchMap = map[string]string{
72 archArm: "//build/bazel/platforms/arch:arm",
73 archArm64: "//build/bazel/platforms/arch:arm64",
74 archX86: "//build/bazel/platforms/arch:x86",
75 archX86_64: "//build/bazel/platforms/arch:x86_64",
Liz Kammer74deed42021-06-02 13:02:03 -040076 conditionsDefault: ConditionsDefaultSelectKey, // The default condition of as arch select map.
Liz Kammer9abd62d2021-05-21 08:37:59 -040077 }
78
79 // A map of target operating systems to the Bazel label of the
80 // constraint_value for the @platforms//os:os constraint_setting
81 platformOsMap = map[string]string{
82 osAndroid: "//build/bazel/platforms/os:android",
83 osDarwin: "//build/bazel/platforms/os:darwin",
Liz Kammer9abd62d2021-05-21 08:37:59 -040084 osLinux: "//build/bazel/platforms/os:linux",
85 osLinuxBionic: "//build/bazel/platforms/os:linux_bionic",
86 osWindows: "//build/bazel/platforms/os:windows",
Liz Kammer74deed42021-06-02 13:02:03 -040087 conditionsDefault: ConditionsDefaultSelectKey, // The default condition of an os select map.
Liz Kammer9abd62d2021-05-21 08:37:59 -040088 }
89
Liz Kammer01a16e82021-07-16 16:33:47 -040090 platformBionicMap = map[string]string{
91 "bionic": "//build/bazel/platforms/os:bionic",
92 conditionsDefault: ConditionsDefaultSelectKey, // The default condition of an os select map.
93 }
94
Liz Kammer9abd62d2021-05-21 08:37:59 -040095 platformOsArchMap = map[string]string{
96 osArchAndroidArm: "//build/bazel/platforms/os_arch:android_arm",
97 osArchAndroidArm64: "//build/bazel/platforms/os_arch:android_arm64",
98 osArchAndroidX86: "//build/bazel/platforms/os_arch:android_x86",
99 osArchAndroidX86_64: "//build/bazel/platforms/os_arch:android_x86_64",
100 osArchDarwinX86_64: "//build/bazel/platforms/os_arch:darwin_x86_64",
Liz Kammer9abd62d2021-05-21 08:37:59 -0400101 osArchLinuxX86: "//build/bazel/platforms/os_arch:linux_glibc_x86",
102 osArchLinuxX86_64: "//build/bazel/platforms/os_arch:linux_glibc_x86_64",
103 osArchLinuxBionicArm64: "//build/bazel/platforms/os_arch:linux_bionic_arm64",
104 osArchLinuxBionicX86_64: "//build/bazel/platforms/os_arch:linux_bionic_x86_64",
105 osArchWindowsX86: "//build/bazel/platforms/os_arch:windows_x86",
106 osArchWindowsX86_64: "//build/bazel/platforms/os_arch:windows_x86_64",
Liz Kammer74deed42021-06-02 13:02:03 -0400107 conditionsDefault: ConditionsDefaultSelectKey, // The default condition of an os select map.
Liz Kammer9abd62d2021-05-21 08:37:59 -0400108 }
109)
110
111// basic configuration types
112type configurationType int
113
114const (
115 noConfig configurationType = iota
116 arch
117 os
118 osArch
Liz Kammer01a16e82021-07-16 16:33:47 -0400119 bionic
Liz Kammer9abd62d2021-05-21 08:37:59 -0400120 productVariables
121)
122
123func (ct configurationType) String() string {
124 return map[configurationType]string{
125 noConfig: "no_config",
126 arch: "arch",
127 os: "os",
128 osArch: "arch_os",
Liz Kammer01a16e82021-07-16 16:33:47 -0400129 bionic: "bionic",
Liz Kammer9abd62d2021-05-21 08:37:59 -0400130 productVariables: "product_variables",
131 }[ct]
132}
133
134func (ct configurationType) validateConfig(config string) {
135 switch ct {
136 case noConfig:
137 if config != "" {
138 panic(fmt.Errorf("Cannot specify config with %s, but got %s", ct, config))
139 }
140 case arch:
141 if _, ok := platformArchMap[config]; !ok {
142 panic(fmt.Errorf("Unknown arch: %s", config))
143 }
144 case os:
145 if _, ok := platformOsMap[config]; !ok {
146 panic(fmt.Errorf("Unknown os: %s", config))
147 }
148 case osArch:
149 if _, ok := platformOsArchMap[config]; !ok {
150 panic(fmt.Errorf("Unknown os+arch: %s", config))
151 }
Liz Kammer01a16e82021-07-16 16:33:47 -0400152 case bionic:
153 if _, ok := platformBionicMap[config]; !ok {
154 panic(fmt.Errorf("Unknown for %s: %s", ct.String(), config))
155 }
Liz Kammer9abd62d2021-05-21 08:37:59 -0400156 case productVariables:
157 // do nothing
158 default:
159 panic(fmt.Errorf("Unrecognized ConfigurationType %d", ct))
160 }
161}
162
163// SelectKey returns the Bazel select key for a given configurationType and config string.
164func (ct configurationType) SelectKey(config string) string {
165 ct.validateConfig(config)
166 switch ct {
167 case noConfig:
168 panic(fmt.Errorf("SelectKey is unnecessary for noConfig ConfigurationType "))
169 case arch:
170 return platformArchMap[config]
171 case os:
172 return platformOsMap[config]
173 case osArch:
174 return platformOsArchMap[config]
Liz Kammer01a16e82021-07-16 16:33:47 -0400175 case bionic:
176 return platformBionicMap[config]
Liz Kammer9abd62d2021-05-21 08:37:59 -0400177 case productVariables:
Liz Kammer74deed42021-06-02 13:02:03 -0400178 if config == conditionsDefault {
Liz Kammer9abd62d2021-05-21 08:37:59 -0400179 return ConditionsDefaultSelectKey
180 }
181 return fmt.Sprintf("%s:%s", productVariableBazelPackage, strings.ToLower(config))
182 default:
183 panic(fmt.Errorf("Unrecognized ConfigurationType %d", ct))
184 }
185}
186
187var (
188 // Indicating there is no configuration axis
189 NoConfigAxis = ConfigurationAxis{configurationType: noConfig}
190 // An axis for architecture-specific configurations
191 ArchConfigurationAxis = ConfigurationAxis{configurationType: arch}
192 // An axis for os-specific configurations
193 OsConfigurationAxis = ConfigurationAxis{configurationType: os}
194 // An axis for arch+os-specific configurations
195 OsArchConfigurationAxis = ConfigurationAxis{configurationType: osArch}
Liz Kammer01a16e82021-07-16 16:33:47 -0400196 // An axis for bionic os-specific configurations
197 BionicConfigurationAxis = ConfigurationAxis{configurationType: bionic}
Liz Kammer9abd62d2021-05-21 08:37:59 -0400198)
199
200// ProductVariableConfigurationAxis returns an axis for the given product variable
201func ProductVariableConfigurationAxis(variable string) ConfigurationAxis {
202 return ConfigurationAxis{
203 configurationType: productVariables,
204 subType: variable,
205 }
206}
207
208// ConfigurationAxis is an independent axis for configuration, there should be no overlap between
209// elements within an axis.
210type ConfigurationAxis struct {
211 configurationType
212 // some configuration types (e.g. productVariables) have multiple independent axes, subType helps
213 // distinguish between them without needing to list all 17 product variables.
214 subType string
215}
216
217func (ca *ConfigurationAxis) less(other ConfigurationAxis) bool {
218 if ca.configurationType < other.configurationType {
219 return true
220 }
221 return ca.subType < other.subType
222}