Skip to content

Commit

Permalink
Add python packaging support
Browse files Browse the repository at this point in the history
Signed-off-by: Peyton Murray <peynmurray@gmail.com>
  • Loading branch information
peytondmurray committed May 13, 2022
1 parent 2561c25 commit c232888
Show file tree
Hide file tree
Showing 6 changed files with 210 additions and 5 deletions.
63 changes: 63 additions & 0 deletions .github/workflows/pypi_release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
name: Build and Release Python Bindings to PyPI

on:
release:
types: [published]
workflow_dispatch:
inputs:
tag:
default: ''
required: false
description: Ref to build

jobs:
build-sdist:
name: Build sdist
runs-on: ubuntu-latest
steps:
- name: Checkout the repo 
uses: actions/checkout@v3
with:
ref: ${{ github.event.inputs.tag }}

- name: Set up Python 🐍
uses: actions/setup-python@v3
with:
python-version: '3.10'

- name: Install system dependencies 
run: |
sudo apt-get install -y build-essential cmake libboost-all-dev libjemalloc-dev libtbb-dev libblosc-dev zlib1g-dev
- name: Install build dependencies 
run: |
python -m pip install build
- name: Build the sdist 📦
working-directory: ./openvdb/openvdb/python
run: |
python -m build --sdist
- name: Upload artifact ⇑
uses: actions/upload-artifact@v3
with:
name: dist
path: ./openvdb/openvdb/python/dist/

publish:
name: Publish Python packages on PyPI
needs: [build-sdist, build-wheels]
runs-on: ubuntu-latest
steps:
- name: Download artifacts ⇓
uses: actions/download-artifact@v3
with:
name: dist
path: dist

- name: Publish to PyPI 🎉
uses: pypa/gh-action-pypi-publish@master
with:
user: __token__
password: ${{ secrets.PYPI_API_TOKEN }}
packages_dir: dist
7 changes: 7 additions & 0 deletions openvdb/openvdb/python/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
CMakeCache.txt
CMakeFiles/
Makefile
cmake_install.cmake
*.egg-info/
*.so
_skbuild/
21 changes: 16 additions & 5 deletions openvdb/openvdb/python/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,14 @@ if(USE_NUMPY)
list(APPEND OPENVDB_PYTHON_REQUIRED_COMPONENTS NumPy)
endif()

# scikit-build doesn't yet support FindPython, but this workaround was
# supplied by one of the scikit-build devs. See
# https://github.com/pypa/cibuildwheel/issues/727 for details.
if(SKBUILD)
set(Python_EXECUTABLE "${PYTHON_EXECUTABLE}")
set(Python_NumPy_INCLUDE_DIR "${NUMPY_INCLUDE_DIR}")
endif()

# Make sure find_package(Python) is only ever invoked once with all required components
find_package(Python COMPONENTS ${OPENVDB_PYTHON_REQUIRED_COMPONENTS})

Expand Down Expand Up @@ -283,17 +291,20 @@ if(USE_AX)
target_compile_definitions(pyopenvdb PUBLIC "-DPY_OPENVDB_USE_AX")
endif()

set(PYTHON_PUBLIC_INCLUDE_NAMES
pyopenvdb.h
)

install(TARGETS
pyopenvdb
DESTINATION
${PYOPENVDB_INSTALL_DIRECTORY}
)

install(FILES ${PYTHON_PUBLIC_INCLUDE_NAMES} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/openvdb/python)
# Disable copying this file over during the build; it will be copied by skbuild to the correct
# site-package directory automatically
if(NOT SKBUILD)
set(PYTHON_PUBLIC_INCLUDE_NAMES
pyopenvdb.h
)
install(FILES ${PYTHON_PUBLIC_INCLUDE_NAMES} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/openvdb/python)
endif()

# pytest
if(OPENVDB_BUILD_PYTHON_UNITTESTS)
Expand Down
75 changes: 75 additions & 0 deletions openvdb/openvdb/python/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# pyopenvdb

This project contains python bindings for OpenVDB.

## Dependencies

