Skip to content

Commit

Permalink
[Done] Write docs for runtime library finding + clean CI runners (#387)
Browse files Browse the repository at this point in the history
* Use runtime_library_dirs

* Update release.yml

* Update release.yml

* Update setup.py

* Clean [ci skip]

* Clean

* Attempt windows build bash script

* Use bash shell

* Revert

* Attempt to fix OSX build

* Re-enable cache and fix build script

* Install Ninja on windows

* Update install_geos.sh

* Update install_geos.sh

* Revert some stuff

* Update docs [ci skip]

* Update docs [ci skip]

* Fix docs [ci skip]

* PR Changes

* Fix test-pip.yml

* Bump GEOS 3.8 test to 3.8.2

* Revert [skip ci]

* Re-enable test compilation
  • Loading branch information
caspervdw committed Sep 21, 2021
1 parent 46bbcb6 commit 7aaf0d1
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 45 deletions.
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

0 comments on commit 7aaf0d1

Please sign in to comment.