Naresh | 3af1aaa | 2018-07-27 14:39:14 +0000 | [diff] [blame] | 1 | """Custom rules for gRPC Python""" |
| 2 | |
| 3 | |
| 4 | # Adapted with modifications from |
| 5 | # tensorflow/tensorflow/core/platform/default/build_config.bzl |
| 6 | # Native Bazel rules don't exist yet to compile Cython code, but rules have |
| 7 | # been written at cython/cython and tensorflow/tensorflow. We branch from |
| 8 | # Tensorflow's version as it is more actively maintained and works for gRPC |
| 9 | # Python's needs. |
| 10 | def pyx_library(name, deps=[], py_deps=[], srcs=[], **kwargs): |
| 11 | """Compiles a group of .pyx / .pxd / .py files. |
| 12 | |
| 13 | First runs Cython to create .cpp files for each input .pyx or .py + .pxd |
| 14 | pair. Then builds a shared object for each, passing "deps" to each cc_binary |
| 15 | rule (includes Python headers by default). Finally, creates a py_library rule |
| 16 | with the shared objects and any pure Python "srcs", with py_deps as its |
| 17 | dependencies; the shared objects can be imported like normal Python files. |
| 18 | |
| 19 | Args: |
| 20 | name: Name for the rule. |
| 21 | deps: C/C++ dependencies of the Cython (e.g. Numpy headers). |
| 22 | py_deps: Pure Python dependencies of the final library. |
| 23 | srcs: .py, .pyx, or .pxd files to either compile or pass through. |
| 24 | **kwargs: Extra keyword arguments passed to the py_library. |
| 25 | """ |
| 26 | # First filter out files that should be run compiled vs. passed through. |
| 27 | py_srcs = [] |
| 28 | pyx_srcs = [] |
| 29 | pxd_srcs = [] |
| 30 | for src in srcs: |
| 31 | if src.endswith(".pyx") or (src.endswith(".py") and |
| 32 | src[:-3] + ".pxd" in srcs): |
| 33 | pyx_srcs.append(src) |
| 34 | elif src.endswith(".py"): |
| 35 | py_srcs.append(src) |
| 36 | else: |
| 37 | pxd_srcs.append(src) |
| 38 | if src.endswith("__init__.py"): |
| 39 | pxd_srcs.append(src) |
| 40 | |
| 41 | # Invoke cython to produce the shared object libraries. |
| 42 | for filename in pyx_srcs: |
| 43 | native.genrule( |
| 44 | name=filename + "_cython_translation", |
| 45 | srcs=[filename], |
| 46 | outs=[filename.split(".")[0] + ".cpp"], |
| 47 | # Optionally use PYTHON_BIN_PATH on Linux platforms so that python 3 |
| 48 | # works. Windows has issues with cython_binary so skip PYTHON_BIN_PATH. |
| 49 | cmd= |
| 50 | "PYTHONHASHSEED=0 $(location @cython//:cython_binary) --cplus $(SRCS) --output-file $(OUTS)", |
| 51 | tools=["@cython//:cython_binary"] + pxd_srcs, |
| 52 | ) |
| 53 | |
| 54 | shared_objects = [] |
| 55 | for src in pyx_srcs: |
| 56 | stem = src.split(".")[0] |
| 57 | shared_object_name = stem + ".so" |
| 58 | native.cc_binary( |
| 59 | name=shared_object_name, |
| 60 | srcs=[stem + ".cpp"], |
| 61 | deps=deps + ["@local_config_python//:python_headers"], |
| 62 | linkshared=1, |
| 63 | ) |
| 64 | shared_objects.append(shared_object_name) |
| 65 | |
| 66 | # Now create a py_library with these shared objects as data. |
| 67 | native.py_library( |
| 68 | name=name, |
| 69 | srcs=py_srcs, |
| 70 | deps=py_deps, |
| 71 | srcs_version="PY2AND3", |
| 72 | data=shared_objects, |
| 73 | **kwargs) |
| 74 | |