This provides helpers for using Cython. Use:
find_package(Cython MODULE REQUIRED VERSION 3.0)
include(UseCython)
If you find Python beforehand, the search will take this into account. You can
specify a version range on CMake 3.19+. This will define a Cython::Cython
target (along with a matching CYTHON_EXECUTABLE
variable). It will also
provide the following helper function:
cython_transpile(<pyx_file>
[LANGUAGE C | CXX]
[CYTHON_ARGS <args> ...]
[OUTPUT <OutputFile>]
[OUTPUT_VARIABLE <OutputVariable>]
)
This function takes a pyx file and makes a matching .c
/ .cxx
file in the
current binary directory (exact path can be specified with OUTPUT
). The
location of the produced file is placed in the variable specified by
OUTPUT_VARIABLE
if given. Extra arguments to the Cython executable can be
given with CYTHON_ARGS
, and if this is not set, it will take a default from a
CYTHON_ARGS
variable.
If the LANGUAGE
is not given, and both C
and CXX
are enabled globally,
then the language will try to be deduced from a # distutils: language=...
comment in the source file, and C will be used if not found.
This utility relies on the DEPFILE
feature introduced for Ninja in CMake 3.7,
and added for Make in CMake 3.20, and Visual Studio & Xcode in CMake 3.21.
find_package(
Python
COMPONENTS Interpreter Development.Module
REQUIRED)
find_package(Cython MODULE REQUIRED)
cython_transpile(simple.pyx LANGUAGE C OUTPUT_VARIABLE simple_c)
python_add_library(simple MODULE "${simple_c}" WITH_SOABI)
To use this package with scikit-build-core, you need to include it in your build requirements:
[build-system]
requires = ["scikit-build-core", "cython", "cython-cmake"]
build-backend = "scikit_build_core.build"
It is also recommended to require CMake 3.21:
[tool.scikit-build]
cmake.version = ">=3.21"
You can vendor FindCython and/or UseCython into your package, as well. This avoids requiring a dependency at build time and protects you against changes in this package, at the expense of requiring manual re-vendoring to get bugfixes and/or improvements. This mechanism is also ideal if you want to support direct builds, outside of scikit-build-core.
You should make a CMake helper directory, such as cmake
. Add this to your
CMakeLists.txt
like this:
list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
Then, you can vendor our files into that folder:
pipx run cython-cmake vendor cmake
If you want to just vendor one of the two files, use --member FindCython
or
--member UseCython
. You can rerun this command to revendor. The directory must
already exist.