Skip to content

Commit

Permalink
Switch Python build system to use mesonpy instead of setuptools (#24)
Browse files Browse the repository at this point in the history
This PR solves a couple of problems at once. I got an email from a user complaining that the setuptools build system couldn't handle multiple photospline and boost being in different directories. Meson's pkg-config dependency detection is far superior to anything you can ad hoc program in setuptools. This allowed some cleanup that I had wanted to do regarding the meson build file. Also, one of the reasons that I gave up on making wheels for nuflux was that setuptools couldn't figure out how to include header files while mesonpy does this automatically. The files changed looks big but that is just because I also moved the python source directory to /src/.

The only change from the user perspective is that when compiling you now use exactly the same env vars for both meson and python. Documentation has been updated to reflect this. cvmfs target py3-v4.0.1 was dropped because the last version of meson that worked with python 3.6 doesn't support the pure option for python. And py3-v4.2.1 was dropped because mesonpy doesn't play well with the python misconfiguration present in that version of cvmfs.
  • Loading branch information
kjmeagher authored Jan 22, 2024
1 parent 07ab4b1 commit daad99d
Show file tree
Hide file tree
Showing 189 changed files with 385 additions and 222 deletions.
30 changes: 15 additions & 15 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@ jobs:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest]
build: [meson, setuptools]
build: [meson, pyproject]
include:
- os: ubuntu-latest
python-version: "3.10"
- os: macos-latest
python-version: "3.11"
python-version: "3.12"
steps:
- name: Checkout nuflux
uses: actions/checkout@v2
Expand All @@ -31,24 +31,24 @@ jobs:
sudo apt-get update
sudo apt-get install ninja-build gcovr libcfitsio-dev python-is-python3 libboost-python-dev doxygen
sudo dpkg -r lcov
curl -L https://github.com/icecube/photospline/archive/refs/tags/v2.1.0.tar.gz | tar xz
cmake -S photospline-2.1.0 -B photospline -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr
curl -L https://github.com/icecube/photospline/archive/refs/tags/v2.2.1.tar.gz | tar xz
cmake -S photospline-2.2.1 -B photospline -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr
sudo make install -C photospline
- name: HomeBrew Install Dependencies
if: startsWith( matrix.os, 'macos')
run: |
brew tap icecube/icecube
brew install boost-python3 ninja doxygen cfitsio gcovr icecube/icecube/photospline
- name: Build nuflux with setuptools
if: matrix.build == 'setuptools'
- name: Build nuflux with pyproject
if: matrix.build == 'pyproject'
run: |
python3 -m pip install .[test]
python3 -m pytest
- name: Build nuflux with Meson
if: matrix.build == 'meson'
run: |
python3 -m pip install meson numpy sphinx breathe sphinx_rtd_theme pytest pytest-subtests
meson setup build . -D b_coverage=true
meson setup build . -D b_coverage=true --prefix=${HOME}/inst/
ninja -C build test
- name: Generate Coverage Report and Docs
if: matrix.build == 'meson' && startsWith( matrix.os, 'ubuntu')
Expand All @@ -72,7 +72,7 @@ jobs:
strategy:
fail-fast: false
matrix:
cvmfs: [py3-v4.0.1, py3-v4.1.1, py3-v4.2.1, py3-v4.3.0]
cvmfs: [py3-v4.1.1, py3-v4.2.1, py3-v4.3.0]
steps:
- uses: cvmfs-contrib/github-action-cvmfs@v3
- name: Checkout nuflux
Expand All @@ -89,25 +89,25 @@ jobs:
pip install --user meson ninja pytest pytest-subtests
CMAKE_PREFIX_PATH=${SROOT} BOOST_ROOT=${SROOT} meson setup build /nuflux
ninja -Cbuild test
cvmfs_setuptools_tests:
name: cvmfs setuptools tests ${{matrix.cvmfs}}
cvmfs_pyproject_tests:
name: cvmfs pyproject tests ${{matrix.cvmfs}}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
cvmfs: [py3-v4.0.1, py3-v4.1.1, py3-v4.2.1, py3-v4.3.0]
cvmfs: [py3-v4.1.1, py3-v4.3.0]
steps:
- uses: cvmfs-contrib/github-action-cvmfs@v3
- name: Checkout nuflux
uses: actions/checkout@v2
- name: Build and Run Tests in Docker
uses: addnab/docker-run-action@v3
with:
options: -v /cvmfs/icecube.opensciencegrid.org/:/cvmfs/icecube.opensciencegrid.org/ -v /home/runner/work/nuflux/nuflux:/nuflux
options: -v /cvmfs/icecube.opensciencegrid.org/:/cvmfs/icecube.opensciencegrid.org/ -v /home/runner/work/nuflux/nuflux:/nf
image: centos:centos7.9.2009
run: |
yum -y install glibc-headers glibc-devel
eval $(/cvmfs/icecube.opensciencegrid.org/${{matrix.cvmfs}}/setup.sh)
pip install --user wheel pytest pytest-subtests
PREFIX=${SROOT} pip install --user --no-build-isolation /nuflux
python3 -m pytest /nuflux
python3 -m pip install --user pip pytest pytest-subtests
BOOST_ROOT=${SROOT} python3 -m pip install --user --verbose /nf
python3 -m pytest /nf
14 changes: 7 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,14 @@ If you only need to use python you can install it directly through pip:

