diff --git a/Dockerfile b/Dockerfile index 5b4a118d8d5..d02e77f90ce 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,9 +1,10 @@ FROM ubuntu:20.04 + # Install tools needed for development RUN apt update && \ apt upgrade --yes && \ - apt install --yes build-essential git libssl-dev m4 python3-pip + apt install --yes build-essential cython3 git libssl-dev m4 python3-pip # Copy needed source RUN mkdir /src @@ -17,16 +18,20 @@ RUN cd /src && build/build_openr.sh && chmod 644 /etc/openr.conf RUN mkdir /opt/bin && cp /src/build/docker_openr_helper.sh /opt/bin # Install `breeze` OpenR CLI -RUN pip3 --no-cache-dir install --upgrade pip setuptools wheel -RUN PATH="${PATH}:/opt/facebook/fbthrift/bin" ; \ - cd /src/openr/py/ && \ - python3 setup.py install +RUN apt install g++-10 --yes # We need g++-10 or higher for coroutines which are used in folly::coro +# TODO Move these files into build/ +COPY cython_compile.py /src/build/cython_compile.py +RUN git clone https://github.com/cython/cython +COPY setup.py /src/openr/py/setup.py +RUN cd /src && build/build_breeze.sh +RUN cp -r /src/build/lib.linux-x86_64-3.8 /breeze-build # Cleanup all we can to keep container as lean as possible +# TODO: We can use Dockerfile stages instead RUN apt remove --yes build-essential git libssl-dev m4 && \ apt autoremove --yes && \ rm -rf /src /tmp/* /var/lib/apt/lists/* CMD ["/opt/bin/docker_openr_helper.sh"] -# Expose OpenR Thrift port - Recommended to run OpenR on host network ... +# Expose OpenR Thrift port EXPOSE 2018/tcp diff --git a/README.md b/README.md index 46ddf2bc7d8..a4d4f579e28 100644 --- a/README.md +++ b/README.md @@ -118,7 +118,7 @@ Note: the `build_openr.sh` script will run this step for you - Manually you can drive `getdeps.py` to install elsewhere - refer to `build_openr.sh` -#### Installing Python Libraries +#### Installing Python Libraries + CLI You will need python `pip` or `setuptools` to build and install python modules. All library dependencies will be automatically installed except the @@ -136,11 +136,13 @@ sudo python setup.py install ### Docker Building / Usage -OpenR now has a `Dockerfile`. It uses `gendeps.py` to build all dependencies + OpenR. -It also installs the OpenR CLI `breeze` into the container. +OpenR now has two `Dockerfile`s. It uses `gendeps.py` to build all dependencies + OpenR. The two files are: + +- `Dockerfile` - Full OpenR daemon + `breeze` CLI +- `Dockerfile_breeze` - Only `breeze` CLI ```console - docker build --network host . +docker build [-f Dockerfile_breeze] --network host . ``` #### Running diff --git a/build/build_breeze.sh b/build/build_breeze.sh new file mode 100755 index 00000000000..0eaa7997226 --- /dev/null +++ b/build/build_breeze.sh @@ -0,0 +1,79 @@ +#!/bin/bash + +# +# Copyright (c) 2014-present, Facebook, Inc. +# +# This source code is licensed under the MIT license found in the +# LICENSE file in the root directory of this source tree. +# + +source "$(dirname "$0")/common.sh" + +alias thrift1=/opt/facebook/fbthrift/bin/thrift1 + +# Step 1: Stage compilation + +# folly Cython +mkdir ./folly +cp -r \ +/tmp/fbcode_builder_getdeps-ZsrcZbuildZfbcode_builder-root/repos/github.com-facebook-folly.git/folly/python/* ./folly + +# fb303 thrift +mkdir -p ./fb303-thrift +cp -r /opt/facebook/fb303/include/thrift-files/fb303 ./fb303-thrift/ + +# fbzmq thrift +mkdir -p ./fbzmq-thrift/fbzmq +cp -r /opt/facebook/fbzmq/include/fbzmq/service ./fbzmq-thrift/fbzmq/ + +# fbthrift Cython and thrift +cp -r /opt/facebook/fbthrift/include/thrift/lib/ ./thrift +touch ./thrift/py3/__init__.py +touch ./thrift/__init__.py + +mkdir /src/fbthrift-thrift +cp -r \ +/tmp/fbcode_builder_getdeps-ZsrcZbuildZfbcode_builder-root/repos/github.com-facebook-fbthrift.git/thrift/lib/thrift/* \ +/src/fbthrift-thrift + +mkdir -p /src/thrift/py3 +chown -R root /tmp/fbcode_builder_getdeps-ZsrcZbuildZfbcode_builder-root/repos/github.com-facebook-fbthrift.git/thrift/lib/py3/ +cp -r \ +/tmp/fbcode_builder_getdeps-ZsrcZbuildZfbcode_builder-root/repos/github.com-facebook-fbthrift.git/thrift/lib/py3/* \ +/src/thrift/py3 +touch /src/thrift/__init__.py + +# Open/R thrift +mkdir -p ./openr-thrift/openr +cp -r /src/openr/if/ ./openr-thrift/openr/ + +# Neteng thrift +mkdir -p neteng-thrift/configerator/structs/neteng/config/ +cp -r \ +/tmp/fbcode_builder_getdeps-ZsrcZbuildZfbcode_builder-root/repos/github.com-facebook-openr.git/configerator/structs/neteng/config/routing_policy.thrift \ +neteng-thrift/configerator/structs/neteng/config/ + +# HACK TO FIX CYTHON .pxd +cp /cython/Cython/Includes/libcpp/utility.pxd /usr/lib/python3/dist-packages/Cython/Includes/libcpp/utility.pxd + +# Step 2. Generate mstch_cpp2 and mstch_py3 bindings + +python3 /src/build/gen.py + +# HACK TO FIX fbthrift-py/gen-cpp2/ +echo " " > /src/fbthrift-thrift/gen-cpp2/metadata_metadata.h +echo " " > /src/fbthrift-thrift/gen-cpp2/metadata_types.h +echo " " > /src/fbthrift-thrift/gen-cpp2/metadata_types_custom_protocol.h + +# Step 3. Generate clients.cpp + +python3 /src/build/cython_compile.py + +# Step 4. Compile .so + +CC="/usr/bin/gcc-10" \ +CXX="/usr/bin/g++-10" \ +CFLAGS="-I. -Iopenr-thrift -Ifb303-thrift -Ifbzmq-thrift -Ineteng-thrift -std=c++20 -fcoroutines " \ +CFLAGS="$CFLAGS -w -D_CPPLIB_VER=20" \ +CXXFLAGS="$CFLAGS" \ +python3 openr/py/setup.py build -j10 diff --git a/build/build_openr.sh b/build/build_openr.sh index 6a509f8f424..5714119c9f8 100755 --- a/build/build_openr.sh +++ b/build/build_openr.sh @@ -4,29 +4,16 @@ # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. -errorCheck() { - return_code=$? - if [ $return_code -ne 0 ]; then - echo "[ERROR]: $1" - exit $return_code - fi -} - -GETDEPS="$(dirname "$0")/fbcode_builder/getdeps.py" -INSTALL_PREFIX="/opt/facebook" -PYTHON3=$(command -v python3) - -if [ "$PYTHON3" == "" ]; then - echo "ERROR: No \`python3\` in PATH" - exit 1 -fi +source "$(dirname "$0")/common.sh" # TODO: Get apt deb installing working - dies in Docker container with libzstd-dev fixed -# python3 "$GETDEPS" --allow-system-packages install-system-deps --recursive openr +# "$PYTHON3" "$GETDEPS" --allow-system-packages install-system-deps --recursive openr # errorCheck "Failed to install-system-deps for openr" -python3 "$GETDEPS" --allow-system-packages build --src-dir=. --no-tests --install-prefix "$INSTALL_PREFIX" openr +"$PYTHON3" "$GETDEPS" --allow-system-packages build --no-tests --install-prefix "$INSTALL_PREFIX" \ +--extra-cmake-defines "$EXTRA_CMAKE_DEFINES" openr errorCheck "Failed to build openr" -python3 "$GETDEPS" fixup-dyn-deps --strip --src-dir=. openr _artifacts/linux --project-install-prefix openr:"$INSTALL_PREFIX" --final-install-prefix "$INSTALL_PREFIX" +# TODO: Maybe fix src-dir to be absolute reference to dirname $0's parent +"$PYTHON3" "$GETDEPS" fixup-dyn-deps --strip --src-dir=. openr _artifacts/linux --project-install-prefix openr:"$INSTALL_PREFIX" --final-install-prefix "$INSTALL_PREFIX" errorCheck "Failed to fixup-dyn-deps for openr" diff --git a/build/common.sh b/build/common.sh new file mode 100644 index 00000000000..543da3812d7 --- /dev/null +++ b/build/common.sh @@ -0,0 +1,32 @@ +#!/bin/bash + +# +# Copyright (c) 2014-present, Facebook, Inc. +# +# This source code is licensed under the MIT license found in the +# LICENSE file in the root directory of this source tree. +# + +GETDEPS="$(dirname "$0")/fbcode_builder/getdeps.py" +INSTALL_PREFIX="/opt/facebook" +PYTHON3=$(command -v python3) +PIP3=$(command -v pip3) +EXTRA_CMAKE_DEFINES='{"CMAKE_POSITION_INDEPENDENT_CODE": "ON"}' + +errorCheck() { + return_code=$? + if [ $return_code -ne 0 ]; then + echo "[ERROR]: $1" + exit $return_code + fi +} + +if [ "$PYTHON3" == "" ]; then + echo "ERROR: No \`python3\` in PATH" + exit 1 +fi + +if [ "$PIP3" == "" ]; then + echo "ERROR: No \`pip3\` in PATH" + exit 2 +fi diff --git a/build/cython_compile.py b/build/cython_compile.py new file mode 100644 index 00000000000..c890f377c7e --- /dev/null +++ b/build/cython_compile.py @@ -0,0 +1,35 @@ +import os +from subprocess import Popen, check_call + +thrift_files = [] +procs = [] +for root, dirs, files in os.walk('openr-thrift'): + for f in files: + if f.endswith(".pyx"): + thrift_file = os.path.join(root, f) + cmd = \ + [ + "cython3", + "--fast-fail", + "-3", + "--cplus", + thrift_file, + "-o", + root, + "-I.", + "-I/src", + "-I/usr/lib/python3/dist-packages/Cython/Includes", + "-I/src/fbthrift-thrift/gen-py3", + "-I/src/fb303-thrift/fb303/thrift/gen-py3", + "-I/src/neteng-thrift/configerator/structs/neteng/config/gen-py3", + ] + print(f"Generating cython module {f}") + procs += [Popen( cmd)] + +print("Waiting for cython generation to finish...") +failures = 0 +for proc in procs: + proc.wait() + if proc.returncode != 0: + failures += 1 +print(f"{len(procs) - failures}/{len(procs)} succeeded") diff --git a/build/fbcode_builder/fbcode_builder.py b/build/fbcode_builder/fbcode_builder.py index 921517c4844..5727d71beac 100644 --- a/build/fbcode_builder/fbcode_builder.py +++ b/build/fbcode_builder/fbcode_builder.py @@ -414,6 +414,14 @@ def cmake_configure(self, name, cmake_path='..'): 'BUILD_SHARED_LIBS': 'ON', 'CMAKE_INSTALL_PREFIX': self.option('prefix'), } + + # Hacks to add thriftpy3 support + if 'BUILD_THRIFT_PY3' in os.environ and 'folly' in name: + cmake_defines['PYTHON_EXTENSIONS'] = 'True' + + if 'BUILD_THRIFT_PY3' in os.environ and 'fbthrift' in name: + cmake_defines['thriftpy3'] = 'ON' + cmake_defines.update( self.option('{0}:cmake_defines'.format(name), {}) ) diff --git a/build/gen.py b/build/gen.py new file mode 100644 index 00000000000..fc9b88c9357 --- /dev/null +++ b/build/gen.py @@ -0,0 +1,54 @@ +import os +from subprocess import check_call + +def generate_thrift_files(): + """ + Get list of all thrift files (absolute path names) and then generate + python definitions for all thrift files. + """ + + thrift_dirs = [ + "openr-thrift", + "fb303-thrift", + "fbzmq-thrift", + "fbthrift-thrift", + "neteng-thrift", + ] + generators = ['mstch_cpp2', 'py', 'mstch_py3'] + includes = [ + "openr-thrift", + "fb303-thrift", + "fbzmq-thrift", + "neteng-thrift", + "fbthrift-thrift", + ".", + ] + + # Find .thrift files + thrift_files = [] + for thrift_dir in thrift_dirs: + for root, dirs, files in os.walk(thrift_dir): + for file in files: + if file.endswith(".thrift"): + thrift_files += [os.path.join(root, file)] + + # Generate cpp and python + for gen in generators: + cmd = ["/opt/facebook/fbthrift/bin/thrift1", '--gen', gen] + for include in includes: + cmd += ["-I", f"{include}"] + for thrift_file in thrift_files: + check_call([*cmd, '-o', os.path.join(os.path.dirname(thrift_file)), str(thrift_file)]) + + # Add __init__.py for compiling cython modules + for include in includes: + for root, dirs, files in os.walk(f"{include}"): + for f in files: + check_call( + [ + "touch", + os.path.join(root, os.path.dirname(f), '__init__.py') + ] + ) + +generate_thrift_files() diff --git a/build/setup.py b/build/setup.py new file mode 100644 index 00000000000..6b7cc379570 --- /dev/null +++ b/build/setup.py @@ -0,0 +1,122 @@ +#!/usr/bin/env python3 +# Copyright (c) Facebook, Inc. and its affiliates. +# +# This source code is licensed under the MIT license found in the +# LICENSE file in the root directory of this source tree. + +import glob +import os +from setuptools import Extension, find_packages, setup +from subprocess import Popen, check_call + +from Cython.Build import cythonize + + +INSTALL_REQUIRES = [ + "bunch", + "click", + "cython", + "hexdump", + "jsondiff", + "networkx", + "six", + "tabulate" +] + + +def create_package_list(base): + """ + Get all packages under the base directory + """ + + return [base] + ["{}.{}".format(base, pkg) for pkg in find_packages(base)] + + +extension_include_dirs = [ + ".", + "/opt/facebook/folly/include", + *glob.glob("/opt/facebook/boost-*/include"), + *glob.glob("/opt/facebook/glog-*/include"), + *glob.glob("/opt/facebook/gflags-*/include"), + *glob.glob("/opt/facebook/double-*/include"), + *glob.glob("/opt/facebook/libevent-*/include"), + "/opt/facebook/fbthrift/include", + "/opt/facebook/fizz/include", + "/opt/facebook/wangle/include/", + *glob.glob("/opt/facebook/fmt-*/include"), + *glob.glob("/opt/facebook/libsodium-*/include"), + "/tmp/fbcode_builder_getdeps-ZsrcZbuildZfbcode_builder-root/build/openr", +] + +bespoke_extensions = [ + "openr.thrift.OpenrCtrlCpp.clients", + "openr.thrift.OpenrCtrl.clients", + "openr.thrift.Platform.clients", +] + +extension_library_dirs = [ + "/usr/lib/", + "/opt/facebook/openr/lib/", + "/opt/facebook/fbthrift/lib/", + "/opt/facebook/folly/lib/", +] + +extension_libraries = ['openrlib', 'thriftcpp2', 'folly'] + + +extensions = [ + Extension("openr.thrift.OpenrCtrlCpp.clients", + ["./openr-thrift/openr/if/gen-py3/openr/thrift/OpenrCtrlCpp/clients.cpp", "openr-thrift/openr/if/gen-py3/OpenrCtrlCpp/clients_wrapper.cpp"], + library_dirs=extension_library_dirs, + include_dirs=extension_include_dirs, + libraries=extension_libraries, + ), + Extension("openr.thrift.OpenrCtrl.clients", + ["./openr-thrift/openr/if/gen-py3/openr/thrift/OpenrCtrl/clients.cpp", "openr-thrift/openr/if/gen-py3/OpenrCtrl/clients_wrapper.cpp"], + library_dirs=extension_library_dirs, + include_dirs=extension_include_dirs, + libraries=extension_libraries, + ), + Extension("openr.thrift.Platform.clients", + ["./openr-thrift/openr/if/gen-py3/openr/thrift/Platform/clients.cpp", "openr-thrift/openr/if/gen-py3/Platform/clients_wrapper.cpp"], + library_dirs=extension_library_dirs, + include_dirs=extension_include_dirs, + libraries=extension_libraries, + ), +] + +for root, dirs, files in os.walk('openr-thrift'): + for f in files: + if f.endswith(".pyx"): + pyx_file = (os.path.join(root, f)) + module = pyx_file.replace('openr-thrift/openr/if/gen-py3/', '').replace('.pyx', '').replace('/', '.') + cpp_file = pyx_file.replace('pyx', 'cpp') + if module in bespoke_extensions: + continue + extensions += [ + Extension(module, + [cpp_file], + library_dirs=extension_library_dirs, + include_dirs=extension_include_dirs, + libraries=extension_libraries, + ), + ] + + +setup( + name="openr", + version="2.0.0", + author="Open Routing", + author_email="openr@fb.com", + description=( + "OpenR python tools and bindings. Includes python bindings for various " + + "OpenR modules, CLI tool for interacting with OpenR named as `breeze`." + ), + packages=create_package_list("openr"), + entry_points={"console_scripts": ["breeze=openr.cli.breeze:main"]}, + license="MIT License", + install_requires=INSTALL_REQUIRES, + ext_modules=cythonize(extensions, compiler_directives={'language_level' : "3"}), + python_requires=">=3.7", +) + diff --git a/openr/py/build_thrift.py b/openr/py/build_thrift.py new file mode 100644 index 00000000000..a127c0f34ed --- /dev/null +++ b/openr/py/build_thrift.py @@ -0,0 +1,111 @@ +#!/usr/bin/env python3 + +# +# Copyright (c) 2014-present, Facebook, Inc. +# +# This source code is licensed under the MIT license found in the +# LICENSE file in the root directory of this source tree. +# + +# TODO: This all needs to go to cmake for thrift py3 support + +import logging +import os +from pathlib import Path +from shutil import copytree +from subprocess import check_call +from sys import version_info + + +INSTALL_BASE_PATH = Path("/opt/facebook") +LOG = logging.getLogger(__name__) +# Set for Ubuntu Docker Container +# e.g. /usr/local/lib/python3.8/dist-packages/openr/ +PY_PACKAGE_DIR = "/usr/local/lib/python{}.{}/dist-packages/".format( + version_info.major, version_info.minor +) +CPP2_PATH = Path("/src/generated_cpp2") +PY3_HEADERS = INSTALL_BASE_PATH / "fbthrift/include/thrift/lib/py3" + + +def generate_thrift_files(): + """ + Get list of all thrift files (absolute path names) and then generate + python definitions for all thrift files. + """ + + install_base = str(INSTALL_BASE_PATH) + if "OPENR_INSTALL_BASE" in os.environ: + install_base = os.environ["OPENR_INSTALL_BASE"] + + include_paths = ( + install_base, + "{}/fb303/include/thrift-files/".format(install_base), + ) + include_args = [] + for include_path in include_paths: + include_args.extend(["-I", include_path]) + + # /src/py/ + setup_py_path = Path(__file__).parent.absolute() + # /src + openr_root_path = setup_py_path.parent + # /src/if/ + thrift_path = openr_root_path / "if" + + thrift_files = sorted(thrift_path.rglob("*.thrift")) + LOG.info( + "Going to build the following thrift files from {}: {}".format( + str(thrift_path), thrift_files + ) + ) + CPP2_PATH.mkdir(exist_ok=True) + for thrift_file in thrift_files: + for thrift_lang in ("py", "mstch_cpp2", "mstch_py3"): + target_dir = PY_PACKAGE_DIR if 'py' in thrift_lang else str(CPP2_PATH) + + cmd = [ + "thrift1", + "-r", + "--gen", + thrift_lang, + "-I", + str(openr_root_path), + *include_args, + "--out", + target_dir, + str(thrift_file), + ] + LOG.info(f"Running {' '.join(cmd)} ...") + check_call(cmd) + + # TODO: Cython generated cpp2 with generated py3 + # If we're at py3 means we have CPP already generated + if thrift_lang == 'mstch_py3': + # exec cython with correct args to build ... + LOG.debug("TODO: Run cython compile ...") + pass + + # Copy fbthrift into thrift import dir + fb_thrift_path = INSTALL_BASE_PATH / "fbthrift/lib/fb-py-libs/thrift_py/thrift" + thrift_py_package_path = Path(PY_PACKAGE_DIR) / "thrift" + copytree(str(fb_thrift_path), str(thrift_py_package_path), dirs_exist_ok=True) + + # Symlink fb303 python into PY_PACKAGE_DIR + fb_fb303_path = ( + INSTALL_BASE_PATH / "fb303/lib/fb-py-libs/fb303_thrift_py/fb303_core" + ) + fb303_py_pacakge_path = Path(PY_PACKAGE_DIR) / "fb303_core" + if not fb303_py_pacakge_path.exists(): + fb303_py_pacakge_path.symlink_to(fb_fb303_path) + + # TODO: Build thrift.py + py3 fb303 libraries ... :| + + +if __name__ == "__main__": # pragma: no cover + logging.basicConfig( + format="[%(asctime)s] %(levelname)s: %(message)s (%(filename)s:%(lineno)d)", + level=logging.DEBUG, + ) + LOG.info("Generating Open/R Thrift Libraries") + generate_thrift_files() diff --git a/openr/py/setup.py b/openr/py/setup.py index 8f734a549df..6b7cc379570 100644 --- a/openr/py/setup.py +++ b/openr/py/setup.py @@ -4,16 +4,24 @@ # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. - +import glob import os -from pathlib import Path -from subprocess import check_call -from sys import version_info +from setuptools import Extension, find_packages, setup +from subprocess import Popen, check_call -from setuptools import find_packages, setup +from Cython.Build import cythonize -INSTALL_BASE = "/opt/facebook" +INSTALL_REQUIRES = [ + "bunch", + "click", + "cython", + "hexdump", + "jsondiff", + "networkx", + "six", + "tabulate" +] def create_package_list(base): @@ -24,68 +32,91 @@ def create_package_list(base): return [base] + ["{}.{}".format(base, pkg) for pkg in find_packages(base)] -def generate_thrift_files(): - """ - Get list of all thrift files (absolute path names) and then generate - python definitions for all thrift files. - """ - - install_base = INSTALL_BASE - if "OPENR_INSTALL_BASE" in os.environ: - install_base = os.environ["OPENR_INSTALL_BASE"] - - current_dir = os.path.dirname(os.path.realpath(__file__)) - root_dir = os.path.dirname(os.path.dirname(current_dir)) - top_dirs = [os.path.join(root_dir, "openr/if"), os.path.join(root_dir, "common")] - exclude_files = ["OpenrCtrlCpp"] - - def get_default_install_paths(): - include_paths = ( - install_base, - "{}/fb303/include/thrift-files/".format(install_base), - ) - include_args = [] - for include_path in include_paths: - include_args.extend(["-I", include_path]) - return include_args - - for top_dir in top_dirs: - for thrift_file in Path(top_dir).rglob("*.thrift"): - if thrift_file.stem in exclude_files: +extension_include_dirs = [ + ".", + "/opt/facebook/folly/include", + *glob.glob("/opt/facebook/boost-*/include"), + *glob.glob("/opt/facebook/glog-*/include"), + *glob.glob("/opt/facebook/gflags-*/include"), + *glob.glob("/opt/facebook/double-*/include"), + *glob.glob("/opt/facebook/libevent-*/include"), + "/opt/facebook/fbthrift/include", + "/opt/facebook/fizz/include", + "/opt/facebook/wangle/include/", + *glob.glob("/opt/facebook/fmt-*/include"), + *glob.glob("/opt/facebook/libsodium-*/include"), + "/tmp/fbcode_builder_getdeps-ZsrcZbuildZfbcode_builder-root/build/openr", +] + +bespoke_extensions = [ + "openr.thrift.OpenrCtrlCpp.clients", + "openr.thrift.OpenrCtrl.clients", + "openr.thrift.Platform.clients", +] + +extension_library_dirs = [ + "/usr/lib/", + "/opt/facebook/openr/lib/", + "/opt/facebook/fbthrift/lib/", + "/opt/facebook/folly/lib/", +] + +extension_libraries = ['openrlib', 'thriftcpp2', 'folly'] + + +extensions = [ + Extension("openr.thrift.OpenrCtrlCpp.clients", + ["./openr-thrift/openr/if/gen-py3/openr/thrift/OpenrCtrlCpp/clients.cpp", "openr-thrift/openr/if/gen-py3/OpenrCtrlCpp/clients_wrapper.cpp"], + library_dirs=extension_library_dirs, + include_dirs=extension_include_dirs, + libraries=extension_libraries, + ), + Extension("openr.thrift.OpenrCtrl.clients", + ["./openr-thrift/openr/if/gen-py3/openr/thrift/OpenrCtrl/clients.cpp", "openr-thrift/openr/if/gen-py3/OpenrCtrl/clients_wrapper.cpp"], + library_dirs=extension_library_dirs, + include_dirs=extension_include_dirs, + libraries=extension_libraries, + ), + Extension("openr.thrift.Platform.clients", + ["./openr-thrift/openr/if/gen-py3/openr/thrift/Platform/clients.cpp", "openr-thrift/openr/if/gen-py3/Platform/clients_wrapper.cpp"], + library_dirs=extension_library_dirs, + include_dirs=extension_include_dirs, + libraries=extension_libraries, + ), +] + +for root, dirs, files in os.walk('openr-thrift'): + for f in files: + if f.endswith(".pyx"): + pyx_file = (os.path.join(root, f)) + module = pyx_file.replace('openr-thrift/openr/if/gen-py3/', '').replace('.pyx', '').replace('/', '.') + cpp_file = pyx_file.replace('pyx', 'cpp') + if module in bespoke_extensions: continue - print("> Generating python definition for {}".format(thrift_file)) - check_call( - [ - "thrift1", - "--gen", - "py", - "-I", - root_dir, - *get_default_install_paths(), - "--out", - current_dir, - str(thrift_file), - ] - ) - - -generate_thrift_files() - -INSTALL_REQUIRES = ["bunch", "click", "hexdump", "jsondiff", "networkx", "tabulate"] + extensions += [ + Extension(module, + [cpp_file], + library_dirs=extension_library_dirs, + include_dirs=extension_include_dirs, + libraries=extension_libraries, + ), + ] + setup( - name="py-openr", - version="1.0", + name="openr", + version="2.0.0", author="Open Routing", author_email="openr@fb.com", description=( "OpenR python tools and bindings. Includes python bindings for various " + "OpenR modules, CLI tool for interacting with OpenR named as `breeze`." ), - # TODO: Fix fb303 library installation - packages=create_package_list("openr"), # + create_package_list("fb303"), + packages=create_package_list("openr"), entry_points={"console_scripts": ["breeze=openr.cli.breeze:main"]}, license="MIT License", install_requires=INSTALL_REQUIRES, - python_requires=">=3.6", + ext_modules=cythonize(extensions, compiler_directives={'language_level' : "3"}), + python_requires=">=3.7", ) +