Home | History | Annotate | Download | only in bazel
      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 
     75