pip install --user git+https://github.com/icecube/nuflux

Note that this may fail if photospline and boost_python are installed in nonstandard locations, e.g. headers in /opt/toolsets/mystuff/include, libraries in /opt/toolsets/mystuff/lib. In this case, set the `PREFIX` environment variable to the root of your toolset installation:
Note that this may fail if photospline and boost_python are installed in nonstandard locations, e.g. headers in /opt/toolsets/photospline/include, libraries in /opt/toolsets/photospline/lib. In this case, set the `CMAKE_PREFIX_PATH` environment variable to the root of your photospline installation and `BOOST_ROOT` to the root of your boost installation:

PREFIX=/opt/toolsets/mystuff pip install --user git+https://github.com/icecube/nuflux
CMAKE_PREFIX_PATH=/opt/toolsets/photospline BOOST_ROOT=/opt/toolsets/boost pip install --user git+https://github.com/icecube/nuflux

If you are running it in IceCube's cvmfs environment you will want to set `PREFIX` to the base of the cvmfs envionment which is stored in the envionment variable `SROOT`:
If you are running it in IceCube's cvmfs environment you will want to set `CMAKE_PREFIX_PATH` and `BOOST_ROOT` to the base of the cvmfs envionment which is stored in the environment variable `SROOT`:

eval `/cvmfs/icecube.opensciencegrid.org/py3-v4.1.1/setup.sh`
PREFIX=${SROOT} pip install --user git+https://github.com/icecube/nuflux
eval `/cvmfs/icecube.opensciencegrid.org/py3-v4.3.0/setup.sh`
CMAKE_PREFIX_PATH=${SROOT} BOOST_ROOT=${SROOT} pip install --user git+https://github.com/icecube/nuflux

#### Meson

Expand All @@ -55,11 +55,11 @@ For example, in IceCube's cvmfs envionment you should do:

CMAKE_PREFIX_PATH=${SROOT} BOOST_ROOT=${SROOT} meson setup build . --prefix=/path/to/instal/to

the option -Ddata_path can be used to install to a directory outside of the PREFIX directory.
the option -Ddata_path can be used to install the raw flux tables to a directory outside of the PREFIX directory.

If you want to install to a read-only file system you can pass -Dinstall_data=False

You may also use the environment variable `NUFLUX_DATA` to specify the path of the nuflux data tables if they are in a
You may also use the environment variable `NUFLUX_DATA` to specify the path of the raw flux tables if they are in a
place other than where they were installed to.

## Documentation
Expand Down
Binary file added a.out
Binary file not shown.
4 changes: 2 additions & 2 deletions docs/installation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,11 @@ Here are some errors that have been encountered with Python and Meson installati

* **photospline and boost are installed in non-standard locations**

The Python installation may fail if photospline and boost_python are installed in non-standard locations, e.g. headers in ``/opt/toolsets/mystuff/include``, libraries in ``/opt/toolsets/mystuff/lib``. In this case, set the `PREFIX` environment variable to the root of your toolset installation:
The Python installation may fail if photospline and boost_python are installed in non-standard locations, e.g. headers in ``/opt/toolsets/mystuff/include``, libraries in ``/opt/toolsets/mystuff/lib``. In this case, set the `CMAKE_PREFIX_PATH` and `BOOST_ROOT` environment variables to the root of your toolset installation:

::

PREFIX=/opt/toolsets/mystuff pip install --user git+https://github.com/icecube/nuflux
CMAKE_PREFIX_PATH=/opt/toolsets/photospline and `BOOST_ROOT`=/opt/toolsets/boost pip install --user git+https://github.com/icecube/nuflux


