Imported Upstream version 1.36.0
[platform/upstream/grpc.git] / bazel / grpc_build_system.bzl
1 # Copyright 2016 gRPC authors.
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
15 #
16 # This is for the gRPC build system. This isn't intended to be used outsite of
17 # the BUILD file for gRPC. It contains the mapping for the template system we
18 # use to generate other platform's build system files.
19 #
20 # Please consider that there should be a high bar for additions and changes to
21 # this file.
22 # Each rule listed must be re-written for Google's internal build system, and
23 # each change must be ported from one to the other.
24 #
25
26 load("//bazel:cc_grpc_library.bzl", "cc_grpc_library")
27 load("//bazel:copts.bzl", "GRPC_DEFAULT_COPTS")
28 load("@upb//bazel:upb_proto_library.bzl", "upb_proto_library")
29 load("@build_bazel_rules_apple//apple:ios.bzl", "ios_unit_test")
30
31 # The set of pollers to test against if a test exercises polling
32 POLLERS = ["epollex", "epoll1", "poll"]
33
34 def if_not_windows(a):
35     return select({
36         "//:windows": [],
37         "//:windows_msvc": [],
38         "//conditions:default": a,
39     })
40
41 def if_mac(a):
42     return select({
43         "//:mac_x86_64": a,
44         "//conditions:default": [],
45     })
46
47 def _get_external_deps(external_deps):
48     ret = []
49     for dep in external_deps:
50         if dep == "address_sorting":
51             ret += ["//third_party/address_sorting"]
52         elif dep == "cares":
53             ret += select({
54                 "//:grpc_no_ares": [],
55                 "//conditions:default": ["//external:cares"],
56             })
57         elif dep == "cronet_c_for_grpc":
58             ret += ["//third_party/objective_c/Cronet:cronet_c_for_grpc"]
59         elif dep.startswith("absl/"):
60             ret += ["@com_google_absl//" + dep]
61         else:
62             ret += ["//external:" + dep]
63     return ret
64
65 def grpc_cc_library(
66         name,
67         srcs = [],
68         public_hdrs = [],
69         hdrs = [],
70         external_deps = [],
71         defines = [],
72         deps = [],
73         select_deps = None,
74         standalone = False,
75         language = "C++",
76         testonly = False,
77         visibility = None,
78         alwayslink = 0,
79         data = [],
80         use_cfstream = False,
81         tags = []):
82     copts = []
83     if use_cfstream:
84         copts = if_mac(["-DGRPC_CFSTREAM"])
85     if language.upper() == "C":
86         copts = copts + if_not_windows(["-std=c99"])
87     linkopts = if_not_windows(["-pthread"])
88     if use_cfstream:
89         linkopts = linkopts + if_mac(["-framework CoreFoundation"])
90
91     if select_deps:
92         deps += select(select_deps)
93
94     native.cc_library(
95         name = name,
96         srcs = srcs,
97         defines = defines +
98                   select({
99                       "//:grpc_no_ares": ["GRPC_ARES=0"],
100                       "//conditions:default": [],
101                   }) +
102                   select({
103                       "//:remote_execution": ["GRPC_PORT_ISOLATED_RUNTIME=1"],
104                       "//conditions:default": [],
105                   }) +
106                   select({
107                       "//:grpc_allow_exceptions": ["GRPC_ALLOW_EXCEPTIONS=1"],
108                       "//:grpc_disallow_exceptions": ["GRPC_ALLOW_EXCEPTIONS=0"],
109                       "//conditions:default": [],
110                   }),
111         hdrs = hdrs + public_hdrs,
112         deps = deps + _get_external_deps(external_deps),
113         copts = GRPC_DEFAULT_COPTS + copts,
114         visibility = visibility,
115         testonly = testonly,
116         linkopts = linkopts,
117         includes = [
118             "include",
119             "src/core/ext/upb-generated",  # Once upb code-gen issue is resolved, remove this.
120             "src/core/ext/upbdefs-generated",  # Once upb code-gen issue is resolved, remove this.
121         ],
122         alwayslink = alwayslink,
123         data = data,
124         tags = tags,
125     )
126
127 def grpc_proto_plugin(name, srcs = [], deps = []):
128     native.cc_binary(
129         name = name,
130         srcs = srcs,
131         deps = deps,
132     )
133
134 def grpc_proto_library(
135         name,
136         srcs = [],
137         deps = [],
138         well_known_protos = False,
139         has_services = True,
140         use_external = False,
141         generate_mocks = False):
142     cc_grpc_library(
143         name = name,
144         srcs = srcs,
145         deps = deps,
146         well_known_protos = well_known_protos,
147         proto_only = not has_services,
148         use_external = use_external,
149         generate_mocks = generate_mocks,
150     )
151
152 def ios_cc_test(
153         name,
154         tags = [],
155         **kwargs):
156     ios_test_adapter = "//third_party/objective_c/google_toolbox_for_mac:GTM_GoogleTestRunner_GTM_USING_XCTEST"
157
158     test_lib_ios = name + "_test_lib_ios"
159     ios_tags = tags + ["manual", "ios_cc_test"]
160     if not any([t for t in tags if t.startswith("no_test_ios")]):
161         native.objc_library(
162             name = test_lib_ios,
163             srcs = kwargs.get("srcs"),
164             deps = kwargs.get("deps"),
165             copts = kwargs.get("copts"),
166             tags = ios_tags,
167             alwayslink = 1,
168             testonly = 1,
169         )
170         ios_test_deps = [ios_test_adapter, ":" + test_lib_ios]
171         ios_unit_test(
172             name = name + "_on_ios",
173             size = kwargs.get("size"),
174             tags = ios_tags,
175             minimum_os_version = "9.0",
176             deps = ios_test_deps,
177         )
178
179 def grpc_cc_test(name, srcs = [], deps = [], external_deps = [], args = [], data = [], uses_polling = True, language = "C++", size = "medium", timeout = None, tags = [], exec_compatible_with = [], exec_properties = {}, shard_count = None, flaky = None):
180     copts = if_mac(["-DGRPC_CFSTREAM"])
181     if language.upper() == "C":
182         copts = copts + if_not_windows(["-std=c99"])
183
184     # NOTE: these attributes won't be used for the poller-specific versions of a test
185     # automatically, you need to set them explicitly (if applicable)
186     args = {
187         "srcs": srcs,
188         "args": args,
189         "data": data,
190         "deps": deps + _get_external_deps(external_deps),
191         "copts": GRPC_DEFAULT_COPTS + copts,
192         "linkopts": if_not_windows(["-pthread"]),
193         "size": size,
194         "timeout": timeout,
195         "exec_compatible_with": exec_compatible_with,
196         "exec_properties": exec_properties,
197         "shard_count": shard_count,
198         "flaky": flaky,
199     }
200     if uses_polling:
201         # the vanilla version of the test should run on platforms that only
202         # support a single poller
203         native.cc_test(
204             name = name,
205             testonly = True,
206             tags = (tags + [
207                 "no_linux",  # linux supports multiple pollers
208             ]),
209             **args
210         )
211
212         # on linux we run the same test multiple times, once for each poller
213         for poller in POLLERS:
214             native.sh_test(
215                 name = name + "@poller=" + poller,
216                 data = [name] + data,
217                 srcs = [
218                     "//test/core/util:run_with_poller_sh",
219                 ],
220                 size = size,
221                 timeout = timeout,
222                 args = [
223                     poller,
224                     "$(location %s)" % name,
225                 ] + args["args"],
226                 tags = (tags + ["no_windows", "no_mac"]),
227                 exec_compatible_with = exec_compatible_with,
228                 exec_properties = exec_properties,
229                 shard_count = shard_count,
230                 flaky = flaky,
231             )
232     else:
233         # the test behavior doesn't depend on polling, just generate the test
234         native.cc_test(name = name, tags = tags + ["no_uses_polling"], **args)
235     ios_cc_test(
236         name = name,
237         tags = tags,
238         **args
239     )
240
241 def grpc_cc_binary(name, srcs = [], deps = [], external_deps = [], args = [], data = [], language = "C++", testonly = False, linkshared = False, linkopts = [], tags = [], features = []):
242     copts = []
243     if language.upper() == "C":
244         copts = ["-std=c99"]
245     native.cc_binary(
246         name = name,
247         srcs = srcs,
248         args = args,
249         data = data,
250         testonly = testonly,
251         linkshared = linkshared,
252         deps = deps + _get_external_deps(external_deps),
253         copts = GRPC_DEFAULT_COPTS + copts,
254         linkopts = if_not_windows(["-pthread"]) + linkopts,
255         tags = tags,
256         features = features,
257     )
258
259 def grpc_generate_one_off_targets():
260     # In open-source, grpc_objc* libraries depend directly on //:grpc
261     native.alias(
262         name = "grpc_objc",
263         actual = "//:grpc",
264     )
265
266 def grpc_generate_objc_one_off_targets():
267     pass
268
269 def grpc_sh_test(name, srcs, args = [], data = []):
270     native.sh_test(
271         name = name,
272         srcs = srcs,
273         args = args,
274         data = data,
275     )
276
277 def grpc_sh_binary(name, srcs, data = []):
278     native.sh_binary(
279         name = name,
280         srcs = srcs,
281         data = data,
282     )
283
284 def grpc_py_binary(
285         name,
286         srcs,
287         data = [],
288         deps = [],
289         external_deps = [],
290         testonly = False,
291         python_version = "PY2",
292         **kwargs):
293     native.py_binary(
294         name = name,
295         srcs = srcs,
296         testonly = testonly,
297         data = data,
298         deps = deps + _get_external_deps(external_deps),
299         python_version = python_version,
300         **kwargs
301     )
302
303 def grpc_package(name, visibility = "private", features = []):
304     if visibility == "tests":
305         visibility = ["//test:__subpackages__"]
306     elif visibility == "public":
307         visibility = ["//visibility:public"]
308     elif visibility == "private":
309         visibility = []
310     else:
311         fail("Unknown visibility " + visibility)
312
313     if len(visibility) != 0:
314         native.package(
315             default_visibility = visibility,
316             features = features,
317         )
318
319 def grpc_objc_library(
320         name,
321         srcs = [],
322         hdrs = [],
323         textual_hdrs = [],
324         data = [],
325         deps = [],
326         defines = [],
327         includes = [],
328         visibility = ["//visibility:public"]):
329     """The grpc version of objc_library, only used for the Objective-C library compilation
330
331     Args:
332         name: name of target
333         hdrs: public headers
334         srcs: all source files (.m)
335         textual_hdrs: private headers
336         data: any other bundle resources
337         defines: preprocessors
338         includes: added to search path, always [the path to objc directory]
339         deps: dependencies
340         visibility: visibility, default to public
341     """
342
343     native.objc_library(
344         name = name,
345         hdrs = hdrs,
346         srcs = srcs,
347         textual_hdrs = textual_hdrs,
348         data = data,
349         deps = deps,
350         defines = defines,
351         includes = includes,
352         visibility = visibility,
353     )
354
355 def grpc_upb_proto_library(name, deps):
356     upb_proto_library(name = name, deps = deps)
357
358 def python_config_settings():
359     native.config_setting(
360         name = "python3",
361         flag_values = {"@bazel_tools//tools/python:python_version": "PY3"},
362     )