Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Done] Write docs for runtime library finding + clean CI runners #387

Merged
merged 25 commits into from
Sep 21, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
11 changes: 3 additions & 8 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ on:
pull_request: # also build on PRs touching this file
paths:
- ".github/workflows/release.yml"
- "ci/*"

jobs:
build_sdist:
Expand Down Expand Up @@ -69,9 +70,8 @@ jobs:
- name: Cache GEOS build
uses: actions/cache@v2
with:
path: |
geos-${{ env.GEOS_VERSION }}
key: ${{ matrix.os }}-${{ matrix.archs }}-2
path: geos-${{ env.GEOS_VERSION }}
key: ${{ matrix.os }}-${{ matrix.archs }}-${{ env.GEOS_VERSION }}-${{ hashFiles('ci/*') }}

- name: Add GEOS LICENSE
run: |
Expand Down Expand Up @@ -125,11 +125,6 @@ jobs:
CIBW_BEFORE_BUILD_WINDOWS: pip install delvewheel
CIBW_REPAIR_WHEEL_COMMAND_WINDOWS: delvewheel repair --add-path ${{ github.workspace }}\geos-${{ env.GEOS_VERSION }}\bin -w {dest_dir} {wheel}
CIBW_TEST_REQUIRES: pytest
# The pytest command has the custom setting import-mode=importlib
# so that pytest does not mess up the PATH.
# If you do not do that, the (uncompiled) contents of
# {package}/pygeos will be tested against instead of the
# installed contents of the wheel that was built.
CIBW_TEST_COMMAND: pytest --pyargs pygeos.tests

- name: Upload artifacts
Expand Down
27 changes: 11 additions & 16 deletions .github/workflows/test-pip.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,12 @@ name: Test
on: [push, pull_request]

jobs:
TestLinux:
Test:
name: ${{ matrix.os }}-${{ matrix.architecture }} Py${{ matrix.python }} GEOS ${{ matrix.geos }}
runs-on: ${{ matrix.os }}
defaults:
run:
shell: bash
strategy:
fail-fast: false
matrix:
Expand Down Expand Up @@ -60,7 +63,7 @@ jobs:
- name: Cache GEOS and pip packages
uses: actions/cache@v2
with:
key: ${{ matrix.os }}-${{ matrix.architecture }}-geos-${{ matrix.geos }}
key: ${{ matrix.os }}-${{ matrix.architecture }}-geos-${{ matrix.geos }}-${{ hashFiles('ci/install_geos.sh') }}
path: |
~/.cache/pip
${{ github.workspace }}/geosinstall
Expand All @@ -72,19 +75,16 @@ jobs:
if: ${{ matrix.os == 'windows-2019' }}

- name: Correct slashes in GEOS_INSTALL (Windows)
shell: bash
run: |
echo 'GEOS_INSTALL=${{ github.workspace }}\geosinstall\geos-${{ matrix.geos }}' >> $GITHUB_ENV
if: ${{ matrix.os == 'windows-2019' }}

- name: Install GEOS
shell: bash
run: |
./ci/install_geos.sh
cd '${{ github.workspace }}'

- name: Install python dependencies
shell: bash
run: |
pip install --disable-pip-version-check --upgrade pip
pip install --upgrade wheel setuptools
Expand All @@ -96,42 +96,37 @@ jobs:
pip list

- name: Set environment variables (Linux)
shell: bash
run: |
echo "${{ env.GEOS_INSTALL }}/bin" >> $GITHUB_PATH
echo "LD_LIBRARY_PATH=${{ env.GEOS_INSTALL }}/lib" >> $GITHUB_ENV
if: ${{ matrix.os == 'ubuntu-latest' }}

- name: Set environment variables (OSX)
shell: bash
run: |
echo "${{ env.GEOS_INSTALL }}/bin" >> $GITHUB_PATH
echo "LDFLAGS=-Wl,-rpath,${{ env.GEOS_INSTALL }}/lib" >> $GITHUB_ENV
if: ${{ matrix.os == 'macos-latest' }}

