Skip to content

Commit

Permalink
Update installation setup to a PEP517 build backend (grimme-lab#95)
Browse files Browse the repository at this point in the history
  • Loading branch information
awvwgk committed Dec 31, 2022
1 parent 3335421 commit 48eabe1
Show file tree
Hide file tree
Showing 15 changed files with 184 additions and 255 deletions.
72 changes: 46 additions & 26 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,44 +3,64 @@ name: CI
on: [push, pull_request]

jobs:
sdist:
runs-on: ubuntu-latest
defaults:
run:
shell: bash -l {0}
steps:
- uses: actions/checkout@v3
- name: Setup Python
uses: mamba-org/provision-with-micromamba@main
with:
environment-file: environment.yml
extra-specs: |
meson-python
python-build
- run: |
python -m build . --sdist --outdir . -n ${{ env.SETUP_ARGS }}
env:
SETUP_ARGS: >-
-Csetup-args=-Dxtb-6.5.1:la_backend=netlib
-Csetup-args=-Dmctc-lib:json=disabled
- uses: actions/upload-artifact@v3
with:
name: xtb-python-sdist
path: ./*.tar.gz
retention-days: 5

build:
runs-on: ${{ matrix.os }}
runs-on: ubuntu-latest
defaults:
run:
shell: bash -l {0}
strategy:
fail-fast: false
matrix:
os: [macos-latest, ubuntu-latest]
python: ['3.7', '3.8', '3.9', '3.10', '3.11']

steps:
- uses: actions/checkout@v2
with:
submodules: true
- uses: actions/checkout@v3

- name: Python 3.8
uses: actions/setup-python@v2
- name: Setup Python
uses: mamba-org/provision-with-micromamba@main
with:
python-version: 3.8

- name: Install dependencies
run: |
pip3 install -U meson==0.55.3 ninja pytest pytest-cov codecov
pip3 install -r requirements.txt
environment-file: environment.yml
extra-specs: |
c-compiler
fortran-compiler
meson-python
python=${{ matrix.python }}
pytest
- name: Setup build of extension module
run: |
pip3 install . ${{ env.SETUP_ARGS }}
env:
FC: gfortran-9
CC: gcc-9
run: meson setup build --prefix=$PWD -Dla_backend=netlib

- name: Compile extension module
run: ninja -C build install

- name: Install Python package
run: pip3 install -e .
SETUP_ARGS: >-
--config-settings setup-args=-Dxtb-6.5.1:la_backend=netlib
- name: Test Python package
run: pytest -v --cov=xtb --pyargs xtb
run: pytest -v --pyargs xtb
env:
OMP_NUM_THREADS: 2,1

- name: Upload coverage report to codecov
run: codecov
3 changes: 0 additions & 3 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,3 +0,0 @@
[submodule "subprojects/xtb"]
path = subprojects/xtb
url = https://github.com/grimme-lab/xtb.git
40 changes: 9 additions & 31 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -62,43 +62,21 @@ It is possible to list all of the versions of ``xtb-python`` available on your p
Build from Source
~~~~~~~~~~~~~~~~~

When building this project from source, make sure to initialize the git submodules
with

.. code::
git submodule update --init
The project is built with meson; the exact dependencies are defined by the ``xtb``
project. In summary it requires a Fortran and a C compiler as well as a
The project is build with meson, the exact dependencies are defined by the ``xtb``
project, in summary it requires a Fortran and a C compiler as well as a
linear algebra backend. Make yourself familiar with building ``xtb`` first!

This project requires a development version of Python installed.
Also, ensure that you have the ``numpy`` and ``cffi`` packages installed,
configure the build of the extension with:

.. code::
meson setup build --prefix=$PWD
ninja -C build install -v
By default, the build will use ``'python3'``.
If you have several versions of Python installed, you can point meson
to the correct one using the ``-Dpy=<version>`` option.
This will create the CFFI extension ``_libxtb`` and place it in the ``xtb``
directory.
Additionally this project requires a development version of Python installed.
Also ensure that you have the ``numpy`` and ``cffi`` packages installed,
configure the build of the extension with.

In case meson fails to configure or build, check the options for ``-Dla_backend``
and ``-Dopenmp`` which are passed to the ``xtb`` subproject.
For more information on the build with meson, follow the guide in the ``xtb``
repository `here <https://github.com/grimme-lab/xtb/blob/HEAD/meson/README.adoc>`_.

After creating the ``_libxtb`` extension, the Python module can be installed
as usual with
All steps to build the project are automated using

.. code::
pip install -e .
pip install .
To pass options to the meson build of xtb use ``--config-setting setup-args="-Dxtb-6.5.1:la_backend=openblas"`` to set for example the linear algebra backend to OpenBLAS.


Contributing
Expand Down
86 changes: 1 addition & 85 deletions docs/installation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,6 @@ To install ``xtb-python`` from source clone the repository from GitHub with
git clone https://github.com/grimme-lab/xtb-python
cd xtb-python
git submodule update --init
This will ensure that you have access to the ``xtb-python`` and the parent ``xtb`` repository, with the latter to be found in ``subprojects/xtb``.
Building the Extension Module
Expand Down Expand Up @@ -104,11 +101,9 @@ Now, setup the project by building the CFFI extension module from the ``xtb`` AP

.. code-block:: none
meson setup build --prefix=$PWD --default-library=shared
meson setup build --prefix=$HOME/.local
ninja -C build install
This step will create the CFFI extension ``_libxtb`` and place it in the ``xtb`` directory.

Meson cannot find xtb dependency
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Expand Down Expand Up @@ -137,44 +132,6 @@ For the official release tarball you possible have to edit the first line of ``x
Installs from conda-forge should work out-of-box.


Dealing with Several Versions of Python
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

If you have several versions of Python installed you can point meson with the ``-Dpy=<version>`` option to the correct one.
Depending on your setup you have to export your compilers (``CC`` and ``FC``) first and set the ``-Dla_backend=<name>`` and ``-Dopenmp=<bool>`` option accordingly.


.. _devel-install:

Installing in Development Mode
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

After creating the ``_libxtb`` extension, the Python module can be installed as usual with

.. code-block:: none
pip install -e .
Now you are set to start using ``xtb-python``.
You can test your setup by opening a new Python interpreter and try to import the interface module

.. code::
>>> import xtb.interface
If you also want to use extensions install with

.. code-block:: none
pip install -e '.[ase,qcschema]'
Now you can test your installation with

.. code-block:: none
pytest --pyargs xtb
Helpful Tools
^^^^^^^^^^^^^

Expand All @@ -183,44 +140,3 @@ We aim for a high quality code base and encourage substainable development model
Please, install a linter like ``flake8`` or ``pylint`` to catch errors before they become bugs.
Also, typehints are mandatory in this project, you should typecheck locally with ``mypy``.
A consistent coding style is enforced by using ``black``, every source file should be reformatted using ``black``, the only exceptions are tests.


Building without Upstream Dependency
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

For convenience we also offer a mode to work without an upstream ``xtb`` dependency, this can be quite handy if you also want to work on the ``xtb`` API itself or want to create a failsafe package that cannot break due to ABI or API incompatibilities.

.. note::

It is highly recommend to make yourself familiar with building ``xtb`` first.

For this approach we follow the same scheme as with the normal extension build.
You will need the following packages installed

.. code-block:: none
cffi
numpy
meson # build only
Additionally you will need a development version of Python, for the Python headers, a Fortran and a C compiler (GCC 7 or newer or Intel 17 or newer) and a linear algebra backend (providing LAPACK and BLAS API).

We closely follow the approach from before, but we change the configuration of the extension build to

.. code-block:: none
meson setup build --prefix=$PWD --default-library=static
ninja -C build install
Depending on how you acquired the project mesons wrap-tool will first need to download the ``xtb`` source code.
Instead of dynamically depending on ``xtb`` the complete project will be build and included as a whole into the CFFI extension module, making your ``xtb-python`` effectively independent of ``xtb``.

You can pass the ``-Dopenmp=<bool>`` and ``-Dla_backend=<netlib|openblas|mkl>`` in the configuration step to configure the ``xtb`` build.
To change the compiler used export them in the environment variables ``CC`` and ``FC``.

.. tip::

For more information on the build with meson, follow the guide in the ``xtb`` repository `here <https://github.com/grimme-lab/xtb/blob/master/meson/README.adoc>`_.

From here you can proceed with :ref:`devel-install`.
8 changes: 8 additions & 0 deletions environment.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
name: devel
channels:
- conda-forge
dependencies:
- ase
- cffi
- numpy
- qcelemental
96 changes: 66 additions & 30 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -20,42 +20,29 @@ project(
'c',
license: 'LGPL-3.0-or-later',
default_options: [
'libdir=xtb',
'default_library=static',
'optimization=2',
'buildtype=debugoptimized',
]
)
install = true

cc = meson.get_compiler('c')
xtb_dep = dependency(
'xtb',
version: '>=@0@'.format(meson.project_version()),
fallback: ['xtb-6.5.1', 'xtb_dep'],
default_options: [
'default_library=static',
'c_api=true',
],
)
# TODO: replace with include/_xtb.h containing only ``#include "xtb.h"``
xtb_header = files('include' / 'xtb.h')

# In case you actually want to depend on the xtb shared library
if get_option('default_library') == 'shared'
xtb_dep = declare_dependency(
include_directories: include_directories('include'),
dependencies: dependency('xtb', version: '>=6.3', required: true),
)
xtb_header = files('include/xtb.h')
else
# Import xtb as subproject, we need the API of version 6.3 or newer,
# in this mode we want to dependency free regarding xtb, therefore,
# we force xtb to provide a _static_ library to avoid depending on xtb at runtime
xtb_prj = subproject(
'xtb',
version: '>=6.3',
default_options: [
'default_library=static',
'openmp=@0@'.format(get_option('openmp')),
'la_backend=@0@'.format(get_option('la_backend')),
'optimization=@0@'.format(get_option('optimization')),
],
)
xtb_dep = xtb_prj.get_variable('xtb_dep')
xtb_header = xtb_prj.get_variable('xtb_header')
endif
cc = meson.get_compiler('c')

pymod = import('python')
python = pymod.find_installation(
get_option('py'),
get_option('python_version'),
modules: [
'cffi',
],
Expand All @@ -65,7 +52,21 @@ python_dep = python.dependency(required: true)
# Python's CFFI is horrible in working with preprocessor statements,
# therefore, we have to preprocess the header before passing it to the ffibuilder
xtb_pp = configure_file(
command: [cc, '-E', '@INPUT@'],
command: [
cc,
'-I@0@'.format(
meson.current_source_dir() / 'include',
# TODO: support in upstream xtb
# xtb_dep.get_variable(
# pkgconfig: 'includedir',
# cmake: 'tblite_INCLUDE_DIRS',
# internal: 'includedir',
# ).split().get(0)
),
'-DXTB_CFFI',
'-E',
'@INPUT@',
],
input: xtb_header,
output: '_libxtb.h',
capture: true,
Expand All @@ -88,5 +89,40 @@ xtb_pyext = python.extension_module(
dependencies: [xtb_dep, python_dep],
),
dependencies: [xtb_dep, python_dep],
install: true,
install: install,
subdir: 'xtb',
)

if install
python.install_sources(
files(
'xtb' / '__init__.py',
'xtb' / 'interface.py',
'xtb' / 'libxtb.py',
'xtb' / 'utils.py',
'xtb' / 'test_interface.py',
'xtb' / 'test_libxtb.py',
'xtb' / 'test_utils.py',
),
subdir: 'xtb',
)

python.install_sources(
files(
'xtb' / 'ase' / '__init__.py',
'xtb' / 'ase' / 'calculator.py',
'xtb' / 'ase' / 'test_calculator.py',
'xtb' / 'ase' / 'test_optimize.py',
),
subdir: 'xtb' / 'ase',
)

python.install_sources(
files(
'xtb' / 'qcschema' / '__init__.py',
'xtb' / 'qcschema' / 'harness.py',
'xtb' / 'qcschema' / 'test_qcschema.py',
),
subdir: 'xtb' / 'qcschema',
)
endif
Loading

0 comments on commit 48eabe1

Please sign in to comment.