blob: 1993f76fc8a0c7e0250fd1c465e8069ca07d414a [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"
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 Cross528d67e2021-07-23 22:23:07 +000046 osArchLinuxMuslX86 = "linux_musl_x86"
47 osArchLinuxMuslX86_64 = "linux_musl_x86_64"
Liz Kammer9abd62d2021-05-21 08:37:59 -040048 osArchLinuxBionicArm64 = "linux_bionic_arm64"
49 osArchLinuxBionicX86_64 = "linux_bionic_x86_64"
50 osArchWindowsX86 = "windows_x86"
51 osArchWindowsX86_64 = "windows_x86_64"
52
53 // This is the string representation of the default condition wherever a
54 // configurable attribute is used in a select statement, i.e.
55 // //conditions:default for Bazel.
56 //
57 // This is consistently named "conditions_default" to mirror the Soong
58 // config variable default key in an Android.bp file, although there's no
59 // integration with Soong config variables (yet).
Chris Parsons51f8c392021-08-03 21:01:05 -040060 ConditionsDefaultConfigKey = "conditions_default"
Liz Kammer9abd62d2021-05-21 08:37:59 -040061
62 ConditionsDefaultSelectKey = "//conditions:default"
63
64 productVariableBazelPackage = "//build/bazel/product_variables"
65)
66
67var (
68 // These are the list of OSes and architectures with a Bazel config_setting
69 // and constraint value equivalent. These exist in arch.go, but the android
70 // package depends on the bazel package, so a cyclic dependency prevents
71 // using those variables here.
72
73 // A map of architectures to the Bazel label of the constraint_value
74 // for the @platforms//cpu:cpu constraint_setting
75 platformArchMap = map[string]string{
Chris Parsons51f8c392021-08-03 21:01:05 -040076 archArm: "//build/bazel/platforms/arch:arm",
77 archArm64: "//build/bazel/platforms/arch:arm64",
78 archX86: "//build/bazel/platforms/arch:x86",
79 archX86_64: "//build/bazel/platforms/arch:x86_64",
80 ConditionsDefaultConfigKey: ConditionsDefaultSelectKey, // The default condition of as arch select map.
Liz Kammer9abd62d2021-05-21 08:37:59 -040081 }
82
83 // A map of target operating systems to the Bazel label of the
84 // constraint_value for the @platforms//os:os constraint_setting
85 platformOsMap = map[string]string{
Chris Parsons51f8c392021-08-03 21:01:05 -040086 osAndroid: "//build/bazel/platforms/os:android",
87 osDarwin: "//build/bazel/platforms/os:darwin",
88 osLinux: "//build/bazel/platforms/os:linux",
89 osLinuxMusl: "//build/bazel/platforms/os:linux_musl",
90 osLinuxBionic: "//build/bazel/platforms/os:linux_bionic",
91 osWindows: "//build/bazel/platforms/os:windows",
92 ConditionsDefaultConfigKey: ConditionsDefaultSelectKey, // The default condition of an os select map.
Liz Kammer9abd62d2021-05-21 08:37:59 -040093 }
94
95 platformOsArchMap = map[string]string{
Chris Parsons51f8c392021-08-03 21:01:05 -040096 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",
Dan Willemsen8528f4e2021-10-19 00:22:06 -0700100 osArchDarwinArm64: "//build/bazel/platforms/os_arch:darwin_arm64",
Chris Parsons51f8c392021-08-03 21:01:05 -0400101 osArchDarwinX86_64: "//build/bazel/platforms/os_arch:darwin_x86_64",
102 osArchLinuxX86: "//build/bazel/platforms/os_arch:linux_glibc_x86",
103 osArchLinuxX86_64: "//build/bazel/platforms/os_arch:linux_glibc_x86_64",
104 osArchLinuxMuslX86: "//build/bazel/platforms/os_arch:linux_musl_x86",
105 osArchLinuxMuslX86_64: "//build/bazel/platforms/os_arch:linux_musl_x86_64",
106 osArchLinuxBionicArm64: "//build/bazel/platforms/os_arch:linux_bionic_arm64",
107 osArchLinuxBionicX86_64: "//build/bazel/platforms/os_arch:linux_bionic_x86_64",
108 osArchWindowsX86: "//build/bazel/platforms/os_arch:windows_x86",
109 osArchWindowsX86_64: "//build/bazel/platforms/os_arch:windows_x86_64",
110 ConditionsDefaultConfigKey: ConditionsDefaultSelectKey, // The default condition of an os select map.
Liz Kammer9abd62d2021-05-21 08:37:59 -0400111 }
112)
113
114// basic configuration types
115type configurationType int
116
117const (
118 noConfig configurationType = iota
119 arch
120 os
121 osArch
122 productVariables
123)
124
125func (ct configurationType) String() string {
126 return map[configurationType]string{
127 noConfig: "no_config",
128 arch: "arch",
129 os: "os",
130 osArch: "arch_os",
131 productVariables: "product_variables",
132 }[ct]
133}
134
135func (ct configurationType) validateConfig(config string) {
136 switch ct {
137 case noConfig:
138 if config != "" {
139 panic(fmt.Errorf("Cannot specify config with %s, but got %s", ct, config))
140 }
141 case arch:
142 if _, ok := platformArchMap[config]; !ok {
143 panic(fmt.Errorf("Unknown arch: %s", config))
144 }
145 case os:
146 if _, ok := platformOsMap[config]; !ok {
147 panic(fmt.Errorf("Unknown os: %s", config))
148 }
149 case osArch:
150 if _, ok := platformOsArchMap[config]; !ok {
151 panic(fmt.Errorf("Unknown os+arch: %s", config))
152 }
153 case productVariables:
154 // do nothing
155 default:
156 panic(fmt.Errorf("Unrecognized ConfigurationType %d", ct))
157 }
158}
159
160// SelectKey returns the Bazel select key for a given configurationType and config string.
Jingwen Chena47f28d2021-11-02 16:43:57 +0000161func (ca ConfigurationAxis) SelectKey(config string) string {
162 ca.validateConfig(config)
163 switch ca.configurationType {
Liz Kammer9abd62d2021-05-21 08:37:59 -0400164 case noConfig:
165 panic(fmt.Errorf("SelectKey is unnecessary for noConfig ConfigurationType "))
166 case arch:
167 return platformArchMap[config]
168 case os:
169 return platformOsMap[config]
170 case osArch:
171 return platformOsArchMap[config]
172 case productVariables:
Jingwen Chena47f28d2021-11-02 16:43:57 +0000173 if strings.HasSuffix(config, ConditionsDefaultConfigKey) {
174 // e.g. "acme__feature1__conditions_default" or "android__board__conditions_default"
Liz Kammer9abd62d2021-05-21 08:37:59 -0400175 return ConditionsDefaultSelectKey
176 }
Jingwen Chena47f28d2021-11-02 16:43:57 +0000177 return fmt.Sprintf("%s:%s", productVariableBazelPackage, config)
Liz Kammer9abd62d2021-05-21 08:37:59 -0400178 default:
Jingwen Chena47f28d2021-11-02 16:43:57 +0000179 panic(fmt.Errorf("Unrecognized ConfigurationType %d", ca.configurationType))
Liz Kammer9abd62d2021-05-21 08:37:59 -0400180 }
181}
182
183var (
184 // Indicating there is no configuration axis
185 NoConfigAxis = ConfigurationAxis{configurationType: noConfig}
186 // An axis for architecture-specific configurations
187 ArchConfigurationAxis = ConfigurationAxis{configurationType: arch}
188 // An axis for os-specific configurations
189 OsConfigurationAxis = ConfigurationAxis{configurationType: os}
190 // An axis for arch+os-specific configurations
191 OsArchConfigurationAxis = ConfigurationAxis{configurationType: osArch}
Liz Kammer9abd62d2021-05-21 08:37:59 -0400192)
193
194// ProductVariableConfigurationAxis returns an axis for the given product variable
195func ProductVariableConfigurationAxis(variable string) ConfigurationAxis {
196 return ConfigurationAxis{
197 configurationType: productVariables,
198 subType: variable,
199 }
200}
201
202// ConfigurationAxis is an independent axis for configuration, there should be no overlap between
203// elements within an axis.
204type ConfigurationAxis struct {
205 configurationType
206 // some configuration types (e.g. productVariables) have multiple independent axes, subType helps
207 // distinguish between them without needing to list all 17 product variables.
208 subType string
209}
210
211func (ca *ConfigurationAxis) less(other ConfigurationAxis) bool {
212 if ca.configurationType < other.configurationType {
213 return true
214 }
215 return ca.subType < other.subType
216}