Skip to content

Commit

Permalink
Build wheels for Windows with vcpkg and cibuildwheel on github actions (
Browse files Browse the repository at this point in the history
  • Loading branch information
jorisvandenbossche authored Mar 16, 2022
1 parent 9f9b9f4 commit d243d02
Show file tree
Hide file tree
Showing 5 changed files with 152 additions and 4 deletions.
92 changes: 92 additions & 0 deletions .github/workflows/build_wheel_windows.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
name: Build wheels for Windows

on:
push:
branches:
- main # just build the sdist & wheel, skip release
tags:
- "*"
pull_request: # also build on PRs touching files that affect wheels
paths:
- ".github/workflows/build_wheel.yml"
- "MANIFEST.in"
- "pyproject.toml"
- "setup.py"

jobs:
build_wheels:
name: Build wheels on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [windows-2019]

steps:
- name: Checkout
uses: actions/checkout@v2
with:
fetch-depth: 0

- name: Cache vcpkg
uses: actions/cache@v1
id: vcpkgcache
with:
path: C:/vcpkg/installed
key: ${{ runner.os }}-vcpkg

- name: Install GDAL
run: |
vcpkg install gdal[core]:x64-windows
- name: Build wheels
uses: pypa/[email protected]

- uses: actions/upload-artifact@v2
with:
path: ./wheelhouse/*.whl

test_wheels:
name: windows py${{ matrix.python-version }} tests
runs-on: windows-latest
needs: build_wheels
strategy:
fail-fast: false
matrix:
python-version: ['3.8', '3.9', '3.10']

steps:
- name: Checkout
uses: actions/checkout@v2
with:
submodules: false

- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}
cache: 'pip'
cache-dependency-path: 'ci/requirements-wheel-test.txt'

- name: Download wheels from artifacts
uses: actions/download-artifact@v2
with:
path: wheelhouse

- name: Set version string
shell: bash
run: echo "py_version_str=cp$(echo ${{ matrix.python-version }} | tr -d -c 0-9)" >> $GITHUB_ENV

- name: Install dependencies and pyogrio wheel
shell: bash
run: |
python -m pip install -r ci/requirements-wheel-test.txt
python -m pip install --no-deps geopandas
ls -R wheelhouse
python -m pip install wheelhouse/artifact/pyogrio-*${{ env.py_version_str }}*.whl
python -m pip list
- name: Run tests
shell: bash
run: |
cd ..
python -m pytest --pyargs pyogrio
1 change: 1 addition & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ include versioneer.py
include pyogrio/_version.py
include pyogrio/*.pyx pyogrio/*.pxd
exclude pyogrio/*.c
recursive-include pyogrio/tests/fixtures *
6 changes: 6 additions & 0 deletions ci/requirements-wheel-test.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
pytest
# dependencies of geopandas (installed separately with --no-deps to avoid fiona)
pandas
pyproj
shapely
packaging
17 changes: 17 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,20 @@ requires = [
"Cython>=0.29",
"oldest-supported-numpy",
]

[tool.cibuildwheel]
skip = ["cp36-*", "cp37-*", "pp*"]

[tool.cibuildwheel.windows]
archs = ["auto64"]

before-build = "pip install delvewheel"
repair-wheel-command = "delvewheel repair --add-path C:/vcpkg/installed/x64-windows/bin -w {dest_dir} {wheel}"

[tool.cibuildwheel.windows.environment]
VCPKG_INSTALL = "$VCPKG_INSTALLATION_ROOT/installed/x64-windows"
GDAL_INCLUDE_PATH = "$VCPKG_INSTALL/include"
GDAL_LIBRARY_PATH = "$VCPKG_INSTALL/lib"
PYOGRIO_PACKAGE_DATA = 1
GDAL_DATA = "$VCPKG_INSTALL/share/gdal"
PROJ_LIB = "$VCPKG_INSTALL/share/proj4"
40 changes: 36 additions & 4 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import sys

from distutils import log
from setuptools import setup
from setuptools import setup, find_packages
from setuptools.extension import Extension
import versioneer

Expand All @@ -29,6 +29,12 @@
raise RuntimeError("Python >= 3.8 is required")


def copy_data_tree(datadir, destdir):
if os.path.exists(destdir):
shutil.rmtree(destdir)
shutil.copytree(datadir, destdir)


# Get GDAL config from gdal-config command
def read_response(cmd):
return subprocess.check_output(cmd).decode("utf").strip()
Expand Down Expand Up @@ -108,11 +114,13 @@ def get_gdal_paths():


ext_modules = []
package_data = {}

# setuptools clean does not cleanup Cython artifacts
if "clean" in sys.argv:
if os.path.exists("build"):
shutil.rmtree("build")
for directory in ["build", "pyogrio/gdal_data", "pyogrio/proj_data"]:
if os.path.exists(directory):
shutil.rmtree(directory)

root = Path(".")
for ext in ["*.so", "*.pyc", "*.c", "*.cpp"]:
Expand Down Expand Up @@ -153,6 +161,29 @@ def run(self):
except ImportError:
pass

if os.environ.get("PYOGRIO_PACKAGE_DATA"):
gdal_data = os.environ.get("GDAL_DATA")
if gdal_data and os.path.exists(gdal_data):
log.info(f"Copying gdal data from {gdal_data}")
copy_data_tree(gdal_data, "pyogrio/gdal_data")
else:
raise Exception(
"Could not find GDAL data files for packaging. "
"Ensure to set the GDAL_DATA environment variable"
)

proj_data = os.environ.get("PROJ_LIB")
if proj_data and os.path.exists(proj_data):
log.info(f"Copying proj data from {proj_data}")
copy_data_tree(proj_data, "pyogrio/proj_data")
else:
raise Exception(
"Could not find PROJ data files for packaging. "
"Ensure to set the PROJ_LIB environment variable"
)

package_data = {"pyogrio": ["gdal_data/*", "proj_data/*"]}


version = versioneer.get_version()
cmdclass = versioneer.get_cmdclass()
Expand All @@ -161,7 +192,7 @@ def run(self):
setup(
name="pyogrio",
version=version,
packages=["pyogrio"],
packages=find_packages(),
url="https://github.com/pyogrio/pyogrio",
license="MIT",
author="Brendan C. Ward",
Expand All @@ -180,4 +211,5 @@ def run(self):
include_package_data=True,
cmdclass=cmdclass,
ext_modules=ext_modules,
package_data=package_data,
)

0 comments on commit d243d02

Please sign in to comment.