* **Meson is out of date**
Expand Down
109 changes: 18 additions & 91 deletions meson.build
Original file line number Diff line number Diff line change
@@ -1,102 +1,29 @@
project('nuflux', 'cpp',
version : '2.0.4',
default_options : ['cpp_std=c++17'])
version: '2.0.4',
default_options: ['cpp_std=c++17'])

cfitsio = dependency('cfitsio')
photospline = dependency('photospline', method : 'cmake')

datadir = get_option('data_path')
if datadir == ''
datadir = get_option('prefix') / get_option('datadir') / meson.project_name()
endif
conf_data = configuration_data()
conf_data.set_quoted('DATA_DIR',datadir)
configure_file(output : 'config.h',
configuration : conf_data)
if get_option('install_data')
install_subdir('nuflux/data/',
install_dir:datadir,
strip_directory:true)
conf_data.set_quoted('NUFLUX_VERSION',meson.project_version())
if not get_option('pymodule')
datadir = get_option('data_path')
if datadir == ''
datadir = get_option('prefix') / get_option('datadir') / meson.project_name()
endif
conf_data.set_quoted('DATA_DIR',datadir)
endif

subdir('src/include/nuflux')
configure_file(
output: 'config.h',
configuration: conf_data)
configuration_inc = include_directories('.')

inc = include_directories('src/include')
libnuflux = library(
'nuflux',
'src/library/ANFlux.cpp',
'src/library/IPLEFlux.cpp',
'src/library/LegacyConventionalFlux.cpp',
'src/library/SplineFlux.cpp',
'src/library/SplineFlux2.cpp',
'src/library/FluxFunction.cpp',
'src/library/LegacyPromptFlux.cpp',
'src/library/detail.cpp',
include_directories : inc,
dependencies : [photospline,cfitsio],
install : true)

init_file = files('src/nuflux/__init__.py')
subdir('src/include/nuflux')
subdir('src/library')
subdir('src/pybindings')
subdir('src/nuflux/data')
subdir('tests')

pkg_mod = import('pkgconfig')
pkg_mod.generate(
libraries : libnuflux,
version : meson.project_version(),
name : meson.project_name(),
filebase : meson.project_name(),
url : 'https://github.com/IceCubeOpenSource/nuflux',
description : 'A library for calculating atmospheric neutrino fluxes')

cppcomp = meson.get_compiler('cpp')
pymod = import('python')
python = pymod.find_installation(get_option('python'),required: false)

if not python.found()
warning('Can\'t find python: "'+get_option('python')+'", skipping python build')
else
pydep = python.dependency()

# Find numpy
numpy = run_command(python,'-c',
'import importlib.util,os;print(os.path.join(importlib.util.find_spec("numpy").submodule_search_locations[0],"core","include"))',
check: true,
)
if numpy.returncode()==0
pybind_inc = include_directories(numpy.stdout().strip())
message ('Numpy found: '+ numpy.stdout().strip())
else
warning ('Numpy not found: building without arrays')
pybind_inc = include_directories()
endif

python_name = 'python'+''.join(python.language_version().split('.'))
boost = dependency('boost' , modules : [python_name])

if not boost.found()
warning( 'Can\'t find boost python, Skipping python build')
else
message('Building package for python version ' +
python.language_version() + ': ' + python.get_install_dir())
python.install_sources('nuflux/__init__.py',
subdir: 'nuflux',
)

python.extension_module(
'_nuflux',
['src/pybindings/module.cxx'],
include_directories : [inc,pybind_inc],
dependencies : [photospline,pydep, boost],
link_with : libnuflux,
install:true)

pytest_env = environment(test_env)
pytest_env.append('PYTHONPATH',meson.current_source_dir())
pytest_env.append('PYTHONPATH',meson.current_build_dir())
test('test_fluxes',find_program('tests/test_fluxes.py'), env: pytest_env)
test('doctest',python,args: ['-m','doctest',files('README.md')],env: pytest_env)
meson.add_devenv(pytest_env)
endif

endif

