Skip to content

Commit

Permalink
Interface with libtopotoolbox through scikit-build-core and pybind11 (#…
Browse files Browse the repository at this point in the history
…12)

The current approach using `ctypes` requires separately building and
installing libtopotoolbox in an appropriate directory, which is tricky
to get right in a cross-platform way without substantial intervention
from users. This set of changes introduces a new build system using
scikit-build-core and pybind11 to build an extension module that
includes an interface to our library.

pyproject.toml is modified to switch the build backend to
scikit-build-core to install pybind11 as a build-time dependency.

src/lib.cpp contains the bindings for libtopotoolbox, defined using
pybind11. The PYBIND11_MODULE declaration exposes a Python module _lib
within the topotoolbox package that contains the bindings. Right now,
it only binds `has_topotoolbox`, which has a trivial binding because
it requires no marshalling of Python data into C/C++ types. Other
functions such as `fillsinks` will require more complex binding
declarations, but pybind11 provides an interface to working with NumPy
arrays that should be helpful.

CMakeLists.txt is used by scikit-build-core to build the package. It
follows the guidance at
https://scikit-build-core.readthedocs.io/en/latest/getting_started.html
with the exception of adding libtopotoolbox using
FetchContent. This will download the source from GitHub and then build
a /static/ library for libtopotoolbox and link it into the /shared/
library that is built by pybind11.

src/topotoolbox/__init__.py shows how to access the binding from the
_lib module. In practice, we probably don't want to expose the raw
bindings from the topotoolbox module but instead use them to implement
methods within the proposed `GridObject` class.
  • Loading branch information
wkearn authored Apr 18, 2024
1 parent bfb46c1 commit a5f394f
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 3 deletions.
23 changes: 23 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
cmake_minimum_required(VERSION 3.15)

project(${SKBUILD_PROJECT_NAME}
VERSION ${SKBUILD_PROJECT_VERSION}
LANGUAGES CXX)

# Find TopoToolbox somewhere
include(FetchContent)
FetchContent_Declare(
topotoolbox
GIT_REPOSITORY https://github.com/TopoToolbox/libtopotoolbox.git
GIT_TAG main # In the future, we should track a specific tag/commit
# and bump it as we release versions
)
FetchContent_MakeAvailable(topotoolbox)

set(PYBIND11_NEWPYTHON ON)
find_package(pybind11 CONFIG REQUIRED)

pybind11_add_module(_lib src/lib.cpp)
target_link_libraries(_lib PRIVATE topotoolbox)

install(TARGETS _lib LIBRARY DESTINATION topotoolbox)
4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
requires = ["scikit-build-core","pybind11"]
build-backend = "scikit_build_core.build"

[project]
name = "topotoolbox"
Expand Down
11 changes: 11 additions & 0 deletions src/lib.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
extern "C" {
#include <topotoolbox.h>
}

#include <pybind11/pybind11.h>

namespace py = pybind11;

PYBIND11_MODULE(_lib, m) {
m.def("has_topotoolbox",&has_topotoolbox);
}
3 changes: 2 additions & 1 deletion src/topotoolbox/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
from .grid_object import GridObject
from .grid_object import GridObject
from ._lib import has_topotoolbox

0 comments on commit a5f394f

Please sign in to comment.