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

Use meson-build and pyproject.toml #22

Open
wants to merge 14 commits into
base: master
Choose a base branch
from
Open
11 changes: 5 additions & 6 deletions .github/workflows/ci-ubuntu.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,9 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ['3.7', '3.8', '3.9', '3.10', '3.11']
python-version: ['3.9', '3.10', '3.11', '3.12', '3.13']
# Steps represent a sequence of tasks that will be executed as part of the job
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout@main
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@main
Expand All @@ -34,10 +33,10 @@ jobs:
python -m pip install --upgrade pip
- name: Install the package
run: |
export SETUPTOOLS_ENABLE_FEATURES="legacy-editable"
pip install -e .
# Show f2py compiler info for debug
f2py -c --help-fcompiler
# https://mesonbuild.com/meson-python/how-to-guides/editable-installs.html
python -m pip install -v .
- name: Run tests
run: |
# Force to use the installed package and not the one from the local repo.
rm pypolsys/__init__.py
python -m pypolsys.test
12 changes: 4 additions & 8 deletions .github/workflows/ci-windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
- uses: conda-incubator/setup-miniconda@main
with:
activate-environment: polsys_env
python-version: 3.11
python-version: 3.12
auto-activate-base: false
miniconda-version: "latest"
auto-update-conda: true
Expand All @@ -29,19 +29,15 @@ jobs:
# Use conda to manage the building toolchain, but is now outdated
# https://numpy.org/doc/stable/f2py/windows/index.html
conda install m2w64-toolchain libpython
# numpy is required for pypolsys building. Better to install it with conda.
# Sometime it fails when installed by pip thought `build-system` requirement from `pyproject.toml`
# Limit setuptools version because of numpy.distutils
conda install numpy "setuptools<60.0" wheel
- name: Build
shell: bash -l {0}
run: |
# Ignore `pyproject.toml` to avoid conda/pip mix in numpy version
python -m pip install -e . --no-use-pep517
# Show f2py compiler info for debug
f2py -c --help-fcompiler
python -m pip install -v .
- name: Test
shell: bash -l {0}
run: |
# force to use the installed package and not the one from the local repo.
rm pypolsys/__init__.py
python -m pypolsys.test

38 changes: 14 additions & 24 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,48 +37,37 @@ To facilitate the build of this module, a copy of `POLSYS_PLP` *original* source
## Installation

You'll need :
* python (tested for v >= 3.5);
* python (tested for v >= 3.8);
* pip (optional);
* fortran compiler (tested with `gfortran` and with `m2w64-toolchain` on windows)
* lapack and blas installation (only on linux). The useful lapack/blas routines are also shipped with `POLSYS_PLP` sources and built by default on Window or on demand on linux (see below). Optimized library are preferred and often already present on linux systems. If not, library like `openblas` and the required development files can be installed with `sudo apt install libopenblas-dev` on debian based distribution (including ubuntu).

If needed, please see the steps given in the continuous integration script [workflows](.github/workflows/ci-ubuntu.yml).
If needed, please see the steps given in the continuous integration scripts [ci-ubuntu](.github/workflows/ci-ubuntu.yml) or [ci-windows](.github/workflows/ci-windows.yml).

### Using pip (preferred)
### Using pip
You can install `pypolsys` from pip:
```
pip install pypolsys [--user]
```
You can also install `pypolsys` after a download from github:
You can also install `pypolsys` after a download from github or after cloning the repos:
```
pip install path/to/pypolsys-version.tar.gz [--user]
```
or in _editable_ mode if you want to modify the sources
Installation can be done _editable_ mode if you want to modify the sources:
```
pip install -e path/to/pypolsys
python -m pip install --no-build-isolation --editable .
```
after cloning the repos.
In this case, compatible version of meson, meson-python and ninja have to be installed before (see `pyproject.toml` file).

`pip` will install `numpy` (mandatory) and `sympy` and `scipy` (optional, required only for tests).

Note that on ubuntu, you will need to use `pip3` instead of `pip` and `python3` instead of `python`.

On linux, if you want to force the building with `POLSYS_PLP` lapack sources, you can tell it to pip with
### Running tests
To execute the full test suite, run :
```
pip install --no-use-pep517 --install-option="--buildLapack" path/to/pypolsys
python -m pypolsys.test
```
The flag `--no-use-pep517` avoids side effect of `install-option` that disable wheels.
Using `POLSYS_PLP` lapack sources is the standard behavior on windows.

### Troubleshooting
With old `gfortran` version present on ubuntu 16.04 (see [here](https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84276)) the building may failed. To avoid this, `intent(in, out)` statement has to be removed from the original `pypolsys/801/polsys_plp.f90`. It seems to work out of the box with `gfortan-8`.

### Running tests

To execute the full test suite, run :
```
python -m pypolsys.test
```

## Usage
Note that this projet is a work in progress and the API may change.
Expand Down Expand Up @@ -204,9 +193,10 @@ Before submitting a PR, run the tests suite ;-)
If you need to modify `wrapper.f90` fortran source file. You will need to re-build the Fortran extension. This should be done into 2 steps
1. The pyf file that avoid trouble with user_defined fortran type should be updated with `f2py` utilities :

