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