grpc_build_system.bzl 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511
  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. # This is for the gRPC build system. This isn't intended to be used outsite of
  16. # the BUILD file for gRPC. It contains the mapping for the template system we
  17. # use to generate other platform's build system files.
  18. #
  19. # Please consider that there should be a high bar for additions and changes to
  20. # this file.
  21. # Each rule listed must be re-written for Google's internal build system, and
  22. # each change must be ported from one to the other.
  23. #
  24. """
  25. Contains macros used throughout the repo.
  26. """
  27. load("//bazel:cc_grpc_library.bzl", "cc_grpc_library")
  28. load("//bazel:copts.bzl", "GRPC_DEFAULT_COPTS")
  29. load("@upb//bazel:upb_proto_library.bzl", "upb_proto_library", "upb_proto_reflection_library")
  30. load("@build_bazel_rules_apple//apple:ios.bzl", "ios_unit_test")
  31. load("@build_bazel_rules_apple//apple/testing/default_runner:ios_test_runner.bzl", "ios_test_runner")
  32. # The set of pollers to test against if a test exercises polling
  33. POLLERS = ["epollex", "epoll1", "poll"]
  34. def if_not_windows(a):
  35. return select({
  36. "//:windows": [],
  37. "//:windows_msvc": [],
  38. "//conditions:default": a,
  39. })
  40. def if_windows(a):
  41. return select({
  42. "//:windows": a,
  43. "//:windows_msvc": a,
  44. "//conditions:default": [],
  45. })
  46. def if_mac(a):
  47. return select({
  48. "//:mac_x86_64": a,
  49. "//conditions:default": [],
  50. })
  51. def _get_external_deps(external_deps):
  52. ret = []
  53. for dep in external_deps:
  54. if dep == "address_sorting":
  55. ret.append("//third_party/address_sorting")
  56. elif dep == "xxhash":
  57. ret.append("//third_party/xxhash")
  58. elif dep == "cares":
  59. ret += select({
  60. "//:grpc_no_ares": [],
  61. "//conditions:default": ["//external:cares"],
  62. })
  63. elif dep == "cronet_c_for_grpc":
  64. ret.append("//third_party/objective_c/Cronet:cronet_c_for_grpc")
  65. elif dep.startswith("absl/"):
  66. ret.append("@com_google_absl//" + dep)
  67. else:
  68. ret.append("//external:" + dep)
  69. return ret
  70. def _update_visibility(visibility):
  71. if visibility == None:
  72. return None
  73. # Visibility rules prefixed with '@grpc_' are used to flag different visibility rule
  74. # classes upstream.
  75. PUBLIC = ["//visibility:public"]
  76. PRIVATE = ["//:__subpackages__"]
  77. VISIBILITY_TARGETS = {
  78. "alt_gpr_base_legacy": PRIVATE,
  79. "alt_grpc++_base_legacy": PRIVATE,
  80. "alt_grpc_base_legacy": PRIVATE,
  81. "alt_grpc++_base_unsecure_legacy": PRIVATE,
  82. "alts_frame_protector": PRIVATE,
  83. "channelz": PRIVATE,
  84. "client_channel": PRIVATE,
  85. "debug_location": PRIVATE,
  86. "endpoint_tests": PRIVATE,
  87. "grpclb": PRIVATE,
  88. "grpc_opencensus_plugin": PUBLIC,
  89. "grpc_resolver_fake": PRIVATE,
  90. "grpc++_test": PRIVATE,
  91. "httpcli": PRIVATE,
  92. "public": PUBLIC,
  93. "ref_counted_ptr": PRIVATE,
  94. "trace": PRIVATE,
  95. "tsi_interface": PRIVATE,
  96. "tsi": PRIVATE,
  97. "xds": PRIVATE,
  98. }
  99. final_visibility = []
  100. for rule in visibility:
  101. if rule.startswith("@grpc:"):
  102. for replacement in VISIBILITY_TARGETS[rule[len("@grpc:"):]]:
  103. final_visibility.append(replacement)
  104. else:
  105. final_visibility.append(rule)
  106. return [x for x in final_visibility]
  107. def grpc_cc_library(
  108. name,
  109. srcs = [],
  110. public_hdrs = [],
  111. hdrs = [],
  112. external_deps = [],
  113. defines = [],
  114. deps = [],
  115. select_deps = None,
  116. standalone = False,
  117. language = "C++",
  118. testonly = False,
  119. visibility = None,
  120. alwayslink = 0,
  121. data = [],
  122. use_cfstream = False,
  123. tags = [],
  124. linkstatic = False):
  125. """An internal wrapper around cc_library.
  126. Args:
  127. name: The name of the library.
  128. srcs: The source files.
  129. public_hdrs: The public headers.
  130. hdrs: The headers.
  131. external_deps: External depdendencies to be resolved.
  132. defines: Build defines to use.
  133. deps: cc_library deps.
  134. select_deps: deps included conditionally.
  135. standalone: Unused.
  136. language: The language of the library, e.g. C, C++.
  137. testonly: Whether the target is for tests only.
  138. visibility: The visibility of the target.
  139. alwayslink: Whether to enable alwayslink on the cc_library.
  140. data: Data dependencies.
  141. use_cfstream: Whether to use cfstream.
  142. tags: Tags to apply to the rule.
  143. linkstatic: Whether to enable linkstatic on the cc_library.
  144. """
  145. visibility = _update_visibility(visibility)
  146. copts = []
  147. if use_cfstream:
  148. copts = if_mac(["-DGRPC_CFSTREAM"])
  149. if language.upper() == "C":
  150. copts = copts + if_not_windows(["-std=c99"])
  151. linkopts = if_not_windows(["-pthread"]) + if_windows(["-defaultlib:ws2_32.lib"])
  152. if use_cfstream:
  153. linkopts = linkopts + if_mac(["-framework CoreFoundation"])
  154. if select_deps:
  155. for select_deps_entry in select_deps:
  156. deps += select(select_deps_entry)
  157. native.cc_library(
  158. name = name,
  159. srcs = srcs,
  160. defines = defines +
  161. select({
  162. "//:grpc_no_ares": ["GRPC_ARES=0"],
  163. "//conditions:default": [],
  164. }) +
  165. select({
  166. "//:remote_execution": ["GRPC_PORT_ISOLATED_RUNTIME=1"],
  167. "//conditions:default": [],
  168. }) +
  169. select({
  170. "//:grpc_allow_exceptions": ["GRPC_ALLOW_EXCEPTIONS=1"],
  171. "//:grpc_disallow_exceptions": ["GRPC_ALLOW_EXCEPTIONS=0"],
  172. "//conditions:default": [],
  173. }) +
  174. select({
  175. "//:use_abseil_status": ["GRPC_ERROR_IS_ABSEIL_STATUS=1"],
  176. "//conditions:default": [],
  177. }),
  178. hdrs = hdrs + public_hdrs,
  179. deps = deps + _get_external_deps(external_deps),
  180. copts = GRPC_DEFAULT_COPTS + copts,
  181. visibility = visibility,
  182. testonly = testonly,
  183. linkopts = linkopts,
  184. includes = [
  185. "include",
  186. "src/core/ext/upb-generated", # Once upb code-gen issue is resolved, remove this.
  187. "src/core/ext/upbdefs-generated", # Once upb code-gen issue is resolved, remove this.
  188. ],
  189. alwayslink = alwayslink,
  190. data = data,
  191. tags = tags,
  192. linkstatic = linkstatic,
  193. )
  194. def grpc_proto_plugin(name, srcs = [], deps = []):
  195. native.cc_binary(
  196. name = name,
  197. srcs = srcs,
  198. deps = deps,
  199. )
  200. def grpc_proto_library(
  201. name,
  202. srcs = [],
  203. deps = [],
  204. well_known_protos = False,
  205. has_services = True,
  206. use_external = False,
  207. generate_mocks = False):
  208. cc_grpc_library(
  209. name = name,
  210. srcs = srcs,
  211. deps = deps,
  212. well_known_protos = well_known_protos,
  213. proto_only = not has_services,
  214. use_external = use_external,
  215. generate_mocks = generate_mocks,
  216. )
  217. def ios_cc_test(
  218. name,
  219. tags = [],
  220. **kwargs):
  221. """An ios C++ test target.
  222. Args:
  223. name: The name of the test.
  224. tags: The tags to apply to the test.
  225. **kwargs: All other arguments to apply.
  226. """
  227. test_lib_ios = name + "_test_lib_ios"
  228. ios_tags = tags + ["manual", "ios_cc_test"]
  229. test_runner = "ios_x86_64_sim_runner_" + name
  230. ios_test_runner(
  231. name = test_runner,
  232. device_type = "iPhone X",
  233. )
  234. if not any([t for t in tags if t.startswith("no_test_ios")]):
  235. native.objc_library(
  236. name = test_lib_ios,
  237. srcs = kwargs.get("srcs"),
  238. deps = kwargs.get("deps"),
  239. copts = kwargs.get("copts"),
  240. data = kwargs.get("data"),
  241. tags = ios_tags,
  242. alwayslink = 1,
  243. testonly = 1,
  244. )
  245. ios_test_deps = [":" + test_lib_ios]
  246. ios_unit_test(
  247. name = name + "_on_ios",
  248. size = kwargs.get("size"),
  249. data = kwargs.get("data"),
  250. tags = ios_tags,
  251. minimum_os_version = "9.0",
  252. runner = test_runner,
  253. deps = ios_test_deps,
  254. )
  255. 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, copts = [], linkstatic = None):
  256. """A cc_test target for use in the gRPC repo.
  257. Args:
  258. name: The name of the test.
  259. srcs: The source files.
  260. deps: The target deps.
  261. external_deps: The external deps.
  262. args: The args to supply to the test binary.
  263. data: Data dependencies.
  264. uses_polling: Whether the test uses polling.
  265. language: The language of the test, e.g C, C++.
  266. size: The size of the test.
  267. timeout: The test timeout.
  268. tags: The tags for the test.
  269. exec_compatible_with: A list of constraint values that must be
  270. satisifed for the platform.
  271. exec_properties: A dictionary of strings that will be added to the
  272. exec_properties of a platform selected for this target.
  273. shard_count: The number of shards for this test.
  274. flaky: Whether this test is flaky.
  275. copts: Add these to the compiler invocation.
  276. linkstatic: link the binary in static mode
  277. """
  278. copts = copts + if_mac(["-DGRPC_CFSTREAM"])
  279. if language.upper() == "C":
  280. copts = copts + if_not_windows(["-std=c99"])
  281. # NOTE: these attributes won't be used for the poller-specific versions of a test
  282. # automatically, you need to set them explicitly (if applicable)
  283. args = {
  284. "srcs": srcs,
  285. "args": args,
  286. "data": data,
  287. "deps": deps + _get_external_deps(external_deps),
  288. "copts": GRPC_DEFAULT_COPTS + copts,
  289. "linkopts": if_not_windows(["-pthread"]) + if_windows(["-defaultlib:ws2_32.lib"]),
  290. "size": size,
  291. "timeout": timeout,
  292. "exec_compatible_with": exec_compatible_with,
  293. "exec_properties": exec_properties,
  294. "shard_count": shard_count,
  295. "flaky": flaky,
  296. "linkstatic": linkstatic,
  297. }
  298. if uses_polling:
  299. # the vanilla version of the test should run on platforms that only
  300. # support a single poller
  301. native.cc_test(
  302. name = name,
  303. testonly = True,
  304. tags = (tags + [
  305. "no_linux", # linux supports multiple pollers
  306. ]),
  307. **args
  308. )
  309. # on linux we run the same test multiple times, once for each poller
  310. for poller in POLLERS:
  311. native.sh_test(
  312. name = name + "@poller=" + poller,
  313. data = [name] + data,
  314. srcs = [
  315. "//test/core/util:run_with_poller_sh",
  316. ],
  317. size = size,
  318. timeout = timeout,
  319. args = [
  320. poller,
  321. "$(location %s)" % name,
  322. ] + args["args"],
  323. tags = (tags + ["no_windows", "no_mac"]),
  324. exec_compatible_with = exec_compatible_with,
  325. exec_properties = exec_properties,
  326. shard_count = shard_count,
  327. flaky = flaky,
  328. )
  329. else:
  330. # the test behavior doesn't depend on polling, just generate the test
  331. native.cc_test(name = name, tags = tags + ["no_uses_polling"], **args)
  332. ios_cc_test(
  333. name = name,
  334. tags = tags,
  335. **args
  336. )
  337. def grpc_cc_binary(name, srcs = [], deps = [], external_deps = [], args = [], data = [], language = "C++", testonly = False, linkshared = False, linkopts = [], tags = [], features = []):
  338. """Generates a cc_binary for use in the gRPC repo.
  339. Args:
  340. name: The name of the target.
  341. srcs: The source files.
  342. deps: The dependencies.
  343. external_deps: The external dependencies.
  344. args: The arguments to supply to the binary.
  345. data: The data dependencies.
  346. language: The language of the binary, e.g. C, C++.
  347. testonly: Whether the binary is for tests only.
  348. linkshared: Enables linkshared on the binary.
  349. linkopts: linkopts to supply to the cc_binary.
  350. tags: Tags to apply to the target.
  351. features: features to be supplied to the cc_binary.
  352. """
  353. copts = []
  354. if language.upper() == "C":
  355. copts = ["-std=c99"]
  356. native.cc_binary(
  357. name = name,
  358. srcs = srcs,
  359. args = args,
  360. data = data,
  361. testonly = testonly,
  362. linkshared = linkshared,
  363. deps = deps + _get_external_deps(external_deps),
  364. copts = GRPC_DEFAULT_COPTS + copts,
  365. linkopts = if_not_windows(["-pthread"]) + linkopts,
  366. tags = tags,
  367. features = features,
  368. )
  369. # buildifier: disable=unnamed-macro
  370. def grpc_generate_one_off_targets():
  371. # In open-source, grpc_objc* libraries depend directly on //:grpc
  372. native.alias(
  373. name = "grpc_objc",
  374. actual = "//:grpc",
  375. )
  376. def grpc_generate_objc_one_off_targets():
  377. pass
  378. def grpc_sh_test(name, srcs, args = [], data = [], tags = []):
  379. native.sh_test(
  380. name = name,
  381. srcs = srcs,
  382. args = args,
  383. data = data,
  384. tags = tags,
  385. )
  386. def grpc_sh_binary(name, srcs, data = []):
  387. native.sh_binary(
  388. name = name,
  389. srcs = srcs,
  390. data = data,
  391. )
  392. def grpc_py_binary(
  393. name,
  394. srcs,
  395. data = [],
  396. deps = [],
  397. external_deps = [],
  398. testonly = False,
  399. python_version = "PY2",
  400. **kwargs):
  401. native.py_binary(
  402. name = name,
  403. srcs = srcs,
  404. testonly = testonly,
  405. data = data,
  406. deps = deps + _get_external_deps(external_deps),
  407. python_version = python_version,
  408. **kwargs
  409. )
  410. def grpc_package(name, visibility = "private", features = []):
  411. """Creates a package.
  412. Args:
  413. name: The name of the target
  414. visibility: The visibility of the target.
  415. features: The features to enable.
  416. """
  417. if visibility == "tests":
  418. visibility = ["//test:__subpackages__"]
  419. elif visibility == "public":
  420. visibility = ["//visibility:public"]
  421. elif visibility == "private":
  422. visibility = []
  423. else:
  424. fail("Unknown visibility " + visibility)
  425. if len(visibility) != 0:
  426. # buildifier: disable=native-package
  427. native.package(
  428. default_visibility = visibility,
  429. features = features,
  430. )
  431. def grpc_objc_library(
  432. name,
  433. srcs = [],
  434. hdrs = [],
  435. textual_hdrs = [],
  436. data = [],
  437. deps = [],
  438. defines = [],
  439. includes = [],
  440. visibility = ["//visibility:public"]):
  441. """The grpc version of objc_library, only used for the Objective-C library compilation
  442. Args:
  443. name: name of target
  444. hdrs: public headers
  445. srcs: all source files (.m)
  446. textual_hdrs: private headers
  447. data: any other bundle resources
  448. defines: preprocessors
  449. includes: added to search path, always [the path to objc directory]
  450. deps: dependencies
  451. visibility: visibility, default to public
  452. """
  453. native.objc_library(
  454. name = name,
  455. hdrs = hdrs,
  456. srcs = srcs,
  457. textual_hdrs = textual_hdrs,
  458. data = data,
  459. deps = deps,
  460. defines = defines,
  461. includes = includes,
  462. visibility = visibility,
  463. )
  464. def grpc_upb_proto_library(name, deps):
  465. upb_proto_library(name = name, deps = deps)
  466. def grpc_upb_proto_reflection_library(name, deps):
  467. upb_proto_reflection_library(name = name, deps = deps)
  468. # buildifier: disable=unnamed-macro
  469. def python_config_settings():
  470. native.config_setting(
  471. name = "python3",
  472. flag_values = {"@bazel_tools//tools/python:python_version": "PY3"},
  473. )