| Name | Version |
| --- | --- |
| cmake | 3.15 |
| boost | 1.70 |
| numpy | 1.14 |
| openvdb | >9.0.0 |

## Installing from source

Installation using `pip` is preferred because it manages the package version
sensibly, and also automatically handles finding the correct python
installation.

### Using pip

The python bindings for OpenVDB can be installed using `pip install .`. In this
case, the build build toolchain executes in the following order:

1. `setup.py` is executed, calling `scikit-build`'s [`setup`
function](https://scikit-build.readthedocs.io/en/latest/usage.html#setup-options).
`scikit-build` acts as [glue between `setuptools` and
`cmake`](https://scikit-build.readthedocs.io/en/latest/).
2. `setuptools_scm` generates a version string for the python package. If
building on a git tag, the python version will be identical to the tag. See
[this page](https://github.com/pypa/setuptools_scm#default-versioning-scheme)
for more information about the versioning scheme.
3. `scikit-build` passes a sensible default set of flags, defined in `setup.py`,
to `cmake`, which generates build files the project (ninja or GNU make)
before using them to build the project.
4. `pip` copies the resulting shared object into your python installation's
`site-packages` directory. C headers for the python bindings are installed to
your python installation's `sys.prefix`, under
`include/pythonX.Y/pyopenvdb/`.

### Using cmake

Build files for the C++ code are generated by `cmake`, so the bindings can be
built by invoking

```bash
mkdir build
cd build
cmake ..
cmake --build .
cmake --install .
```

This will generate build files, build a shared object library, and copy it into
your python installation's `site-packages` directory, where it can be imported
directly. If you wish to target a particular version of python, this can be done
by setting [the appropriate cmake
flags](https://cmake.org/cmake/help/latest/module/FindPython.html).
`CMakeLists.txt` contains a full listing of build options for more
customization; by default the `pyopenvdb` package on PyPI is built with all the
optional functionality enabled.

## Releasing to PyPI

Using GitHub actions, new `pyopenvdb` versions are published to PyPI
automatically when a new OpenVDB release is made. Releases can also published to
PyPI by triggering the "Build and Release Python Bindings to PyPI" job, and
specifying a branch/ref; if no ref is specified, the most recent commit on the
given branch is used. Publishing to PyPI requires an API token to be specified
as a secret (`PYPI_API_TOKEN`) on the repository.

## Contributors

Thanks to Alex Braun (@theNewFlesh) for contributing the original python
packaging for pyopenvdb.
9 changes: 9 additions & 0 deletions openvdb/openvdb/python/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[build-system]
requires = [
"setuptools>=42",
"setuptools_scm[toml]>=6.2",
"wheel",
"scikit-build",
"cmake",
"numpy"
]
40 changes: 40 additions & 0 deletions openvdb/openvdb/python/setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import sys
import pathlib
import numpy as np
from skbuild import setup


with open(pathlib.Path(__file__).parent / "README.md") as f:
long_description = f.read()


# Explicitly set NUMPY_INCLUDE_DIR because cmake fails to find it otherwise.
# Same is true for the boost python libs.
setup(
name="pyopenvdb",
use_scm_version={
"root": '../../..',
"relative_to": __file__,
},
author="OpenVDB",
author_email="openvdb-dev@lists.aswf.io",
description=(
"Python bindings for OpenVDB: sparse volume data structure and tools."
),
download_url="https://pypi.python.org/pypi/pyopenvdb",
headers=['pyopenvdb.h'],
include_package_data=True,
license="Mozilla Public License 2.0",
long_description=long_description,
long_description_content_type='text/markdown',
url="https://github.com/AcademySoftwareFoundation/openvdb",
cmake_args=[
'-DUSE_NUMPY=ON',
'-DOPENVDB_PYTHON_WRAP_ALL_GRID_TYPES=ON',
'-DOPENVDB_BUILD_CORE=ON',
f'-DNUMPY_INCLUDE_DIR={np.get_include()}',
f'-DBoost_PYTHON_VERSION={sys.version_info[0]}.{sys.version_info[1]}',
],
cmake_install_dir='.',
cmake_source_dir='.',
)

0 comments on commit c232888

Please sign in to comment.