subdir('docs')
7 changes: 4 additions & 3 deletions meson_options.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
option('python', type : 'string', value : 'python3', description : 'python path to compile against')
option('data_path', type: 'string', value : '', description: 'absolute path to where to install data files, will overrede --datadir Default will be PREFIX/share/nuflux')
option('install_data', type: 'boolean', value : true, description: 'can be set to false if installing on a readonly filesystem')
option('python', type : 'string', value: 'python3', description : 'python path to compile against')
option('data_path', type: 'string', value: '', description: 'absolute path to where to install the raw flux tables, will override --datadir Default will be PREFIX/share/nuflux')
option('install_data', type: 'boolean', value: true, description: 'can be set to false if installing on a readonly filesystem')
option('pymodule', type: 'boolean', value: false, description: 'install as a python module, no shared library, and with the data files as part of the python module' )
1 change: 0 additions & 1 deletion nuflux/data/SplineFlux/BERSS_H3a_central_nue.fits

This file was deleted.

1 change: 0 additions & 1 deletion nuflux/data/SplineFlux/BERSS_H3a_central_nuebar.fits

This file was deleted.

1 change: 0 additions & 1 deletion nuflux/data/SplineFlux/BERSS_H3a_central_numu.fits

This file was deleted.

1 change: 0 additions & 1 deletion nuflux/data/SplineFlux/BERSS_H3a_central_numubar.fits

This file was deleted.

1 change: 0 additions & 1 deletion nuflux/data/SplineFlux/BERSS_H3p_central_nue.fits

This file was deleted.

1 change: 0 additions & 1 deletion nuflux/data/SplineFlux/BERSS_H3p_central_nuebar.fits

This file was deleted.

1 change: 0 additions & 1 deletion nuflux/data/SplineFlux/BERSS_H3p_central_numu.fits

This file was deleted.

1 change: 0 additions & 1 deletion nuflux/data/SplineFlux/BERSS_H3p_central_numubar.fits

This file was deleted.

1 change: 0 additions & 1 deletion nuflux/data/SplineFlux/BERSS_H3p_lower_nue.fits

This file was deleted.

1 change: 0 additions & 1 deletion nuflux/data/SplineFlux/BERSS_H3p_lower_nuebar.fits

This file was deleted.

1 change: 0 additions & 1 deletion nuflux/data/SplineFlux/BERSS_H3p_lower_numu.fits

This file was deleted.

1 change: 0 additions & 1 deletion nuflux/data/SplineFlux/BERSS_H3p_lower_numubar.fits

This file was deleted.

1 change: 0 additions & 1 deletion nuflux/data/SplineFlux/BERSS_H3p_upper_nue.fits

This file was deleted.

1 change: 0 additions & 1 deletion nuflux/data/SplineFlux/BERSS_H3p_upper_nuebar.fits

This file was deleted.

1 change: 0 additions & 1 deletion nuflux/data/SplineFlux/BERSS_H3p_upper_numu.fits

This file was deleted.

1 change: 0 additions & 1 deletion nuflux/data/SplineFlux/BERSS_H3p_upper_numubar.fits

This file was deleted.

9 changes: 6 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
[build-system]
requires = ["setuptools", "oldest-supported-numpy"]
build-backend = "setuptools.build_meta"
build-backend = 'mesonpy'
requires = ['meson-python', 'oldest-supported-numpy']

[project]
name = "nuflux"
version = "2.0.4"
dynamic = ["version"]
description = "A library for calculating atmospheric neutrino fluxes"
readme = "README.md"
requires-python = "~=3.7"
Expand Down Expand Up @@ -37,6 +37,9 @@ doi = "https://doi.org/10.5281/zenodo.8180337"
[project.optional-dependencies]
test = ["pytest","pytest-subtests"]

[tool.meson-python.args]
setup = ['-Dpymodule=true']

[tool.pytest.ini_options]
addopts = "--doctest-glob='README.md'"
testpaths = ["tests", "README.md"]
34 changes: 0 additions & 34 deletions setup.py

This file was deleted.

2 changes: 1 addition & 1 deletion src/include/nuflux/SplineFlux.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ namespace nuflux{

class SimpleSplineFlux : public FluxFunction{
private:
std::map<ParticleType,boost::shared_ptr<photospline::splinetable<>> > components;
boost::shared_ptr<photospline::splinetable<>> spline;
public:
SimpleSplineFlux(const std::string& fluxName);
static boost::shared_ptr<FluxFunction> makeFlux(const std::string& fluxName);
Expand Down
3 changes: 3 additions & 0 deletions src/include/nuflux/nuflux.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ namespace nuflux{

///Print an listing of all supported models
void printModels();

///Return the current nuflux version
std::string getVersion();

} //namespace nuflux

Expand Down
Loading

0 comments on commit daad99d

Please sign in to comment.