forked from kubernetes/kubernetes
-
Notifications
You must be signed in to change notification settings - Fork 1
/
platforms.bzl
189 lines (179 loc) · 6.6 KB
/
platforms.bzl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
# Copyright 2019 The Kubernetes Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
load("@bazel_skylib//lib:new_sets.bzl", "sets")
load("@bazel_skylib//lib:types.bzl", "types")
# KUBE_SERVER_PLATFORMS in hack/lib/golang.sh
SERVER_PLATFORMS = {
"linux": [
"amd64",
"arm",
"arm64",
"ppc64le",
"s390x",
],
}
# KUBE_NODE_PLATFORMS in hack/lib/golang.sh
NODE_PLATFORMS = {
"linux": [
"amd64",
"arm",
"arm64",
"ppc64le",
"s390x",
],
"windows": [
"amd64",
],
}
# KUBE_CLIENT_PLATFORMS in hack/lib/golang.sh
CLIENT_PLATFORMS = {
"linux": [
"386",
"amd64",
"arm",
"arm64",
"ppc64le",
"s390x",
],
"darwin": [
"386",
"amd64",
],
"windows": [
"386",
"amd64",
],
}
# KUBE_TEST_PLATFORMS in hack/lib/golang.sh
TEST_PLATFORMS = {
"linux": [
"amd64",
"arm",
"arm64",
"s390x",
"ppc64le",
],
"darwin": [
"amd64",
],
"windows": [
"amd64",
],
}
# Helper which produces the ALL_PLATFORMS dictionary, composed of the union of
# CLIENT, NODE, SERVER, and TEST platforms
def _all_platforms():
all_platforms = {}
for platforms in [CLIENT_PLATFORMS, NODE_PLATFORMS, SERVER_PLATFORMS, TEST_PLATFORMS]:
for os, archs in platforms.items():
all_platforms[os] = sets.union(
all_platforms.setdefault(os, sets.make()),
sets.make(archs),
)
for os, archs in all_platforms.items():
all_platforms[os] = sets.to_list(archs)
return all_platforms
ALL_PLATFORMS = _all_platforms()
def go_platform_constraint(os, arch):
return "@io_bazel_rules_go//go/platform:%s_%s" % (os, arch)
# Helper to for_platforms which updates the select() dictionary.
# d is the dictionary being updated.
# value is the value to set for each item of platforms, which should
# be a single platform category dictionary (e.g. SERVER_PLATFORMS).
# only_os selects one of the OSes in platforms.
def _update_dict_for_platform_category(d, value, platforms, only_os = None):
if not value:
return
for os, arches in platforms.items():
if only_os and os != only_os:
continue
for arch in arches:
constraint = go_platform_constraint(os, arch)
fmt_args = {"OS": os, "ARCH": arch}
if types.is_list(value):
# Format all items in the list, and hope there are no duplicates
d.setdefault(constraint, []).extend(
[v.format(**fmt_args) for v in value],
)
else:
# Don't overwrite existing value
if constraint in d:
fail("duplicate entry for constraint %s", constraint)
if types.is_dict(value):
# Format dictionary values only
d[constraint] = {
dict_key: dict_value.format(**fmt_args)
for dict_key, dict_value in value.items()
}
else:
# Hopefully this is just a string
d[constraint] = value.format(**fmt_args)
# for_platforms returns a dictionary to be used with select().
# select() is used for configurable attributes (most attributes, notably
# excluding output filenames), and takes a dictionary mapping a condition
# to a value for that attribute.
# select() is described in more detail in the Bazel documentation:
# https://docs.bazel.build/versions/master/be/functions.html#select
#
# One notable condition is the target platform (os and arch).
# Kubernetes binaries generally target particular platform categories,
# such as client binaries like kubectl, or node binaries like kubelet.
# Additionally, some build artifacts need specific configurations such as
# the appropriate arch-specific base image.
#
# This macro produces a dictionary where each of the platform categories
# (client, node, server, test, all) is enumerated and filled in
# with the provided arguments as the values.
#
# For example, a filegroup might want to include one binary for all client
# platforms and another binary for server platforms. The client and server
# platform lists have some shared items but also some disjoint items.
# The client binary can be provided in for_client and the server binary provided
# in for_server; this macro will then return a select() dictionary that
# includes the appropriate binaries based on the configured platform.
#
# Another example selecting the appropriate base image for a docker container.
# One can use select(for_platforms(for_server="base-image-{ARCH}//image"))
# to have the appropriate arch-specific image selected.
#
# The for_platform arguments can be lists, dictionaries, or strings, but
# they should all be the same type for a given call.
# The tokens {OS} and {ARCH} will be substituted with the corresponding values,
# but if a dictionary is provided, only the dictionary values will be formatted.
#
# If default is provided, a default condition will be added with the provided
# value.
# only_os can be used to select a single OS from a platform category that lists
# multiple OSes. For example, it doesn't make sense to build debs or RPMs for
# anything besides Linux, so you might supply only_os="linux" for those rules.
#
# For a complete example, consult something like the release-tars target in
# build/release-tars/BUILD.
def for_platforms(
for_client = None,
for_node = None,
for_server = None,
for_test = None,
for_all = None,
default = None,
only_os = None):
d = {}
if default != None:
d["//conditions:default"] = default
_update_dict_for_platform_category(d, for_client, CLIENT_PLATFORMS, only_os)
_update_dict_for_platform_category(d, for_node, NODE_PLATFORMS, only_os)
_update_dict_for_platform_category(d, for_server, SERVER_PLATFORMS, only_os)
_update_dict_for_platform_category(d, for_test, TEST_PLATFORMS, only_os)
_update_dict_for_platform_category(d, for_all, ALL_PLATFORMS, only_os)
return d