# Python >=3.8 ignores the PATH for finding DLLs. We copy them into the package dir.
# Windows requires special treatment:
# - geos-config does not exist, so we specify include and library paths
# - Python >=3.8 ignores the PATH for finding DLLs, so we copy them into the package
- name: Set environment variables + copy DLLs (Windows)
shell: bash
run: |
cp geosinstall/geos-${{ matrix.geos }}/bin/*.dll pygeos
echo 'GEOS_LIBRARY_PATH=${{ env.GEOS_INSTALL }}\lib' >> $GITHUB_ENV
echo 'GEOS_INCLUDE_PATH=${{ env.GEOS_INSTALL }}\include' >> $GITHUB_ENV
if: ${{ matrix.os == 'windows-2019' }}

- name: Build PyGEOS
shell: bash
run: |
python setup.py build_ext --inplace
pip install --no-deps -e .

- name: Run tests
shell: bash
continue-on-error: ${{ matrix.geos == 'main' }}
run: |
pytest pygeos
run: pytest pygeos

# Only run doctests on 1 runner (because of typographic differences in doctest results)
- name: Run doctests
shell: bash
run: |
pytest --doctest-modules pygeos --ignore=pygeos/tests
run: pytest --doctest-modules pygeos --ignore=pygeos/tests
if: ${{ matrix.os == 'ubuntu-latest' && matrix.python == '3.8' }}
11 changes: 7 additions & 4 deletions ci/install_geos.sh
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,17 @@ prepare_geos_build_dir(){

build_geos(){
echo "Installing cmake"
pip install cmake ninja
pip install cmake

echo "Building geos-$GEOS_VERSION"
mkdir build
cd build
cmake -GNinja -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=ON -DCMAKE_INSTALL_PREFIX=$GEOS_INSTALL ..
cmake --build .
# ctest .
# Use Ninja on windows, otherwise, use the platform's default
if [ "$RUNNER_OS" = "Windows" ]; then
export CMAKE_GENERATOR=Ninja
fi
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$GEOS_INSTALL ..
cmake --build . -j 4
cmake --install .
}

Expand Down
41 changes: 25 additions & 16 deletions docs/installation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -98,27 +98,36 @@ GEOS discovery (runtime)
------------------------

PyGEOS is dynamically linked to GEOS. This means that the same GEOS library that was used
during PyGEOS compilation is required on your system. Make sure that the dynamic linker paths are
set such that the libraries are found.
during PyGEOS compilation is required on your system at runtime. When using pygeos that was distributed
as a binary wheel or through conda, this is automatically the case and you can stop reading.

When using a binary wheel, conda, the Anaconda shell, or the OSGeo4W shell, this is automatically
the case and you can stop reading. In other cases this can be tricky, especially if you have
multiple GEOS installations next to each other. For PyGEOS this can be solved by prepending
the GEOS path before you start Python.
In other cases this can be tricky, especially if you have multiple GEOS installations next
to each other. We only include some guidelines here to address this issue as this document is
not intended as a general guide of shared library discovery.

On Linux::
If you encountered exceptions like:

$ export LD_LIBRARY_PATH=/path/to/geos/lib:$LD_LIBRARY_PATH
$ sudo ldconfig # refresh dynamic linker cache
.. code-block:: none

On OSX::
ImportError: libgeos_c.so.1: cannot open shared object file: No such file or directory

You will have to make the shared library file available to the Python interpreter. There are in
general four ways of making Python aware of the location of shared library:

$ export DYLD_LIBRARY_PATH=/path/to/geos/lib:$DYLD_LIBRARY_PATH
1. Copy the shared libraries into the pygeos module directory (this is how Windows binary wheels work:
they are distributed with the correct dlls in the pygeos module directory)
2. Copy the shared libraries into the library directory of the Python interpreter (this is how
Anaconda environments work)
3. Copy the shared libraries into some system location (``C:\Windows\System32``; ``/usr/local/lib``,
this happens if you installed GEOS through ``apt`` or ``brew``)
4. Add the shared library location to a the dynamic linker path variable at runtime.
(Advanced usage; Linux and OSX only; on Windows this method was deprecated in Python 3.8)

On Windows::
The filenames of the GEOS shared libraries are:

$ set PATH=C:\path\to\geos\bin;%PATH%
* On Linux: ``libgeos-*.so.*, libgeos_c-*.so.*``
* On OSX: ``libgeos.dylib, libgeos_c.dylib``
* On Windows: ``geos-*.dll, geos_c-*.dll``

Note that setting environment variables like this is temporary. You will need to
repeat this every time before you want to use PyGEOS. Also, it will influence other
applications that are using GEOS; they may find a different GEOS version and crash.
Note that pygeos does not make use of any RUNPATH (RPATH) header. The location
of the GEOS shared library is not stored inside the compiled PyGEOS library.
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from pathlib import Path

from pkg_resources import parse_version
from setuptools import Extension, setup, find_packages
from setuptools import Extension, find_packages, setup
from setuptools.command.build_ext import build_ext as _build_ext

import versioneer
Expand Down