1 # Platform-specific build configurations. 2 3 load("@protobuf_archive//:protobuf.bzl", "proto_gen") 4 load("@protobuf_archive//:protobuf.bzl", "py_proto_library") 5 load("//tensorflow:tensorflow.bzl", "if_not_mobile") 6 load("//tensorflow:tensorflow.bzl", "if_windows") 7 load("//tensorflow:tensorflow.bzl", "if_not_windows") 8 load("//tensorflow/core:platform/default/build_config_root.bzl", "if_static") 9 load("@local_config_cuda//cuda:build_defs.bzl", "if_cuda") 10 load( 11 "//third_party/mkl:build_defs.bzl", 12 "if_mkl", 13 ) 14 15 # Appends a suffix to a list of deps. 16 def tf_deps(deps, suffix): 17 tf_deps = [] 18 19 # If the package name is in shorthand form (ie: does not contain a ':'), 20 # expand it to the full name. 21 for dep in deps: 22 tf_dep = dep 23 24 if not ":" in dep: 25 dep_pieces = dep.split("/") 26 tf_dep += ":" + dep_pieces[len(dep_pieces) - 1] 27 28 tf_deps += [tf_dep + suffix] 29 30 return tf_deps 31 32 # Modified from @cython//:Tools/rules.bzl 33 def pyx_library( 34 name, 35 deps=[], 36 py_deps=[], 37 srcs=[], 38 **kwargs): 39 """Compiles a group of .pyx / .pxd / .py files. 40 41 First runs Cython to create .cpp files for each input .pyx or .py + .pxd 42 pair. Then builds a shared object for each, passing "deps" to each cc_binary 43 rule (includes Python headers by default). Finally, creates a py_library rule 44 with the shared objects and any pure Python "srcs", with py_deps as its 45 dependencies; the shared objects can be imported like normal Python files. 46 47 Args: 48 name: Name for the rule. 49 deps: C/C++ dependencies of the Cython (e.g. Numpy headers). 50 py_deps: Pure Python dependencies of the final library. 51 srcs: .py, .pyx, or .pxd files to either compile or pass through. 52 **kwargs: Extra keyword arguments passed to the py_library. 53 """ 54 # First filter out files that should be run compiled vs. passed through. 55 py_srcs = [] 56 pyx_srcs = [] 57 pxd_srcs = [] 58 for src in srcs: 59 if src.endswith(".pyx") or (src.endswith(".py") 60 and src[:-3] + ".pxd" in srcs): 61 pyx_srcs.append(src) 62 elif src.endswith(".py"): 63 py_srcs.append(src) 64 else: 65 pxd_srcs.append(src) 66 if src.endswith("__init__.py"): 67 pxd_srcs.append(src) 68 69 # Invoke cython to produce the shared object libraries. 70 for filename in pyx_srcs: 71 native.genrule( 72 name = filename + "_cython_translation", 73 srcs = [filename], 74 outs = [filename.split(".")[0] + ".cpp"], 75 cmd = "PYTHONHASHSEED=0 $(location @cython//:cython_binary) --cplus $(SRCS) --output-file $(OUTS)", 76 tools = ["@cython//:cython_binary"] + pxd_srcs, 77 ) 78 79 shared_objects = [] 80 for src in pyx_srcs: 81 stem = src.split(".")[0] 82 shared_object_name = stem + ".so" 83 native.cc_binary( 84 name=shared_object_name, 85 srcs=[stem + ".cpp"], 86 deps=deps + ["//util/python:python_headers"], 87 linkshared = 1, 88 ) 89 shared_objects.append(shared_object_name) 90 91 # Now create a py_library with these shared objects as data. 92 native.py_library( 93 name=name, 94 srcs=py_srcs, 95 deps=py_deps, 96 srcs_version = "PY2AND3", 97 data=shared_objects, 98 **kwargs 99 ) 100 101 def _proto_cc_hdrs(srcs, use_grpc_plugin=False): 102 ret = [s[:-len(".proto")] + ".pb.h" for s in srcs] 103 if use_grpc_plugin: 104 ret += [s[:-len(".proto")] + ".grpc.pb.h" for s in srcs] 105 return ret 106 107 def _proto_cc_srcs(srcs, use_grpc_plugin=False): 108 ret = [s[:-len(".proto")] + ".pb.cc" for s in srcs] 109 if use_grpc_plugin: 110 ret += [s[:-len(".proto")] + ".grpc.pb.cc" for s in srcs] 111 return ret 112 113 # Re-defined protocol buffer rule to allow building "header only" protocol 114 # buffers, to avoid duplicate registrations. Also allows non-iterable cc_libs 115 # containing select() statements. 116 def cc_proto_library( 117 name, 118 srcs=[], 119 deps=[], 120 cc_libs=[], 121 include=None, 122 protoc="@protobuf_archive//:protoc", 123 internal_bootstrap_hack=False, 124 use_grpc_plugin=False, 125 default_header=False, 126 **kargs): 127 """Bazel rule to create a C++ protobuf library from proto source files. 128 129 Args: 130 name: the name of the cc_proto_library. 131 srcs: the .proto files of the cc_proto_library. 132 deps: a list of dependency labels; must be cc_proto_library. 133 cc_libs: a list of other cc_library targets depended by the generated 134 cc_library. 135 include: a string indicating the include path of the .proto files. 136 protoc: the label of the protocol compiler to generate the sources. 137 internal_bootstrap_hack: a flag indicate the cc_proto_library is used only 138 for bootstraping. When it is set to True, no files will be generated. 139 The rule will simply be a provider for .proto files, so that other 140 cc_proto_library can depend on it. 141 use_grpc_plugin: a flag to indicate whether to call the grpc C++ plugin 142 when processing the proto files. 143 default_header: Controls the naming of generated rules. If True, the `name` 144 rule will be header-only, and an _impl rule will contain the 145 implementation. Otherwise the header-only rule (name + "_headers_only") 146 must be referred to explicitly. 147 **kargs: other keyword arguments that are passed to cc_library. 148 """ 149 150 includes = [] 151 if include != None: 152 includes = [include] 153 154 if internal_bootstrap_hack: 155 # For pre-checked-in generated files, we add the internal_bootstrap_hack 156 # which will skip the codegen action. 157 proto_gen( 158 name=name + "_genproto", 159 srcs=srcs, 160 deps=[s + "_genproto" for s in deps], 161 includes=includes, 162 protoc=protoc, 163 visibility=["//visibility:public"], 164 ) 165 # An empty cc_library to make rule dependency consistent. 166 native.cc_library( 167 name=name, 168 **kargs) 169 return 170 171 grpc_cpp_plugin = None 172 if use_grpc_plugin: 173 grpc_cpp_plugin = "//external:grpc_cpp_plugin" 174 175 gen_srcs = _proto_cc_srcs(srcs, use_grpc_plugin) 176 gen_hdrs = _proto_cc_hdrs(srcs, use_grpc_plugin) 177 outs = gen_srcs + gen_hdrs 178 179 proto_gen( 180 name=name + "_genproto", 181 srcs=srcs, 182 deps=[s + "_genproto" for s in deps], 183 includes=includes, 184 protoc=protoc, 185 plugin=grpc_cpp_plugin, 186 plugin_language="grpc", 187 gen_cc=1, 188 outs=outs, 189 visibility=["//visibility:public"], 190 ) 191 192 if use_grpc_plugin: 193 cc_libs += ["//external:grpc_lib"] 194 195 if default_header: 196 header_only_name = name 197 impl_name = name + "_impl" 198 else: 199 header_only_name = name + "_headers_only" 200 impl_name = name 201 202 native.cc_library( 203 name=impl_name, 204 srcs=gen_srcs, 205 hdrs=gen_hdrs, 206 deps=cc_libs + deps, 207 includes=includes, 208 **kargs) 209 native.cc_library( 210 name=header_only_name, 211 deps=["@protobuf_archive//:protobuf_headers"] + if_static([impl_name]), 212 hdrs=gen_hdrs, 213 **kargs) 214 215 def tf_proto_library_cc(name, srcs = [], has_services = None, 216 protodeps = [], 217 visibility = [], testonly = 0, 218 cc_libs = [], 219 cc_stubby_versions = None, 220 cc_grpc_version = None, 221 j2objc_api_version = 1, 222 cc_api_version = 2, go_api_version = 2, 223 java_api_version = 2, py_api_version = 2, 224 js_api_version = 2, js_codegen = "jspb", 225 default_header = False): 226 js_codegen = js_codegen # unused argument 227 js_api_version = js_api_version # unused argument 228 native.filegroup( 229 name = name + "_proto_srcs", 230 srcs = srcs + tf_deps(protodeps, "_proto_srcs"), 231 testonly = testonly, 232 visibility = visibility, 233 ) 234 235 use_grpc_plugin = None 236 if cc_grpc_version: 237 use_grpc_plugin = True 238 cc_proto_library( 239 name = name + "_cc", 240 srcs = srcs, 241 deps = tf_deps(protodeps, "_cc") + ["@protobuf_archive//:cc_wkt_protos"], 242 cc_libs = cc_libs + if_static( 243 ["@protobuf_archive//:protobuf"], 244 ["@protobuf_archive//:protobuf_headers"] 245 ), 246 copts = if_not_windows([ 247 "-Wno-unknown-warning-option", 248 "-Wno-unused-but-set-variable", 249 "-Wno-sign-compare", 250 ]), 251 protoc = "@protobuf_archive//:protoc", 252 use_grpc_plugin = use_grpc_plugin, 253 testonly = testonly, 254 visibility = visibility, 255 default_header = default_header, 256 ) 257 258 def tf_proto_library_py(name, srcs=[], protodeps=[], deps=[], visibility=[], 259 testonly=0, 260 srcs_version="PY2AND3"): 261 py_proto_library( 262 name = name + "_py", 263 srcs = srcs, 264 srcs_version = srcs_version, 265 deps = deps + tf_deps(protodeps, "_py") + ["@protobuf_archive//:protobuf_python"], 266 protoc = "@protobuf_archive//:protoc", 267 default_runtime = "@protobuf_archive//:protobuf_python", 268 visibility = visibility, 269 testonly = testonly, 270 ) 271 272 def tf_jspb_proto_library(**kwargs): 273 pass 274 275 def tf_nano_proto_library(**kwargs): 276 pass 277 278 def tf_proto_library(name, srcs = [], has_services = None, 279 protodeps = [], 280 visibility = [], testonly = 0, 281 cc_libs = [], 282 cc_api_version = 2, cc_grpc_version = None, 283 go_api_version = 2, 284 j2objc_api_version = 1, 285 java_api_version = 2, py_api_version = 2, 286 js_api_version = 2, js_codegen = "jspb", 287 default_header = False): 288 """Make a proto library, possibly depending on other proto libraries.""" 289 js_api_version = js_api_version # unused argument 290 js_codegen = js_codegen # unused argument 291 tf_proto_library_cc( 292 name = name, 293 srcs = srcs, 294 protodeps = protodeps, 295 cc_grpc_version = cc_grpc_version, 296 cc_libs = cc_libs, 297 testonly = testonly, 298 visibility = visibility, 299 default_header = default_header, 300 ) 301 302 tf_proto_library_py( 303 name = name, 304 srcs = srcs, 305 protodeps = protodeps, 306 srcs_version = "PY2AND3", 307 testonly = testonly, 308 visibility = visibility, 309 ) 310 311 def tf_additional_lib_hdrs(exclude = []): 312 windows_hdrs = native.glob([ 313 "platform/default/*.h", 314 "platform/windows/*.h", 315 "platform/posix/error.h", 316 ], exclude = exclude) 317 return select({ 318 "//tensorflow:windows" : windows_hdrs, 319 "//tensorflow:windows_msvc" : windows_hdrs, 320 "//conditions:default" : native.glob([ 321 "platform/default/*.h", 322 "platform/posix/*.h", 323 ], exclude = exclude), 324 }) 325 326 def tf_additional_lib_srcs(exclude = []): 327 windows_srcs = native.glob([ 328 "platform/default/*.cc", 329 "platform/windows/*.cc", 330 "platform/posix/error.cc", 331 ], exclude = exclude) 332 return select({ 333 "//tensorflow:windows" : windows_srcs, 334 "//tensorflow:windows_msvc" : windows_srcs, 335 "//conditions:default" : native.glob([ 336 "platform/default/*.cc", 337 "platform/posix/*.cc", 338 ], exclude = exclude), 339 }) 340 341 # pylint: disable=unused-argument 342 def tf_additional_framework_hdrs(exclude = []): 343 return [] 344 345 def tf_additional_framework_srcs(exclude = []): 346 return [] 347 # pylint: enable=unused-argument 348 349 def tf_additional_minimal_lib_srcs(): 350 return [ 351 "platform/default/integral_types.h", 352 "platform/default/mutex.h", 353 ] 354 355 def tf_additional_proto_hdrs(): 356 return [ 357 "platform/default/integral_types.h", 358 "platform/default/logging.h", 359 "platform/default/protobuf.h" 360 ] + if_windows([ 361 "platform/windows/integral_types.h", 362 ]) 363 364 def tf_additional_proto_srcs(): 365 return [ 366 "platform/default/logging.cc", 367 "platform/default/protobuf.cc", 368 ] 369 370 def tf_additional_all_protos(): 371 return ["//tensorflow/core:protos_all"] 372 373 def tf_protos_all_impl(): 374 return ["//tensorflow/core:protos_all_cc_impl"] 375 376 def tf_protos_all(): 377 return if_static( 378 extra_deps=tf_protos_all_impl(), 379 otherwise=["//tensorflow/core:protos_all_cc"]) 380 381 def tf_protos_grappler_impl(): 382 return ["//tensorflow/core/grappler/costs:op_performance_data_cc_impl"] 383 384 def tf_protos_grappler(): 385 return if_static( 386 extra_deps=tf_protos_grappler_impl(), 387 otherwise=["//tensorflow/core/grappler/costs:op_performance_data_cc"]) 388 389 def tf_env_time_hdrs(): 390 return [ 391 "platform/env_time.h", 392 ] 393 394 def tf_env_time_srcs(): 395 win_env_time = native.glob([ 396 "platform/windows/env_time.cc", 397 "platform/env_time.cc", 398 ], exclude = []) 399 return select({ 400 "//tensorflow:windows" : win_env_time, 401 "//tensorflow:windows_msvc" : win_env_time, 402 "//conditions:default" : native.glob([ 403 "platform/posix/env_time.cc", 404 "platform/env_time.cc", 405 ], exclude = []), 406 }) 407 408 def tf_additional_cupti_wrapper_deps(): 409 return ["//tensorflow/core/platform/default/gpu:cupti_wrapper"] 410 411 def tf_additional_device_tracer_srcs(): 412 return ["platform/default/device_tracer.cc"] 413 414 def tf_additional_device_tracer_cuda_deps(): 415 return [] 416 417 def tf_additional_device_tracer_deps(): 418 return [] 419 420 def tf_additional_libdevice_data(): 421 return [] 422 423 def tf_additional_libdevice_deps(): 424 return ["@local_config_cuda//cuda:cuda_headers"] 425 426 def tf_additional_libdevice_srcs(): 427 return ["platform/default/cuda_libdevice_path.cc"] 428 429 def tf_additional_test_deps(): 430 return [] 431 432 def tf_additional_test_srcs(): 433 return [ 434 "platform/default/test_benchmark.cc", 435 ] + select({ 436 "//tensorflow:windows" : [ 437 "platform/windows/test.cc" 438 ], 439 "//conditions:default" : [ 440 "platform/posix/test.cc", 441 ], 442 }) 443 444 def tf_kernel_tests_linkstatic(): 445 return 0 446 447 def tf_additional_lib_defines(): 448 """Additional defines needed to build TF libraries.""" 449 return select({ 450 "//tensorflow:with_jemalloc_linux_x86_64": ["TENSORFLOW_USE_JEMALLOC"], 451 "//tensorflow:with_jemalloc_linux_ppc64le":["TENSORFLOW_USE_JEMALLOC"], 452 "//conditions:default": [], 453 }) + if_not_mobile(["TENSORFLOW_USE_ABSL"]) 454 455 def tf_additional_lib_deps(): 456 """Additional dependencies needed to build TF libraries.""" 457 return if_not_mobile(["@com_google_absl//absl/base:base"]) + if_static( 458 ["@nsync//:nsync_cpp"], 459 ["@nsync//:nsync_headers"] 460 ) + select({ 461 "//tensorflow:with_jemalloc_linux_x86_64_dynamic": ["@jemalloc//:jemalloc_headers"], 462 "//tensorflow:with_jemalloc_linux_ppc64le_dynamic": ["@jemalloc//:jemalloc_headers"], 463 "//tensorflow:with_jemalloc_linux_x86_64": ["@jemalloc//:jemalloc_impl"], 464 "//tensorflow:with_jemalloc_linux_ppc64le": ["@jemalloc//:jemalloc_impl"], 465 "//conditions:default": [], 466 }) 467 468 def tf_additional_core_deps(): 469 return select({ 470 "//tensorflow:with_gcp_support_android_override": [], 471 "//tensorflow:with_gcp_support_ios_override": [], 472 "//tensorflow:with_gcp_support": [ 473 "//tensorflow/core/platform/cloud:gcs_file_system", 474 ], 475 "//conditions:default": [], 476 }) + select({ 477 "//tensorflow:with_hdfs_support_windows_override": [], 478 "//tensorflow:with_hdfs_support_android_override": [], 479 "//tensorflow:with_hdfs_support_ios_override": [], 480 "//tensorflow:with_hdfs_support": [ 481 "//tensorflow/core/platform/hadoop:hadoop_file_system", 482 ], 483 "//conditions:default": [], 484 }) + select({ 485 "//tensorflow:with_s3_support_windows_override": [], 486 "//tensorflow:with_s3_support_android_override": [], 487 "//tensorflow:with_s3_support_ios_override": [], 488 "//tensorflow:with_s3_support": [ 489 "//tensorflow/core/platform/s3:s3_file_system", 490 ], 491 "//conditions:default": [], 492 }) 493 494 # TODO(jart, jhseu): Delete when GCP is default on. 495 def tf_additional_cloud_op_deps(): 496 return select({ 497 "//tensorflow:with_gcp_support_windows_override": [], 498 "//tensorflow:with_gcp_support_android_override": [], 499 "//tensorflow:with_gcp_support_ios_override": [], 500 "//tensorflow:with_gcp_support": [ 501 "//tensorflow/contrib/cloud:bigquery_reader_ops_op_lib", 502 ], 503 "//conditions:default": [], 504 }) 505 506 # TODO(jart, jhseu): Delete when GCP is default on. 507 def tf_additional_cloud_kernel_deps(): 508 return select({ 509 "//tensorflow:with_gcp_support_windows_override": [], 510 "//tensorflow:with_gcp_support_android_override": [], 511 "//tensorflow:with_gcp_support_ios_override": [], 512 "//tensorflow:with_gcp_support": [ 513 "//tensorflow/contrib/cloud/kernels:bigquery_reader_ops", 514 ], 515 "//conditions:default": [], 516 }) 517 518 def tf_lib_proto_parsing_deps(): 519 return [ 520 ":protos_all_cc", 521 "//third_party/eigen3", 522 "//tensorflow/core/platform/default/build_config:proto_parsing", 523 ] 524 525 def tf_additional_verbs_lib_defines(): 526 return select({ 527 "//tensorflow:with_verbs_support": ["TENSORFLOW_USE_VERBS"], 528 "//conditions:default": [], 529 }) 530 531 def tf_additional_mpi_lib_defines(): 532 return select({ 533 "//tensorflow:with_mpi_support": ["TENSORFLOW_USE_MPI"], 534 "//conditions:default": [], 535 }) 536 537 def tf_additional_gdr_lib_defines(): 538 return select({ 539 "//tensorflow:with_gdr_support": ["TENSORFLOW_USE_GDR"], 540 "//conditions:default": [], 541 }) 542 543 def tf_py_clif_cc(name, visibility=None, **kwargs): 544 pass 545 546 def tf_pyclif_proto_library(name, proto_lib, proto_srcfile="", visibility=None, 547 **kwargs): 548 pass 549 550 def tf_additional_binary_deps(): 551 return ["@nsync//:nsync_cpp"] + if_cuda( 552 [ 553 "//tensorflow/stream_executor:cuda_platform", 554 "//tensorflow/core/platform/default/build_config:cuda", 555 ], 556 ) + select({ 557 "//tensorflow:with_jemalloc_linux_x86_64": ["@jemalloc//:jemalloc_impl"], 558 "//tensorflow:with_jemalloc_linux_ppc64le": ["@jemalloc//:jemalloc_impl"], 559 "//conditions:default": [], 560 }) + [ 561 # TODO(allenl): Split these out into their own shared objects (they are 562 # here because they are shared between contrib/ op shared objects and 563 # core). 564 "//tensorflow/core/kernels:lookup_util", 565 "//tensorflow/core/util/tensor_bundle", 566 ] + if_mkl( 567 [ 568 "//third_party/mkl:intel_binary_blob", 569 ], 570 ) 571