```
f2py -m polsys -h polsys.pyf wrapper.f90 --overwrite-signature
```
```
f2py -m polsys -h polsys.pyf wrapper.f90 --overwrite-signature
```

2. Re run the install


Expand Down
108 changes: 108 additions & 0 deletions meson.build
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
project(
'pypolsys',
'c',
version: run_command('pypolsys/version.py', check: true).stdout().strip(),
license: 'GNU General Public License v3 (GPLv3)',
meson_version: '>=0.64.0',
default_options: ['warning_level=2', 'buildtype=release'],
)

add_languages('fortran', native: true)
# load meson python module
py_mod = import('python')
py = py_mod.find_installation(pure: false)
py_dep = py.dependency()

# Get include from numpy and f2py
# based on https://numpy.org/doc/stable/f2py/buildtools/meson.html
incdir_numpy = run_command(
py,
[
'-c',
'import os; os.chdir(".."); import numpy; print(numpy.get_include())',
],
check: true,
).stdout().strip()

incdir_f2py = run_command(
py,
[
'-c',
'import os; os.chdir(".."); import numpy.f2py; print(numpy.f2py.get_include())',
],
check: true,
).stdout().strip()

inc_np = include_directories(incdir_numpy, incdir_f2py)

# Need to call f2py to process pyf files
# Based on https://numpy.org/doc/stable/f2py/buildtools/meson.html and
# https://github.com/scipy/scipy/blob/5e986a24f0ab03fbb382ed67ef15895024334481/scipy/io/meson.build#L4
# From https://numpy.org/doc/stable/f2py/buildtools/index.html
# For Fortran 90 programs, f2py generates for an input file blah.f90
# blahmodule.c
# blah-f2pywrappers.f, makes subroutines for functions, it rewrites assumed shape arrays as automatic arrays (empty for pypolsys).
# blah-f2pywrappers2.f90, handles code which is subdivided into modules

# Copy .f2py_f2cmap in buildir (f2py needs it in the working dir)
fs = import('fs')
fs.copyfile('.f2py_f2cmap')
_polsys_module = custom_target(
'polsys',
output: [
'polsysmodule.c',
'polsys-f2pywrappers2.f90',
'polsys-f2pywrappers.f',
],
input: ['pypolsys/src/polsys.pyf'],
command: [py, '-m', 'numpy.f2py', '@INPUT@', '--lower'],
)
# Pypolsys extension own src files
src_files = [
_polsys_module,
'pypolsys/801/polsys_plp.f90',
'pypolsys/src/wrapper.f90',
]
# Lapack
lapack_dep = dependency('lapack', required: false)
if not lapack_dep.found()
# Need to compile lapack too
src_files += 'pypolsys/801/lapack_plp.f'
endif

# Assumes that f2py was run before in _polsys_module
py.extension_module(
'polsys',
src_files,
incdir_f2py / 'fortranobject.c',
include_directories: inc_np,
# No problem if lapack_dep is not found, meson just ignore it
dependencies: [py_dep, lapack_dep],
install: true,
link_language: 'fortran',
native: true,
subdir: 'pypolsys', # Folder relative to site-packages to install to
)

# Add pure python files
# Another approach is to split in two meso.build files
python_sources = [
'pypolsys/__init__.py',
'pypolsys/test.py',
'pypolsys/utils.py',
'pypolsys/version.py',
]

# Install pure Python
# see https://mesonbuild.com/Python-module.html
py.install_sources(
python_sources,
pure: false, # Will be installed next to binaries
subdir: 'pypolsys', # Folder relative to site-packages to install to
)

# Add package_data used for tests as source files
install_dir = py.get_install_dir(subdir: 'pypolsys/examples/data')
install_data('pypolsys/examples/data/toy_model.npz', install_dir: install_dir) # / 'examples' / 'data'


6 changes: 5 additions & 1 deletion pypolsys/version.py
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
__version__ = '0.1.4'
#!/usr/bin/env python3
__version__ = '0.1.5'

if __name__ == '__main__':
print(__version__)
33 changes: 32 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,2 +1,33 @@
[build-system]
requires=['setuptools<60.0', 'wheel', 'numpy']
build-backend = 'mesonpy'
requires = ['meson-python>=0.15.0', 'cython', 'numpy']

[project]
name = 'pypolsys'
dynamic = ["version"]
description = "A python wrapper to `POLSYS_PLP` fortran90 package from Layne T. Watson, Steven M. Wise, Andrew J. Sommese, August, 1998."
readme = 'README.md'
license = {file = 'LICENSE'}
requires-python = '>=3.8'
authors = [
{name = "B. Nennig", email = '[email protected]'},
]
dependencies = [
"numpy",
"scipy",
"sympy",
]
classifiers = [
# How mature is this project?
"Development Status :: 5 - Production/Stable",
# Indicate who your project is intended for
"Topic :: Scientific/Engineering",
# Specify the Python versions you support here.
"Programming Language :: Python :: 3",
"License :: OSI Approved :: GNU General Public License v3 (GPLv3)",
"Operating System :: OS Independent",
]

[project.urls]
homepage = "https://github.com/nennigb/pypolsys"

Loading
Loading