Welcome to scikit-build¶
scikit-build is a Python build system for CPython C/C++/Fortran/Cython extensions using CMake.
The scikit-build package is fundamentally just glue between the setuptools
Python module and CMake.
The next generation of scikit-build, scikit-build-core, is currently under development. This provides a simple, reliable build backend for CMake that does not use setuptools and provides a lot of new features. Scikit-build-core can also power a setuptools-based extension system, which will eventually become the backend for scikit-build (classic). If you do not require extensive customization of the build process, you should consider trying scikit-build-core instead of scikit-build.
To get started, see this example. For more examples, see scikit-build-sample-projects.
Installation¶
Install package with pip¶
To install with pip:
$ pip install scikit-build
Install from source¶
To install scikit-build from the latest source, first obtain the source code:
$ git clone https://github.com/scikit-build/scikit-build
$ cd scikit-build
then install with:
$ pip install .
or:
$ pip install -e .
for development.
Dependencies¶
Python Packages¶
The project has a few common Python package dependencies. These can be seen in
setup.py
and pyproject.toml
.
Compiler Toolchain¶
The same compiler toolchain used to build the CPython interpreter should also be available. Refer to the CPython Developer’s Guide for details about the compiler toolchain for your operating system.
For example, on Ubuntu Linux, install with:
$ sudo apt-get install build-essential
On Mac OSX, install XCode to build packages for the system Python.
On Windows, install the version of Visual Studio used to create the target version of CPython
CMake¶
The easiest way to get CMake is to add it to the pyproject.toml file. With pip 10 or later, this will cause the CMake Python package to be downloaded and installed when your project is built.
To manually install the cmake package from PyPI:
$ pip install cmake
To install the cmake package in conda:
$ conda install -c conda-forge cmake
You can also download the standard CMake binaries for your platform.
Alternatively, build CMake from source with a C++ compiler if binaries are not available for your operating system.
Why should I use scikit-build ?¶
Scikit-build is a replacement for distutils.core.Extension with the following advantages:
provide better support for additional compilers and build systems
first-class cross-compilation support
location of dependencies and their associated build requirements
Basic Usage¶
Example of setup.py, CMakeLists.txt and pyproject.toml¶
The full example code is Here
Make a fold name my_project as your project root folder, place the following in your project’s
setup.py
file:
from skbuild import setup # This line replaces 'from setuptools import setup'
setup(
name="hello-cpp",
version="1.2.3",
description="a minimal example package (cpp version)",
author='The scikit-build team',
license="MIT",
packages=['hello'],
python_requires=">=3.7",
)
Your project now uses scikit-build instead of setuptools.
Next, add a CMakeLists.txt
to describe how to build your extension. In the following example,
a C++ extension named _hello
is built:
cmake_minimum_required(VERSION 3.18...3.22)
project(hello)
find_package(PythonExtensions REQUIRED)
add_library(_hello MODULE hello/_hello.cxx)
python_extension_module(_hello)
install(TARGETS _hello LIBRARY DESTINATION hello)
Then, add a pyproject.toml
to list the build system requirements:
[build-system]
requires = [
"setuptools>=42",
"scikit-build>=0.13",
"cmake>=3.18",
"ninja",
]
build-backend = "setuptools.build_meta"
Make a hello folder inside my_project folder and place _hello.cxx and __init__.py inside hello folder.
Now every thing is ready, go to my_project’s parent folder and type following command to install your extension:
pip install my_project/.
If you want to see the detail of installation:
pip install my_project/. -v
Try your new extension:
$ python
Python 3.10.4 (main, Jun 29 2022, 12:14:53) [GCC 11.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import hello
>>> hello.hello("scikit-build")
Hello, scikit-build!
>>>
You can add lower limits to cmake
or scikit-build
as needed. Ninja
should be limited to non-Windows systems, as MSVC 2017+ ships with Ninja
already, and there are fall-backs if Ninja is missing, and the Python Ninja
seems to be less likely to find MSVC than the built-in one currently.
Note
By default, scikit-build looks in the project top-level directory for a
file named CMakeLists.txt
. It will then invoke cmake
executable
specifying a generator matching the python being used.
Setup options¶
setuptools options¶
The section below documents some of the options accepted by the setup()
function. These currently must be passed in your setup.py
, not in
setup.cfg
, as scikit-build intercepts them and inspects them. This
restriction may be relaxed in the future. Setuptools options not listed here can
be placed in setup.cfg
as normal.
packages
: Explicitly list of all packages to include in the distribution. Setuptools will not recursively scan the source tree looking for any directory with an__init__.py
file. To automatically generate the list of packages, see Using find_package().package_dir
: A mapping of package to directory namesinclude_package_data
: If set toTrue
, this tells setuptools to automatically include any data files it finds inside your package directories that are specified by yourMANIFEST.in
file. For more information, see the setuptools documentation section on Including Data Files. scikit-build matches the setuptools behavior of defaulting this parameter toTrue
if a pyproject.toml file exists and contains either theproject
ortool.setuptools
table.package_data
: A dictionary mapping package names to lists of glob patterns. For a complete description and examples, see the setuptools documentation section on Including Data Files. You do not need to use this option if you are using include_package_data, unless you need to add e.g. files that are generated by your setup script and build process. (And are therefore not in source control or are files that you don’t want to include in your source distribution.)exclude_package_data
: Dictionary mapping package names to lists of glob patterns that should be excluded from the package directories. You can use this to trim back any excess files included by include_package_data. For a complete description and examples, see the setuptools documentation section on Including Data Files.py_modules
: List all modules rather than listing packages. More details in the Listing individual modules section of the distutils documentation.data_files
: Sequence of(directory, files)
pairs. Each(directory, files)
pair in the sequence specifies the installation directory and the files to install there. More details in the Installing Additional Files section of the setuptools documentation.entry_points
: A dictionary mapping entry point group names to strings or lists of strings defining the entry points. Entry points are used to support dynamic discovery of services or plugins provided by a project. See Dynamic Discovery of Services and Plugins for details and examples of the format of this argument. In addition, this keyword is used to support Automatic Script Creation. Note that if usingpyproject.toml
for configuration, the requirement to putentry_points
insetup.py
also requires that theproject
section includeentry_points
in thedynamic
section.scripts
: List of python script relative paths. If the first line of the script starts with#!
and contains the wordpython
, the Distutils will adjust the first line to refer to the current interpreter location. More details in the Installing Scripts section of the distutils documentation.
New in version 0.8.0.
zip_safe
: A boolean indicating if the Python packages may be run directly from a zip file. If not already set, scikit-build sets this option toFalse
. See Setting the zip_safe flag section of the setuptools documentation.
Note
As specified in the Wheel documentation, the universal
and python-tag
options
have no effect.
scikit-build options¶
Scikit-build augments the setup()
function with the following options:
cmake_args
: List of CMake options.
For example:
setup(
[...]
cmake_args=['-DSOME_FEATURE:BOOL=OFF']
[...]
)
cmake_install_dir
: relative directory where the CMake artifacts are installed. By default, it is set to an empty string.cmake_source_dir
: Relative directory containing the projectCMakeLists.txt
. By default, it is set to the top-level directory wheresetup.py
is found.cmake_process_manifest_hook
: Python function consuming the list of files to be installed produced by cmake. For example,cmake_process_manifest_hook
can be used to exclude static libraries from the built wheel.
For example:
def exclude_static_libraries(cmake_manifest):
return list(filter(lambda name: not (name.endswith('.a')), cmake_manifest))
setup(
[...]
cmake_process_manifest_hook=exclude_static_libraries
[...]
)
New in version 0.5.0.
cmake_with_sdist
: Boolean indicating if CMake should be executed when runningsdist
command. Setting this option toTrue
is useful when part of the sources specified inMANIFEST.in
are downloaded by CMake. By default, this option isFalse
.
New in version 0.7.0.
cmake_languages
: Tuple of languages that the project use, by default('C', 'CXX',)
. This option ensures that a generator is chosen that supports all languages for the project.cmake_minimum_required_version
: String identifying the minimum version of CMake required to configure the project.cmake_install_target
: Name of the target to “build” for installing the artifacts into the wheel. By default, this option is set toinstall
, which is always provided by CMake. This can be used to only install certain components.
For example:
install(TARGETS foo COMPONENT runtime)
add_custom_target(foo-install-runtime
${CMAKE_COMMAND}
-DCMAKE_INSTALL_COMPONENT=runtime
-P "${PROJECT_BINARY_DIR}/cmake_install.cmake"
DEPENDS foo
)
Scikit-build changes the following options:
New in version 0.7.0.
setup_requires
: Ifcmake
is found in the list, it is explicitly installed first by scikit-build.
Command line options¶
Warning: Passing options to setup.py
is deprecated and may be removed in a
future release. Environment variables can be used instead for most options.
usage: setup.py [global_opts] cmd1 [cmd1_opts] [cmd2 [cmd2_opts] ...] [skbuild_opts] [cmake_configure_opts] [-- [cmake_opts] [-- [build_tool_opts]]]
or: setup.py --help [cmd1 cmd2 ...]
or: setup.py --help-commands
or: setup.py cmd --help
There are few types of options:
-
[global_opts] cmd1 [cmd1_opts] [cmd2 [cmd2_opts] ...]
--help [cmd1 cmd2 ...]
cmd --help
scikit-build options:
[skbuild_opts]
CMake configure options:
[cmake_configure_opts]
CMake options:
[cmake_opts]
build tool options:
[build_tool_opts]
setuptools, scikit-build and CMake configure options can be passed normally, the cmake and
build_tool set of options needs to be separated by --
:
Arguments following a "--" are passed directly to CMake (e.g. -DSOME_FEATURE:BOOL=ON).
Arguments following a second "--" are passed directly to the build tool.
setuptools options¶
For more details, see the official documentation.
scikit-build extends the global set of setuptools options with:
New in version 0.4.0.
Global options:
[...]
--hide-listing do not display list of files being included in the
distribution
New in version 0.5.0.
Global options:
[...]
--force-cmake always run CMake
--skip-cmake do not run CMake
Note
As specified in the Wheel documentation, the --universal
and --python-tag
options
have no effect.
scikit-build options¶
scikit-build options:
--build-type specify the CMake build type (e.g. Debug or Release)
-G , --generator specify the CMake build system generator
-j N allow N build jobs at once
[...]
New in version 0.7.0.
scikit-build options:
[...]
--cmake-executable specify the path to the cmake executable
New in version 0.8.0.
scikit-build options:
[...]
--skip-generator-test skip generator test when a generator is explicitly selected using --generator
CMake Configure options¶
New in version 0.10.1.
These options are relevant when configuring a project and can be passed as global options using setup.py
or pip install
.
The CMake options accepted as global options are any of the following:
-C<initial-cache> = Pre-load a script to populate the cache.
-D<var>[:<type>]=<value> = Create or update a cmake cache entry.
Warning
The CMake configure option should be passed without spaces. For example, use -DSOME_FEATURE:BOOL=ON instead of -D SOME_FEATURE:BOOL=ON.
CMake options¶
These are any specific to CMake. See list of CMake options.
For example:
-DSOME_FEATURE:BOOL=OFF
build tool options¶
These are specific to the underlying build tool (e.g msbuild.exe, make, ninja).
Advanced Usage¶
How to test if scikit-build is driving the compilation ?¶
To support the case of code base being built as both a standalone project
and a python wheel, it is possible to test for the variable SKBUILD
:
if(SKBUILD)
message(STATUS "The project is built using scikit-build")
endif()
Adding cmake as building requirement only if not installed or too low a version¶
If systematically installing cmake wheel is not desired, it is possible to set it using an in-tree backend
.
For this purpose place the following configuration in your pyproject.toml
:
[build-system]
requires = [
"setuptools>=42",
"packaging",
"scikit-build",
"ninja; platform_system!='Windows'"
]
build-backend = "backend"
backend-path = ["_custom_build"]
then you can implement a thin wrapper around build_meta
in the _custom_build/backend.py
file:
from setuptools import build_meta as _orig
prepare_metadata_for_build_wheel = _orig.prepare_metadata_for_build_wheel
build_wheel = _orig.build_wheel
build_sdist = _orig.build_sdist
get_requires_for_build_sdist = _orig.get_requires_for_build_sdist
def get_requires_for_build_wheel(config_settings=None):
from packaging import version
from skbuild.exceptions import SKBuildError
from skbuild.cmaker import get_cmake_version
packages = []
try:
if version.parse(get_cmake_version()) < version.parse("3.4"):
packages.append('cmake')
except SKBuildError:
packages.append('cmake')
return _orig.get_requires_for_build_wheel(config_settings) + packages
Also see scikit-build-core where this is a built-in feature.
Enabling parallel build¶
Ninja¶
If Ninja generator is used, the associated build tool (called ninja
)
will automatically parallelize the build based on the number of available CPUs.
To limit the number of parallel jobs, the build tool option -j N
can be passed
to ninja
.
For example, to limit the number of parallel jobs to 3
, the following could be done:
python setup.py bdist_wheel -- -- -j3
For complex projects where more granularity is required, it is also possible to limit the number of simultaneous link jobs, or compile jobs, or both.
Indeed, starting with CMake 3.11, it is possible to configure the project with these options:
For example, to have at most 5
compile jobs and 2
link jobs, the following could be done:
python setup.py bdist_wheel -- \
-DCMAKE_JOB_POOL_COMPILE:STRING=compile \
-DCMAKE_JOB_POOL_LINK:STRING=link \
'-DCMAKE_JOB_POOLS:STRING=compile=5;link=2'
Unix Makefiles¶
If Unix Makefiles generator is used, the associated build tool (called make
)
will NOT automatically parallelize the build, the user has to explicitly pass
option like -j N
.
For example, to limit the number of parallel jobs to 3
, the following could be done:
python setup.py bdist_wheel -- -- -j3
Visual Studio IDE¶
If Visual Studio IDE generator is used, there are two types of parallelism:
target level parallelism
object level parallelism
Warning
Since finding the right combination of parallelism can be challenging, whenever possible we recommend to use the Ninja generator.
To adjust the object level parallelism, the compiler flag /MP[processMax]
could
be specified. To learn more, read /MP (Build with Multiple Processes).
For example:
set CXXFLAGS=/MP4
python setup.py bdist_wheel
The target level parallelism can be set from command line
using /maxcpucount:N
. This defines the number of simultaneous MSBuild.exe
processes.
To learn more, read Building Multiple Projects in Parallel with MSBuild.
For example:
python setup.py bdist_wheel -- -- /maxcpucount:4
Support for isolated build¶
New in version 0.8.0.
As specified in PEP 518, dependencies required at install time can be specified using a
pyproject.toml
file. Starting with pip 10.0, pip reads the pyproject.toml
file and
installs the associated dependencies in an isolated environment. See the pip build system interface
documentation.
An isolated environment will be created when using pip to install packages directly from source or to create an editable installation.
scikit-build supports these use cases as well as the case where the isolated environment support
is explicitly disabled using the pip option --no-build-isolation
available with the install
,
download
and wheel
commands.
Optimized incremental build¶
To optimize the developer workflow, scikit-build reconfigures the CMake project only when needed. It caches the environment associated with the generator as well as the CMake execution properties.
The CMake properties are saved in a CMake spec file
responsible
to store the CMake executable path, the CMake configuration arguments, the CMake version as well as the
environment variables PYTHONNOUSERSITE
and PYTHONPATH
.
If there are no CMakeCache.txt
file or if any of the CMake properties changes, scikit-build will
explicitly reconfigure the project calling skbuild.cmaker.CMaker.configure()
.
If a file is added to the CMake build system by updating one of the CMakeLists.txt
file, scikit-build
will not explicitly reconfigure the project. Instead, the generated build-system will automatically
detect the change and reconfigure the project after skbuild.cmaker.CMaker.make()
is called.
Environment variable configuration¶
Scikit-build support environment variables to configure some options. These are:
SKBUILD_CONFIGURE_OPTIONS
/CMAKE_ARGS
This will add configuration options when configuring CMake.
SKBUILD_CONFIGURE_OPTIONS
will be used instead ofCMAKE_ARGS
if both are defined.SKBUILD_BUILD_OPTIONS
Pass options to the build.
Cross-compilation¶
See CMake Toolchains.
Introduction to dockross¶
Note
To be documented. See #227.
Using dockcross-manylinux to generate Linux wheels¶
Note
To be documented. See #227.
Using dockcross-mingwpy to generate Windows wheels¶
Note
To be documented. See #227.
Examples for scikit-build developers¶
Note
To be documented. See #227.
Provide small, self-contained setup function calls for (at least) two use cases:
when a CMakeLists.txt file already exists
when a user wants scikit-build to create a CMakeLists.txt file based on the user specifying some input files.
C Runtime, Compiler and Build System Generator¶
scikit-build uses sensible defaults allowing to select the C runtime matching the official CPython recommendations. It also ensures developers remain productive by selecting an alternative environment if recommended one is not available.
The table below lists the different C runtime implementations, compilers and their usual distribution mechanisms for each operating systems.
Linux |
MacOSX |
Windows |
|
---|---|---|---|
C runtime |
|||
Compiler |
Microsoft C/C++ Compiler (cl.exe) |
||
Provenance |
OSX SDK within XCode |
Build system generator¶
Since scikit-build simply provides glue between setuptools
and CMake
, it needs to choose a CMake generator to configure the build
system allowing to build of CPython C extensions.
The table below lists the generator supported by scikit-build:
Operating System |
Linux |
MacOSX |
Windows |
---|---|---|---|
CMake Generator |
When building a project, scikit-build iteratively tries each generator (in the order listed in the table) until it finds a working one.
For more details about CMake generators, see CMake documentation.
Ninja¶
Supported platform(s): Linux, MacOSX and Windows
If ninja executable is in the
PATH
, the associated generator is used to setup the project build system based onninja
files.In a given python environment, installing the ninja python package with
pip install ninja
will ensure that ninja is in thePATH
.
Note
Automatic parallelism
An advantage of ninja is that it automatically parallelizes the build based on the number of CPUs. See Enabling parallel build.
Note
Ninja on Windows
When Ninja generator is used on Windows, scikit-build will make sure the
project is configured and built with the appropriate [3]
environment (equivalent of calling vcvarsall.bat x86
or vcvarsall.bat amd64
).
When Visual Studio >= 2017 is used, ninja is available by default thanks to the Microsoft CMake extension:
C:/Program Files (x86)/Microsoft Visual Studio/2017/Professional/Common7/IDE/CommonExtensions/Microsoft/CMake/Ninja/ninja.exe
Unix Makefiles¶
Supported platform(s): Linux, MacOSX
scikit-build uses this generator to generate a traditional
Makefile
based build system.
Visual Studio IDE¶
Supported platform(s): Windows
scikit-build uses the generator corresponding to selected version of Visual Studio and generate a
solution file
based build system.
Architecture |
||
---|---|---|
CPython Version |
x86 (32-bit) |
x64 (64-bit) |
3.7 and above |
Visual Studio 17 2022 Visual Studio 16 2019 Visual Studio 15 2017 |
Visual Studio 17 2022 Win64 Visual Studio 16 2019 Win64 Visual Studio 15 2017 Win64 |
Note
The Visual Studio generators can not be used when only alternative environments are installed, in that case Ninja or NMake Makefiles are used.
NMake Makefiles¶
Supported platform(s): Windows
scikit-build will make sure the project is configured and built with the appropriate [3] environment (equivalent of calling
vcvarsall.bat x86
orvcvarsall.bat amd64
).
Note
NMake Makefiles JOM
The NMake Makefiles JOM generator is supported but it is not automatically
used by scikit-build (even if jom executable is in the PATH
),
it always needs to be explicitly specified. For example:
python setup.py build -G "NMake Makefiles JOM"
For more details, see scikit-build options.
Linux¶
scikit-build uses the toolchain set using CC
(and CXX
) environment variables. If
no environment variable is set, it defaults to gcc
.
To build compliant Linux wheels, scikit-build also supports the manylinux
platform described in PEP-0513. We
recommend the use of dockcross/manylinux-x64 and
dockcross/manylinux-x86. These images are
optimized for building Linux wheels using scikit-build.
MacOSX¶
scikit-build uses the toolchain set using CC
(and CXX
) environment variables. If
no environment variable is set, it defaults to the Apple compiler installed with XCode.
Default Deployment Target and Architecture¶
New in version 0.7.0.
The default deployment target and architecture selected by scikit-build are
hard-coded for MacOSX and are respectively 10.9
and x86_64
.
This means that the platform name associated with the bdist_wheel
command is:
macosx-10.9-x86_64
and is equivalent to building the wheel using:
python setup.py bdist_wheel --plat-name macosx-10.9-x86_64
Respectively, the values associated with the corresponding CMAKE_OSX_DEPLOYMENT_TARGET and CMAKE_OSX_ARCHITECTURES CMake options that are automatically used to configure the project are the following:
CMAKE_OSX_DEPLOYMENT_TARGET:STRING=10.9
CMAKE_OSX_ARCHITECTURES:STRING=x86_64
As illustrated in the table below, choosing 10.9
as deployment target to build
MacOSX wheels will allow them to work on System CPython
, the Official CPython
,
Macports
and also Homebrew
installations of CPython.
CPython Distribution |
CPython Version |
OSX Version |
|
---|---|---|---|
Official CPython |
3.9, 3.10 |
10.9 |
macosx-10.9-universal2 |
3.8 |
11 |
macosx-11.0-universal2 |
|
3.7, 3.8, 3.9, 3.10 |
10.9 |
macosx-10.9-x86_64 |
|
Macports CPython |
3.x |
Current |
Depends on current macOS version. |
Homebrew CPython |
3.x |
Current |
The information above have been adapted from the excellent Spinning wheels article written by Matthew Brett.
Default SDK and customization¶
New in version 0.7.0.
By default, scikit-build lets CMake discover the most recent SDK available on the system during the configuration of the project. CMake internally uses the logic implemented in the Platform/Darwin-Initialize.cmake CMake module.
Customizing SDK¶
New in version 0.7.0.
If needed, this can be overridden by explicitly passing the CMake option CMAKE_OSX_SYSROOT. For example:
python setup.py bdist_wheel -- -DCMAKE_OSX_SYSROOT:PATH=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk
Customizing Deployment Target and Architecture¶
New in version 0.11.0.
Deployment target can be customized by setting the MACOSX_DEPLOYMENT_TARGET
environment variable.
New in version 0.7.0.
Deployment target and architecture can be customized by associating the
--plat-name macosx-<deployment_target>-<arch>
option with the bdist_wheel
command.
For example:
python setup.py bdist_wheel --plat-name macosx-10.9-x86_64
scikit-build also sets the value of CMAKE_OSX_DEPLOYMENT_TARGET and CMAKE_OSX_ARCHITECTURES option based on the provided platform name. Based on the example above, the options used to configure the associated CMake project are:
-DCMAKE_OSX_DEPLOYMENT_TARGET:STRING=10.9
-DCMAKE_OSX_ARCHITECTURES:STRING=x86_64
libstdc++ vs libc++¶
Before OSX 10.9, the default was libstdc++
.
With OSX 10.9 and above, the default is libc++
.
Forcing the use of libstdc++
on newer version of OSX is still possible using the
flag -stdlib=libstdc++
. That said, doing so will report the following warning:
clang: warning: libstdc++ is deprecated; move to libc++
Windows¶
Microsoft C run-time and Visual Studio version¶
On windows, scikit-build looks for the version of Visual Studio matching the version of CPython being used. The selected Visual Studio version also defines which Microsoft C run-time and compiler are used:
Python version |
3.7 and above |
---|---|
Microsoft C run-time |
|
Compiler version |
MSVC++ 14.0 |
Visual Studio version |
2017 |
Installing compiler and Microsoft C run-time¶
As outlined above, installing a given version of Visual Studio will automatically install the corresponding compiler along with the Microsoft C run-time libraries.
This means that if you already have the corresponding version of Visual Studio installed, your environment is ready.
Nevertheless, since older version of Visual Studio are not available anymore, this next table references links for installing alternative environments:
CPython version |
Download links for Windows SDK or Visual Studio |
---|---|
3.7 and above |
or
|
These links have been copied from the great article [2] of Steve Dower, engineer at Microsoft.
Footnotes
CMake modules¶
To facilitate the writing of CMakeLists.txt
used to build
CPython C/C++/Cython extensions, scikit-build provides the following
CMake modules:
Cython¶
Find cython
executable.
This module will set the following variables in your project:
CYTHON_EXECUTABLE
path to the
cython
programCYTHON_VERSION
version of
cython
CYTHON_FOUND
true if the program was found
For more information on the Cython project, see https://cython.org/.
Cython is a language that makes writing C extensions for the Python language as easy as Python itself.
The following functions are defined:
- add_cython_target¶
Create a custom rule to generate the source code for a Python extension module using cython.
- add_cython_target(<Name> [<CythonInput>]
[EMBED_MAIN] [C | CXX] [PY2 | PY3] [OUTPUT_VAR <OutputVar>])
<Name>
is the name of the new target, and <CythonInput>
is the path to a cython source file. Note that, despite the name, no new
targets are created by this function. Instead, see OUTPUT_VAR
for
retrieving the path to the generated source for subsequent targets.
If only <Name>
is provided, and it ends in the “.pyx” extension, then it
is assumed to be the <CythonInput>
. The name of the input without the
extension is used as the target name. If only <Name>
is provided, and it
does not end in the “.pyx” extension, then the <CythonInput>
is assumed to
be <Name>.pyx
.
The Cython include search path is amended with any entries found in the
INCLUDE_DIRECTORIES
property of the directory containing the
<CythonInput>
file. Use include_directories
to add to the Cython
include search path.
Options:
EMBED_MAIN
Embed a main() function in the generated output (for stand-alone applications that initialize their own Python runtime).
C | CXX
Force the generation of either a C or C++ file. By default, a C file is generated, unless the C language is not enabled for the project; in this case, a C++ file is generated by default.
PY2 | PY3
Force compilation using either Python-2 or Python-3 syntax and code semantics. By default, Python-2 syntax and semantics are used if the major version of Python found is 2. Otherwise, Python-3 syntax and semantics are used.
OUTPUT_VAR <OutputVar>
Set the variable
<OutputVar>
in the parent scope to the path to the generated source file. By default,<Name>
is used as the output variable name.
Defined variables:
<OutputVar>
The path of the generated source file.
Cache variables that affect the behavior include:
CYTHON_ANNOTATE
Whether to create an annotated .html file when compiling.
CYTHON_FLAGS
Additional flags to pass to the Cython compiler.
Example usage¶
find_package(Cython)
# Note: In this case, either one of these arguments may be omitted; their
# value would have been inferred from that of the other.
add_cython_target(cy_code cy_code.pyx)
add_library(cy_code MODULE ${cy_code})
target_link_libraries(cy_code ...)
NumPy¶
Find the include directory for numpy/arrayobject.h
as well as other NumPy tools like conv-template
and
from-template
.
This module sets the following variables:
NumPy_FOUND
True if NumPy was found.
NumPy_INCLUDE_DIRS
The include directories needed to use NumpPy.
NumPy_VERSION
The version of NumPy found.
NumPy_CONV_TEMPLATE_EXECUTABLE
Path to conv-template executable.
NumPy_FROM_TEMPLATE_EXECUTABLE
Path to from-template executable.
The module will also explicitly define one cache variable:
NumPy_INCLUDE_DIR
Note
To support NumPy < v0.15.0 where from-template
and conv-template
are not declared as entry points,
the module emulates the behavior of standalone executables by setting the corresponding variables with the
path the the python interpreter and the path to the associated script. For example:
set(NumPy_CONV_TEMPLATE_EXECUTABLE /path/to/python /path/to/site-packages/numpy/distutils/conv_template.py CACHE STRING "Command executing conv-template program" FORCE)
set(NumPy_FROM_TEMPLATE_EXECUTABLE /path/to/python /path/to/site-packages/numpy/distutils/from_template.py CACHE STRING "Command executing from-template program" FORCE)
PythonExtensions¶
This module defines CMake functions to build Python extension modules and stand-alone executables.
The following variables are defined:
PYTHON_PREFIX - absolute path to the current Python
distribution's prefix
PYTHON_SITE_PACKAGES_DIR - absolute path to the current Python
distribution's site-packages directory
PYTHON_RELATIVE_SITE_PACKAGES_DIR - path to the current Python
distribution's site-packages directory
relative to its prefix
PYTHON_SEPARATOR - separator string for file path
components. Equivalent to ``os.sep`` in
Python.
PYTHON_PATH_SEPARATOR - separator string for PATH-style
environment variables. Equivalent to
``os.pathsep`` in Python.
PYTHON_EXTENSION_MODULE_SUFFIX - suffix of the compiled module. For example, on
Linux, based on environment, it could be ``.cpython-35m-x86_64-linux-gnu.so``.
The following functions are defined:
- python_extension_module¶
For libraries meant to be used as Python extension modules, either dynamically
loaded or directly linked. Amend the configuration of the library target
(created using add_library
) with additional options needed to build and
use the referenced library as a Python extension module.
- python_extension_module(<Target>
[LINKED_MODULES_VAR <LinkedModVar>] [FORWARD_DECL_MODULES_VAR <ForwardDeclModVar>] [MODULE_SUFFIX <ModuleSuffix>])
Only extension modules that are configured to be built as MODULE libraries can
be runtime-loaded through the standard Python import mechanism. All other
modules can only be included in standalone applications that are written to
expect their presence. In addition to being linked against the libraries for
these modules, such applications must forward declare their entry points and
initialize them prior to use. To generate these forward declarations and
initializations, see python_modules_header
.
If <Target>
does not refer to a target, then it is assumed to refer to an
extension module that is not linked at all, but compiled along with other
source files directly into an executable. Adding these modules does not cause
any library configuration modifications, and they are not added to the list of
linked modules. They still must be forward declared and initialized, however,
and so are added to the forward declared modules list.
If the associated target is of type MODULE_LIBRARY
, the LINK_FLAGS target
property is used to set symbol visibility and export only the module init function.
This applies to GNU and MSVC compilers.
Options:
LINKED_MODULES_VAR <LinkedModVar>
Name of the variable referencing a list of extension modules whose libraries must be linked into the executables of any stand-alone applications that use them. By default, the global property
PY_LINKED_MODULES_LIST
is used.FORWARD_DECL_MODULES_VAR <ForwardDeclModVar>
Name of the variable referencing a list of extension modules whose entry points must be forward declared and called by any stand-alone applications that use them. By default, the global property
PY_FORWARD_DECL_MODULES_LIST
is used.MODULE_SUFFIX <ModuleSuffix>
Suffix appended to the python extension module file. The default suffix is retrieved using
sysconfig.get_config_var("SO")"
, if not available, the default is then.so
on unix and.pyd
on windows. Setting the variablePYTHON_EXTENSION_MODULE_SUFFIX
in the caller scope defines the value used for all extensions not having a suffix explicitly specified usingMODULE_SUFFIX
parameter.
- python_standalone_executable¶
python_standalone_executable(<Target>)
For standalone executables that initialize their own Python runtime
(such as when building source files that include one generated by Cython with
the –embed option). Amend the configuration of the executable target
(created using add_executable
) with additional options needed to properly
build the referenced executable.
- python_modules_header¶
Generate a header file that contains the forward declarations and
initialization routines for the given list of Python extension modules.
<Name>
is the logical name for the header file (no file extensions).
<HeaderFilename>
is the actual destination filename for the header file
(e.g.: decl_modules.h).
- python_modules_header(<Name> [HeaderFilename]
[FORWARD_DECL_MODULES_LIST <ForwardDeclModList>] [HEADER_OUTPUT_VAR <HeaderOutputVar>] [INCLUDE_DIR_OUTPUT_VAR <IncludeDirOutputVar>])
without the extension is used as the logical name. If only <Name>
is
If only <Name>
is provided, and it ends in the “.h” extension, then it
is assumed to be the <HeaderFilename>
. The filename of the header file
provided, and it does not end in the “.h” extension, then the
<HeaderFilename>
is assumed to <Name>.h
.
The exact contents of the generated header file depend on the logical
<Name>
. It should be set to a value that corresponds to the target
application, or for the case of multiple applications, some identifier that
conveyes its purpose. It is featured in the generated multiple inclusion
guard as well as the names of the generated initialization routines.
The generated header file includes forward declarations for all listed modules, as well as implementations for the following class of routines:
int <Name>_<Module>(void)
Initializes the python extension module,
<Module>
. Returns an integer handle to the module.void <Name>_LoadAllPythonModules(void)
Initializes all listed python extension modules.
void CMakeLoadAllPythonModules(void);
Alias for
<Name>_LoadAllPythonModules
whose name does not depend on<Name>
. This function is excluded during preprocessing if the preprocessing macroEXCLUDE_LOAD_ALL_FUNCTION
is defined.void Py_Initialize_Wrapper();
Wrapper arpund
Py_Initialize()
that initializes all listed python extension modules. This function is excluded during preprocessing if the preprocessing macroEXCLUDE_PY_INIT_WRAPPER
is defined. If this function is generated, thenPy_Initialize()
is redefined to a macro that calls this function.
Options:
FORWARD_DECL_MODULES_LIST <ForwardDeclModList>
List of extension modules for which to generate forward declarations of their entry points and their initializations. By default, the global property
PY_FORWARD_DECL_MODULES_LIST
is used.HEADER_OUTPUT_VAR <HeaderOutputVar>
Name of the variable to set to the path to the generated header file. By default,
<Name>
is used.INCLUDE_DIR_OUTPUT_VAR <IncludeDirOutputVar>
Name of the variable to set to the path to the directory containing the generated header file. By default,
<Name>_INCLUDE_DIRS
is used.
Defined variables:
<HeaderOutputVar>
The path to the generated header file
<IncludeDirOutputVar>
Directory containing the generated header file
Example usage¶
find_package(PythonExtensions)
find_package(Cython)
find_package(Boost COMPONENTS python)
# Simple Cython Module -- no executables
add_cython_target(_module.pyx)
add_library(_module MODULE ${_module})
python_extension_module(_module)
# Mix of Cython-generated code and C++ code using Boost Python
# Stand-alone executable -- no modules
include_directories(${Boost_INCLUDE_DIRS})
add_cython_target(main.pyx CXX EMBED_MAIN)
add_executable(main boost_python_module.cxx ${main})
target_link_libraries(main ${Boost_LIBRARIES})
python_standalone_executable(main)
# stand-alone executable with three extension modules:
# one statically linked, one dynamically linked, and one loaded at runtime
#
# Freely mixes Cython-generated code, code using Boost-Python, and
# hand-written code using the CPython API.
# module1 -- statically linked
add_cython_target(module1.pyx)
add_library(module1 STATIC ${module1})
python_extension_module(module1
LINKED_MODULES_VAR linked_module_list
FORWARD_DECL_MODULES_VAR fdecl_module_list)
# module2 -- dynamically linked
include_directories(${Boost_INCLUDE_DIRS})
add_library(module2 SHARED boost_module2.cxx)
target_link_libraries(module2 ${Boost_LIBRARIES})
python_extension_module(module2
LINKED_MODULES_VAR linked_module_list
FORWARD_DECL_MODULES_VAR fdecl_module_list)
# module3 -- loaded at runtime
add_cython_target(module3a.pyx)
add_library(module3 MODULE ${module3a} module3b.cxx)
target_link_libraries(module3 ${Boost_LIBRARIES})
python_extension_module(module3
LINKED_MODULES_VAR linked_module_list
FORWARD_DECL_MODULES_VAR fdecl_module_list)
# application executable -- generated header file + other source files
python_modules_header(modules
FORWARD_DECL_MODULES_LIST ${fdecl_module_list})
include_directories(${modules_INCLUDE_DIRS})
add_cython_target(mainA)
add_cython_target(mainC)
add_executable(main ${mainA} mainB.cxx ${mainC} mainD.c)
target_link_libraries(main ${linked_module_list} ${Boost_LIBRARIES})
python_standalone_executable(main)
The following functions are defined:
- add_python_library¶
Add a library that contains a mix of C, C++, Fortran, Cython, F2PY, Template, and Tempita sources. The required targets are automatically generated to “lower” source files from their high-level representation to a file that the compiler can accept.
- add_python_library(<Name>
SOURCES [source1 [source2 …]] [INCLUDE_DIRECTORIES [dir1 [dir2 …]] [LINK_LIBRARIES [lib1 [lib2 …]] [DEPENDS [source1 [source2 …]]])
Example usage¶
find_package(PythonExtensions)
file(GLOB arpack_sources ARPACK/SRC/*.f ARPACK/UTIL/*.f)
add_python_library(arpack_scipy
SOURCES ${arpack_sources}
${g77_wrapper_sources}
INCLUDE_DIRECTORIES ARPACK/SRC
)
- add_python_extension¶
Add a extension that contains a mix of C, C++, Fortran, Cython, F2PY, Template, and Tempita sources. The required targets are automatically generated to “lower” source files from their high-level representation to a file that the compiler can accept.
- add_python_extension(<Name>
SOURCES [source1 [source2 …]] [INCLUDE_DIRECTORIES [dir1 [dir2 …]] [LINK_LIBRARIES [lib1 [lib2 …]] [DEPENDS [source1 [source2 …]]])
Example usage¶
find_package(PythonExtensions)
file(GLOB arpack_sources ARPACK/SRC/*.f ARPACK/UTIL/*.f)
add_python_extension(arpack_scipy
SOURCES ${arpack_sources}
${g77_wrapper_sources}
INCLUDE_DIRECTORIES ARPACK/SRC
)
F2PY¶
The purpose of the F2PY –Fortran to Python interface generator– project is to provide a connection between Python and Fortran languages.
F2PY is a Python package (with a command line tool f2py and a module f2py2e) that facilitates creating/building Python C/API extension modules that make it possible to call Fortran 77/90/95 external subroutines and Fortran 90/95 module subroutines as well as C functions; to access Fortran 77 COMMON blocks and Fortran 90/95 module data, including allocatable arrays from Python.
For more information on the F2PY project, see http://www.f2py.com/.
The following variables are defined:
F2PY_EXECUTABLE - absolute path to the F2PY executable
F2PY_VERSION_STRING - the version of F2PY found
F2PY_VERSION_MAJOR - the F2PY major version
F2PY_VERSION_MINOR - the F2PY minor version
F2PY_VERSION_PATCH - the F2PY patch version
Note
By default, the module finds the F2PY program associated with the installed NumPy package.
Example usage¶
Assuming that a package named method
is declared in setup.py
and that the corresponding directory
containing __init__.py
also exists, the following CMake code can be added to method/CMakeLists.txt
to ensure the C sources associated with cylinder_methods.f90
are generated and the corresponding module
is compiled:
find_package(F2PY REQUIRED)
set(f2py_module_name "_cylinder_methods")
set(fortran_src_file "${CMAKE_CURRENT_SOURCE_DIR}/cylinder_methods.f90")
set(generated_module_file ${CMAKE_CURRENT_BINARY_DIR}/${f2py_module_name}${PYTHON_EXTENSION_MODULE_SUFFIX})
add_custom_target(${f2py_module_name} ALL
DEPENDS ${generated_module_file}
)
add_custom_command(
OUTPUT ${generated_module_file}
COMMAND ${F2PY_EXECUTABLE}
-m ${f2py_module_name}
-c
${fortran_src_file}
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
)
install(FILES ${generated_module_file} DESTINATION methods)
Warning
Using f2py
with -c
argument means that f2py is also responsible to build the module. In that
case, CMake is not used to find the compiler and configure the associated build system.
The following functions are defined:
- add_f2py_target¶
Create a custom rule to generate the source code for a Python extension module using f2py.
- add_f2py_target(<Name> [<F2PYInput>]
[OUTPUT_VAR <OutputVar>])
<Name>
is the name of the new target, and <F2PYInput>
is the path to a pyf source file. Note that, despite the name, no new
targets are created by this function. Instead, see OUTPUT_VAR
for
retrieving the path to the generated source for subsequent targets.
If only <Name>
is provided, and it ends in the “.pyf” extension, then it
is assumed to be the <F2PYInput>
. The name of the input without the
extension is used as the target name. If only <Name>
is provided, and it
does not end in the “.pyf” extension, then the <F2PYInput>
is assumed to
be <Name>.pyf
.
Options:
OUTPUT_VAR <OutputVar>
Set the variable
<OutputVar>
in the parent scope to the path to the generated source file. By default,<Name>
is used as the output variable name.DEPENDS [source [source2...]]
Sources that must be generated before the F2PY command is run.
Defined variables:
<OutputVar>
The path of the generated source file.
Example usage¶
find_package(F2PY)
# Note: In this case, either one of these arguments may be omitted; their
# value would have been inferred from that of the other.
add_f2py_target(f2py_code f2py_code.pyf)
add_library(f2py_code MODULE ${f2py_code})
target_link_libraries(f2py_code ...)
They can be included using find_package
:
find_package(Cython REQUIRED)
find_package(NumPy REQUIRED)
find_package(PythonExtensions REQUIRED)
find_package(F2PY REQUIRED)
For more details, see the respective documentation of each modules.
Contributing¶
Contributions are welcome, and they are greatly appreciated! Every little bit helps, and credit will always be given.
Types of Contributions¶
You can contribute in many ways:
Report Bugs¶
Report bugs at https://github.com/scikit-build/scikit-build/issues.
If you are reporting a bug, please include:
Your operating system name and version.
Any details about your local setup that might be helpful in troubleshooting.
Detailed steps to reproduce the bug.
Fix Bugs¶
Look through the GitHub issues for bugs. Anything tagged with “bug” is open to whoever wants to implement it.
Implement Features¶
Look through the GitHub issues for features. Anything tagged with “feature” is open to whoever wants to implement it.
Write Documentation¶
The scikit-build project could always use more documentation. We welcome help with the official scikit-build docs, in docstrings, or even on blog posts and articles for the web.
Submit Feedback¶
The best way to send feedback is to file an issue at https://github.com/scikit-build/scikit-build/issues.
If you are proposing a new feature:
Explain in detail how it would work.
Keep the scope as narrow as possible, to make it easier to implement.
Remember that this is a volunteer-driven project, and that contributions are welcome :)
Get Started¶
Ready to contribute? Here’s how to set up scikit-build
for local development.
Fork the
scikit-build
repo on GitHub.Clone your fork locally:
$ git clone git@github.com:your_name_here/scikit-build.git
You can use the
gh
command line application to do these last two steps, as well.Make sure you have
nox
installed usingpipx install nox
. If you don’t have pipx, you can install it withpip install pipx
. (You can installnox
withpip
instead, but nox is an application, not a library, and applications should always use pipx.) You can install both of these packages from brew on macOS/linux. You can also usepipx run nox
instead.Create a branch for local development:
$ git checkout -b name-of-your-bugfix-or-feature
Now you can make your changes locally.
When you’re done making changes, check that your changes pass our linters and the tests:
$ nox
If you would like to check all Python versions and you don’t happen to have them all installed locally, you can use the manylinux docker image instead:
$ docker run –rm -itv $PWD:/src -w /src quay.io/pypa/manylinux_2_24_x86_64:latest pipx run nox
Commit your changes and push your branch to GitHub:
$ git add -u . $ git commit -m "Your detailed description of your changes." $ git push origin name-of-your-bugfix-or-feature
Submit a pull request through the GitHub website or the
gh
command line application.
Pull Request Guidelines¶
Before you submit a pull request, check that it meets these guidelines:
The pull request should include tests.
If the pull request adds functionality, the docs should be updated. Put your new functionality into a function with a docstring, and add the feature to the list in
README.rst
.The pull request should work for Python 3.7+ and PyPy. Make sure that the tests pass for all supported Python versions in CI on your PR.
Tips¶
To run a subset of tests:
$ nox -s tests -- tests/test_skbuild.py
You can build and serve the docs:
$ nox -s docs -- serve
You can build an SDist and a wheel in the dist
folder:
$ nox -s build
Hacking¶
Controlling CMake using scikit-build¶
You can drive CMake directly using scikit-build:
""" Use scikit-build's `cmaker` to control CMake configuration and build.
1. Use `cmaker` to define an object that provides convenient access to
CMake's configure and build functionality.
2. Use defined object, `maker`, to call `configure()` to read the
`CMakeLists.txt` file in the current directory and generate a Makefile,
Visual Studio solution, or whatever is appropriate for your platform.
3. Call `make()` on the object to execute the build with the
appropriate build tool and perform installation to the local directory.
"""
from skbuild import cmaker
maker = cmaker.CMaker()
maker.configure()
maker.make()
See skbuild.cmaker.CMaker
for more details.
Internal API¶
skbuild¶
skbuild package¶
scikit-build is an improved build system generator for CPython C extensions.
This module provides the glue between the setuptools Python module and CMake.
- skbuild.setup(*, cmake_args: Sequence[str] = (), cmake_install_dir: str = '', cmake_source_dir: str = '', cmake_with_sdist: bool = False, cmake_languages: Sequence[str] = ('C', 'CXX'), cmake_minimum_required_version: str | None = None, cmake_process_manifest_hook: Callable[[list[str]], list[str]] | None = None, cmake_install_target: str = 'install', **kw: Any) Distribution [source]¶
This function wraps setup() so that we can run cmake, make, CMake build, then proceed as usual with setuptools, appending the CMake-generated output as necessary.
The CMake project is re-configured only if needed. This is achieved by (1) retrieving the environment mapping associated with the generator set in the
CMakeCache.txt
file, (2) saving the CMake configure arguments and version inskbuild.constants.CMAKE_SPEC_FILE()
: and (3) re-configuring only if either the generator or the CMake specs change.
Subpackages¶
skbuild.command package¶
Collection of objects allowing to customize behavior of standard distutils and setuptools commands.
- class skbuild.command.CommandMixinProtocol(*args, **kwargs)[source]¶
Bases:
Protocol
Protocol for commands that use CMake.
- build_base: str¶
- distribution: Distribution¶
- install_lib: str | None¶
- install_platlib: str¶
- outfiles: list[str]¶
- class skbuild.command.set_build_base_mixin[source]¶
Bases:
object
Mixin allowing to override distutils and setuptools commands.
Submodules¶
skbuild.command.bdist module¶
This module defines custom implementation of bdist
setuptools command.
- class skbuild.command.bdist.bdist(dist)[source]¶
Bases:
set_build_base_mixin
,bdist
Custom implementation of
bdist
setuptools command.
skbuild.command.bdist_wheel module¶
This module defines custom implementation of bdist_wheel
setuptools
command.
- class skbuild.command.bdist_wheel.bdist_wheel(dist, **kw)[source]¶
Bases:
set_build_base_mixin
,bdist_wheel
Custom implementation of
bdist_wheel
setuptools command.
skbuild.command.build module¶
This module defines custom implementation of build
setuptools command.
- class skbuild.command.build.build(dist, **kw)[source]¶
Bases:
set_build_base_mixin
,build
Custom implementation of
build
setuptools command.
skbuild.command.build_ext module¶
This module defines custom implementation of build_ext
setuptools command.
- class skbuild.command.build_ext.build_ext(dist, **kw)[source]¶
Bases:
set_build_base_mixin
,build_ext
Custom implementation of
build_ext
setuptools command.- copy_extensions_to_source() None [source]¶
This function is only-called when doing inplace build.
It is customized to ensure the extensions compiled using distutils are copied back to the source tree instead of the
skbuild.constants.CMAKE_INSTALL_DIR()
.
skbuild.command.build_py module¶
This module defines custom implementation of build_py
setuptools
command.
- class skbuild.command.build_py.build_py(dist, **kw)[source]¶
Bases:
set_build_base_mixin
,build_py
Custom implementation of
build_py
setuptools command.- build_module(module: str | list[str] | tuple[str, ...], module_file: str, package: str) None [source]¶
Handle –hide-listing option.
Increments
outfiles_count
.
- find_modules() list[tuple[str, str, str]] [source]¶
Finds individually-specified Python modules, ie. those listed by module name in ‘self.py_modules’. Returns a list of tuples (package, module_base, filename): ‘package’ is a tuple of the path through package-space to the module; ‘module_base’ is the bare (no packages, no dots) module name, and ‘filename’ is the path to the “.py” file (relative to the distribution root) that implements the module.
skbuild.command.clean module¶
This module defines custom implementation of clean
setuptools command.
- class skbuild.command.clean.clean(dist, **kw)[source]¶
Bases:
set_build_base_mixin
,clean
Custom implementation of
clean
setuptools command.
skbuild.command.egg_info module¶
This module defines custom implementation of egg_info
setuptools
command.
- class skbuild.command.egg_info.egg_info(dist, **kw)[source]¶
Bases:
set_build_base_mixin
,egg_info
Custom implementation of
egg_info
setuptools command.
skbuild.command.generate_source_manifest module¶
This module defines custom generate_source_manifest
setuptools
command.
- class skbuild.command.generate_source_manifest.generate_source_manifest(dist)[source]¶
Bases:
set_build_base_mixin
,Command
Custom setuptools command generating a MANIFEST file if not already provided.
- description = 'generate source MANIFEST'¶
- finalize_options(*args: object, **kwargs: object) None [source]¶
Set final values for all the options that this command supports.
- initialize_options() None [source]¶
Set default values for all the options that this command supports.
- run() None [source]¶
If neither a MANIFEST, nor a MANIFEST.in file is provided, and we are in a git repo, try to create a MANIFEST.in file from the output of git ls-tree –name-only -r HEAD.
We need a reliable way to tell if an existing MANIFEST file is one we’ve generated. distutils already uses a first-line comment to tell if the MANIFEST file was generated from MANIFEST.in, so we use a dummy file, _skbuild_MANIFEST, to avoid confusing distutils.
skbuild.command.install module¶
This module defines custom implementation of install
setuptools
command.
- class skbuild.command.install.install(dist, **kw)[source]¶
Bases:
set_build_base_mixin
,install
Custom implementation of
install
setuptools command.
skbuild.command.install_lib module¶
This module defines custom implementation of install_lib
setuptools
command.
- class skbuild.command.install_lib.install_lib(dist, **kw)[source]¶
Bases:
set_build_base_mixin
,install_lib
Custom implementation of
install_lib
setuptools command.
skbuild.command.install_scripts module¶
This module defines custom implementation of install_scripts
setuptools
command.
- class skbuild.command.install_scripts.install_scripts(dist, **kw)[source]¶
Bases:
set_build_base_mixin
,install_scripts
Custom implementation of
install_scripts
setuptools command.
skbuild.command.sdist module¶
This module defines custom implementation of sdist
setuptools command.
- class skbuild.command.sdist.sdist(dist, **kw)[source]¶
Bases:
set_build_base_mixin
,sdist
Custom implementation of
sdist
setuptools command.- make_archive(base_name: str, _format: str, root_dir: str | None = None, base_dir: str | None = None, owner: str | None = None, group: str | None = None) str [source]¶
Handle –hide-listing option.
- run(*args: object, **kwargs: object) None [source]¶
Force
egg_info.egg_info
command to run.
skbuild.command.test module¶
skbuild.platform_specifics package¶
This package provides get_platform()
allowing to get an instance
of abstract.CMakePlatform
matching the current platform.
This folder contains files the define CMake’s defaults for given platforms. Any of them can be overridden by either command line or by environment variables.
- class skbuild.platform_specifics.CMakeGenerator(name: str, env: Mapping[str, str] | None = None, toolset: str | None = None, arch: str | None = None, args: Iterable[str] | None = None)[source]¶
Bases:
object
Represents a CMake generator.
- __init__(name: str, env: Mapping[str, str] | None = None, toolset: str | None = None, arch: str | None = None, args: Iterable[str] | None = None) None [source]¶
Instantiate a generator object with the given
name
.By default,
os.environ
is associated with the generator. Dictionary passed asenv
parameter will be merged withos.environ
. If an environment variable is set in bothos.environ
andenv
, the variable inenv
is used.Some CMake generators support a
toolset
specification to tell the native build system how to choose a compiler. You can also include CMake arguments.
- property architecture: str | None¶
Architecture associated with the CMake generator.
- property description: str¶
Name of CMake generator with properties describing the environment (e.g toolset)
- property name: str¶
Name of CMake generator.
- property toolset: str | None¶
Toolset specification associated with the CMake generator.
- skbuild.platform_specifics.get_platform() CMakePlatform [source]¶
Return an instance of
abstract.CMakePlatform
corresponding to the current platform.
Submodules¶
skbuild.platform_specifics.abstract module¶
This module defines objects useful to discover which CMake generator is supported on the current platform.
- class skbuild.platform_specifics.abstract.CMakeGenerator(name: str, env: Mapping[str, str] | None = None, toolset: str | None = None, arch: str | None = None, args: Iterable[str] | None = None)[source]¶
Bases:
object
Represents a CMake generator.
- __init__(name: str, env: Mapping[str, str] | None = None, toolset: str | None = None, arch: str | None = None, args: Iterable[str] | None = None) None [source]¶
Instantiate a generator object with the given
name
.By default,
os.environ
is associated with the generator. Dictionary passed asenv
parameter will be merged withos.environ
. If an environment variable is set in bothos.environ
andenv
, the variable inenv
is used.Some CMake generators support a
toolset
specification to tell the native build system how to choose a compiler. You can also include CMake arguments.
- property architecture: str | None¶
Architecture associated with the CMake generator.
- property description: str¶
Name of CMake generator with properties describing the environment (e.g toolset)
- property name: str¶
Name of CMake generator.
- property toolset: str | None¶
Toolset specification associated with the CMake generator.
- class skbuild.platform_specifics.abstract.CMakePlatform[source]¶
Bases:
object
This class encapsulates the logic allowing to get the identifier of a working CMake generator.
Derived class should at least set
default_generators
.- static compile_test_cmakelist(cmake_exe_path: str, candidate_generators: Iterable[CMakeGenerator], cmake_args: Iterable[str] = ()) CMakeGenerator | None [source]¶
Attempt to configure the test project with each
CMakeGenerator
fromcandidate_generators
.Only cmake arguments starting with
-DCMAKE_
are used to configure the test project.The function returns the first generator allowing to successfully configure the test project using
cmake_exe_path
.
- property default_generators: list[CMakeGenerator]¶
List of generators considered by
get_best_generator()
.
- property generator_installation_help: str¶
Return message guiding the user for installing a valid toolchain.
- get_best_generator(generator_name: str | None = None, skip_generator_test: bool = False, languages: Iterable[str] = ('CXX', 'C'), cleanup: bool = True, cmake_executable: str = 'cmake', cmake_args: Iterable[str] = (), architecture: str | None = None) CMakeGenerator [source]¶
Loop over generators to find one that works by configuring and compiling a test project.
- Parameters:
generator_name (str | None) – If provided, uses only provided generator, instead of trying
default_generators
.skip_generator_test (bool) – If set to True and if a generator name is specified, the generator test is skipped. If no generator_name is specified and the option is set to True, the first available generator is used.
languages (tuple) – The languages you’ll need for your project, in terms that CMake recognizes.
cleanup (bool) – If True, cleans up temporary folder used to test generators. Set to False for debugging to see CMake’s output files.
cmake_executable (str) – Path to CMake executable used to configure and build the test project used to evaluate if a generator is working.
cmake_args (tuple) – List of CMake arguments to use when configuring the test project. Only arguments starting with
-DCMAKE_
are used.
- Returns:
CMake Generator object
- Return type:
CMakeGenerator
or None- Raises:
- get_generator(generator_name: str) CMakeGenerator [source]¶
Loop over generators and return the first that matches the given name.
- get_generators(generator_name: str) list[CMakeGenerator] [source]¶
Loop over generators and return all that match the given name.
skbuild.platform_specifics.bsd module¶
This module defines object specific to BSD platform.
- class skbuild.platform_specifics.bsd.BSDPlatform[source]¶
Bases:
UnixPlatform
BSD implementation of
abstract.CMakePlatform
.
skbuild.platform_specifics.cygwin module¶
This module defines object specific to Cygwin platform.
- class skbuild.platform_specifics.cygwin.CygwinPlatform[source]¶
Bases:
CMakePlatform
Cygwin implementation of
abstract.CMakePlatform
.- property generator_installation_help: str¶
Return message guiding the user for installing a valid toolchain.
skbuild.platform_specifics.linux module¶
This module defines object specific to Linux platform.
- class skbuild.platform_specifics.linux.LinuxPlatform[source]¶
Bases:
UnixPlatform
Linux implementation of
abstract.CMakePlatform
- static build_essential_install_cmd() tuple[str, str] [source]¶
Return a tuple of the form
(distribution_name, cmd)
.cmd
is the command allowing to install the build tools in the current Linux distribution. It set to an empty string if the command is not known.distribution_name
is the name of the current distribution. It is set to an empty string if the distribution could not be determined.
- property generator_installation_help: str¶
Return message guiding the user for installing a valid toolchain.
skbuild.platform_specifics.osx module¶
This module defines object specific to OSX platform.
- class skbuild.platform_specifics.osx.OSXPlatform[source]¶
Bases:
UnixPlatform
OSX implementation of
abstract.CMakePlatform
.- property generator_installation_help: str¶
Return message guiding the user for installing a valid toolchain.
skbuild.platform_specifics.aix module¶
This module defines object specific to AIX platform.
- class skbuild.platform_specifics.aix.AIXPlatform[source]¶
Bases:
UnixPlatform
AIX implementation of
abstract.CMakePlatform
.- property generator_installation_help: str¶
Return message guiding the user for installing a valid toolchain.
skbuild.platform_specifics.platform_factory module¶
This modules implements the logic allowing to instantiate the expected
abstract.CMakePlatform
.
- skbuild.platform_specifics.platform_factory.get_platform() CMakePlatform [source]¶
Return an instance of
abstract.CMakePlatform
corresponding to the current platform.
skbuild.platform_specifics.unix module¶
This module defines object specific to Unix platform.
- class skbuild.platform_specifics.unix.UnixPlatform[source]¶
Bases:
CMakePlatform
Unix implementation of
abstract.CMakePlatform
.
skbuild.platform_specifics.windows module¶
This module defines object specific to Windows platform.
- class skbuild.platform_specifics.windows.CMakeVisualStudioCommandLineGenerator(name: str, year: str, toolset: str | None = None, args: Iterable[str] | None = None)[source]¶
Bases:
CMakeGenerator
Represents a command-line CMake generator initialized with a specific Visual Studio environment.
- __init__(name: str, year: str, toolset: str | None = None, args: Iterable[str] | None = None)[source]¶
Instantiate CMake command-line generator.
The generator
name
can be values like Ninja, NMake Makefiles or NMake Makefiles JOM.The
year
defines the Visual Studio environment associated with the generator. SeeVS_YEAR_TO_VERSION
.If set, the
toolset
defines the Visual Studio Toolset to select.The platform (32-bit or 64-bit or ARM) is automatically selected.
- class skbuild.platform_specifics.windows.CMakeVisualStudioIDEGenerator(year: str, toolset: str | None = None)[source]¶
Bases:
CMakeGenerator
Represents a Visual Studio CMake generator.
- __init__(year: str, toolset: str | None = None) None [source]¶
Instantiate a generator object with its name set to the Visual Studio generator associated with the given
year
(seeVS_YEAR_TO_VERSION
), the current platform (32-bit or 64-bit) and the selectedtoolset
(if applicable).
- class skbuild.platform_specifics.windows.CachedEnv[source]¶
Bases:
TypedDict
Stored environment.
- INCLUDE: str¶
- LIB: str¶
- PATH: str¶
- skbuild.platform_specifics.windows.VS_YEAR_TO_VERSION = {'2017': 15, '2019': 16, '2022': 17}¶
Describes the version of Visual Studio supported by
CMakeVisualStudioIDEGenerator
andCMakeVisualStudioCommandLineGenerator
.The different version are identified by their year.
- class skbuild.platform_specifics.windows.WindowsPlatform[source]¶
Bases:
CMakePlatform
Windows implementation of
abstract.CMakePlatform
.- property generator_installation_help: str¶
Return message guiding the user for installing a valid toolchain.
- skbuild.platform_specifics.windows.find_visual_studio(vs_version: int) str [source]¶
Return Visual Studio installation path associated with
vs_version
or an empty string if any.The
vs_version
corresponds to the Visual Studio version to lookup. SeeVS_YEAR_TO_VERSION
.Note
Returns path based on the result of invoking
vswhere.exe
.
skbuild.utils package¶
This module defines functions generally useful in scikit-build.
- class skbuild.utils.CommonLog(*args, **kwargs)[source]¶
Bases:
Protocol
Protocol for loggers with an info method.
- class skbuild.utils.Distribution(script_name: str)[source]¶
Bases:
NamedTuple
Distribution stand-in.
- script_name: str¶
Alias for field number 0
- class skbuild.utils.PythonModuleFinder(packages: Sequence[str], package_dir: Mapping[str, str], py_modules: Sequence[str], alternative_build_base: str | None = None)[source]¶
Bases:
build_py
Convenience class to search for python modules.
This class is based on
distutils.command.build_py.build_by
and provides a specialized version offind_all_modules()
.- check_module(module: str, module_file: str) bool [source]¶
Return True if
module_file
belongs tomodule
.
- distribution: Distribution¶
- find_all_modules(project_dir: str | None = None) list[Any | tuple[str, str, str]] [source]¶
Compute the list of all modules that would be built by project located in current directory, whether they are specified one-module-at-a-time
py_modules
or by whole packagespackages
.By default, the function will search for modules in the current directory. Specifying
project_dir
parameter allow to change this.Return a list of tuples
(package, module, module_file)
.
- skbuild.utils.distribution_hide_listing(distribution: Distribution | Distribution) Iterator[bool | int] [source]¶
Given a
distribution
, this context manager temporarily sets distutils threshold to WARN if--hide-listing
argument was provided.It yields True if
--hide-listing
argument was provided.
- skbuild.utils.mkdir_p(path: str) None [source]¶
Ensure directory
path
exists. If needed, parent directories are created.
- skbuild.utils.parse_manifestin(template: str) list[str] [source]¶
This function parses template file (usually MANIFEST.in)
- class skbuild.utils.push_dir(directory: str | None = None, make_directory: bool = False)[source]¶
Bases:
ContextDecorator
Context manager to change current directory.
Submodules¶
skbuild.cmaker module¶
This module provides an interface for invoking CMake executable.
- class skbuild.cmaker.CMaker(cmake_executable: str = 'cmake')[source]¶
Bases:
object
Interface to CMake executable.
- Example:
>>> # Setup dummy repo >>> from skbuild.cmaker import CMaker >>> import ubelt as ub >>> from os.path import join >>> repo_dpath = ub.ensure_app_cache_dir('skbuild', 'test_cmaker') >>> ub.delete(repo_dpath) >>> src_dpath = ub.ensuredir(join(repo_dpath, 'SRC')) >>> cmake_fpath = join(src_dpath, 'CMakeLists.txt') >>> open(cmake_fpath, 'w').write(ub.codeblock( ''' cmake_minimum_required(VERSION 3.5.0) project(foobar NONE) file(WRITE "${CMAKE_BINARY_DIR}/foo.txt" "# foo") install(FILES "${CMAKE_BINARY_DIR}/foo.txt" DESTINATION ".") install(CODE "message(STATUS \\"Project has been installed\\")") message(STATUS "CMAKE_SOURCE_DIR:${CMAKE_SOURCE_DIR}") message(STATUS "CMAKE_BINARY_DIR:${CMAKE_BINARY_DIR}") ''' >>> )) >>> # create a cmaker instance in the dummy repo, configure, and make. >>> from skbuild.utils import push_dir >>> with push_dir(repo_dpath): >>> cmkr = CMaker() >>> config_kwargs = {'cmake_source_dir': str(src_dpath)} >>> print('--- test cmaker configure ---') >>> env = cmkr.configure(**config_kwargs) >>> print('--- test cmaker make ---') >>> cmkr.make(env=env)
- static check_for_bad_installs() None [source]¶
This function tries to catch files that are meant to be installed outside the project root before they are actually installed.
Indeed, we can not wait for the manifest, so we try to extract the information (install destination) from the CMake build files
*.cmake
found inskbuild.constants.CMAKE_BUILD_DIR()
.It raises
skbuild.exceptions.SKBuildError
if it found install destination outside ofskbuild.constants.CMAKE_INSTALL_DIR()
.
- configure(clargs: Sequence[str] = (), generator_name: str | None = None, skip_generator_test: bool = False, cmake_source_dir: str = '.', cmake_install_dir: str = '', languages: Sequence[str] = ('C', 'CXX'), cleanup: bool = True) dict[str, str] [source]¶
Calls cmake to generate the Makefile/VS Solution/XCode project.
- clargs: tuple
List of command line arguments to pass to cmake executable.
- generator_name: string
The string representing the CMake generator to use. If None, uses defaults for your platform.
- skip_generator_test: bool
If set to True and if a generator name is specified (either as a keyword argument or as clargs using -G <generator_name>), the generator test is skipped.
- cmake_source_dir: string
Path to source tree containing a
CMakeLists.txt
- cmake_install_dir: string
Relative directory to append to
skbuild.constants.CMAKE_INSTALL_DIR()
.- languages: tuple
List of languages required to configure the project and expected to be supported by the compiler. The language identifier that can be specified in the list corresponds to the one recognized by CMake.
- cleanup: bool
If True, cleans up temporary folder used to test generators. Set to False for debugging to see CMake’s output files.
Return a mapping of the environment associated with the selected
skbuild.platform_specifics.abstract.CMakeGenerator
.Mapping of the environment can also be later retrieved using
get_cached_generator_env()
.
- static get_cached(variable_name: str) str | None [source]¶
If set, returns the variable cached value from the
skbuild.constants.CMAKE_BUILD_DIR()
, otherwise returns None
- get_cached_generator_env() dict[str, str] | None [source]¶
If any, return a mapping of environment associated with the cached generator.
- classmethod get_cached_generator_name() str | None [source]¶
Reads and returns the cached generator from the
skbuild.constants.CMAKE_BUILD_DIR()
:. Returns None if not found.
- static get_python_include_dir(python_version: str) str | None [source]¶
Get include directory associated with the current python interpreter.
- Args:
python_version (str): python version, may be partial.
- Returns:
PathLike: python include dir
- Example:
>>> # xdoc: +IGNORE_WANT >>> from skbuild.cmaker import CMaker >>> python_version = CMaker.get_python_version() >>> python_include_dir = CMaker.get_python_include_dir(python_version) >>> print('python_include_dir = {!r}'.format(python_include_dir)) python_include_dir = '.../conda/envs/py37/include/python3.7m'
- static get_python_library(python_version: str) str | None [source]¶
Get path to the python library associated with the current python interpreter.
- Args:
python_version (str): python version, may be partial.
- Returns:
PathLike: python_library : python shared library
- Example:
>>> # xdoc: +IGNORE_WANT >>> from skbuild.cmaker import CMaker >>> python_version = CMaker.get_python_version() >>> python_library = CMaker.get_python_include_dir(python_version) >>> print('python_library = {!r}'.format(python_library)) python_library = '.../conda/envs/py37/include/python3.7m'
- static get_python_version() str [source]¶
Get version associated with the current python interpreter.
- Returns:
str: python version string
- Example:
>>> # xdoc: +IGNORE_WANT >>> from skbuild.cmaker import CMaker >>> python_version = CMaker.get_python_version() >>> print('python_version = {!r}'.format(python_version)) python_version = '3.7'
- install() list[str] [source]¶
Returns a list of file paths to install via setuptools that is compatible with the data_files keyword argument.
- make(clargs: Sequence[str] = (), config: str = 'Release', source_dir: str = '.', install_target: str = 'install', env: Mapping[str, str] | None = None) None [source]¶
Calls the system-specific make program to compile code.
- install_target: string
Name of the target responsible to install the project. Default is “install”.
Note
To workaround CMake issue #8438. See https://gitlab.kitware.com/cmake/cmake/-/issues/8438 Due to a limitation of CMake preventing from adding a dependency on the “build-all” built-in target, we explicitly build the project first when the install target is different from the default on.
- make_impl(clargs: list[str], config: str, source_dir: str, install_target: str | None, env: Mapping[str, str] | None = None) None [source]¶
Precondition: clargs does not have –config nor –install-target options. These command line arguments are extracted in the caller function make with clargs, config = pop_arg(’–config’, clargs, config)
This is a refactor effort for calling the function make twice in case the install_target is different than the default install.
- skbuild.cmaker.get_cmake_version(cmake_executable: str = 'cmake') str [source]¶
Runs CMake and extracts associated version information. Raises
skbuild.exceptions.SKBuildError
if it failed to execute CMake.- Example:
>>> # xdoc: IGNORE_WANT >>> from skbuild.cmaker import get_cmake_version >>> print(get_cmake_version()) 3.14.4
- skbuild.cmaker.has_cmake_cache_arg(cmake_args: list[str], arg_name: str, arg_value: str | None = None) bool [source]¶
Return True if
-D<arg_name>:TYPE=<arg_value>
is found incmake_args
. Ifarg_value
is None, return True only if-D<arg_name>:
is found in the list.
- skbuild.cmaker.pop_arg(arg: str, args: Sequence[str], default: None = None) tuple[list[str], str | None] [source]¶
- skbuild.cmaker.pop_arg(arg: str, args: Sequence[str], default: str) tuple[list[str], str]
Pops an argument
arg
from an argument listargs
and returns the new list and the value of the argument if present and a default otherwise.
skbuild.constants module¶
This module defines constants commonly used in scikit-build.
- skbuild.constants.CMAKE_DEFAULT_EXECUTABLE = 'cmake'¶
Default path to CMake executable.
- skbuild.constants.CMAKE_SPEC_FILE() str [source]¶
CMake specification file storing CMake version, CMake configuration arguments and environment variables
PYTHONNOUSERSITE
andPYTHONPATH
.
- skbuild.constants.SKBUILD_DIR() str [source]¶
Top-level directory where setuptools and CMake directories are generated.
- skbuild.constants.SKBUILD_MARKER_FILE() str [source]¶
Marker file used by
skbuild.command.generate_source_manifest.generate_source_manifest.run()
.
- skbuild.constants.set_skbuild_plat_name(plat_name: str) None [source]¶
Set platform name associated with scikit-build functions returning a path:
- skbuild.constants.skbuild_plat_name() str [source]¶
Get platform name formatted as <operating_system>[-<operating_system_version>]-<machine_architecture>.
Default value corresponds to
_default_skbuild_plat_name()
and can be overridden withset_skbuild_plat_name()
.Examples of values are macosx-10.9-x86_64, linux-x86_64, linux-i686 or win-am64.
skbuild.exceptions module¶
This module defines exceptions commonly used in scikit-build.
- exception skbuild.exceptions.SKBuildError[source]¶
Bases:
RuntimeError
Exception raised when an error occurs while configuring or building a project.
- exception skbuild.exceptions.SKBuildGeneratorNotFoundError[source]¶
Bases:
SKBuildError
Exception raised when no suitable generator is found for the current platform.
- exception skbuild.exceptions.SKBuildInvalidFileInstallationError[source]¶
Bases:
SKBuildError
Exception raised when a file is being installed into an invalid location.
skbuild.setuptools_wrap module¶
This module provides functionality for wrapping key infrastructure components from distutils and setuptools.
- skbuild.setuptools_wrap.create_skbuild_argparser() ArgumentParser [source]¶
Create and return a scikit-build argument parser.
- skbuild.setuptools_wrap.get_default_include_package_data() bool [source]¶
Include package data if pyproject.toml contains the project or tool.setuptools table.
- skbuild.setuptools_wrap.parse_args() tuple[list[str], str | None, bool, list[str], list[str]] [source]¶
This function parses the command-line arguments
sys.argv
and returns the tuple(setuptools_args, cmake_executable, skip_generator_test, cmake_args, build_tool_args)
where each*_args
element corresponds to a set of arguments separated by--
.
- skbuild.setuptools_wrap.parse_skbuild_args(args: Sequence[str], cmake_args: Sequence[str], build_tool_args: Sequence[str]) tuple[list[str], str | None, bool, list[str], list[str]] [source]¶
Parse arguments in the scikit-build argument set. Convert specified arguments to proper format and append to cmake_args and build_tool_args. Returns the tuple
(remaining arguments, cmake executable, skip_generator_test)
.
- skbuild.setuptools_wrap.setup(*, cmake_args: Sequence[str] = (), cmake_install_dir: str = '', cmake_source_dir: str = '', cmake_with_sdist: bool = False, cmake_languages: Sequence[str] = ('C', 'CXX'), cmake_minimum_required_version: str | None = None, cmake_process_manifest_hook: Callable[[list[str]], list[str]] | None = None, cmake_install_target: str = 'install', **kw: Any) Distribution [source]¶
This function wraps setup() so that we can run cmake, make, CMake build, then proceed as usual with setuptools, appending the CMake-generated output as necessary.
The CMake project is re-configured only if needed. This is achieved by (1) retrieving the environment mapping associated with the generator set in the
CMakeCache.txt
file, (2) saving the CMake configure arguments and version inskbuild.constants.CMAKE_SPEC_FILE()
: and (3) re-configuring only if either the generator or the CMake specs change.
- skbuild.setuptools_wrap.strip_package(package_parts: Sequence[str], module_file: str) str [source]¶
Given
package_parts
(e.g.['foo', 'bar']
) and amodule_file
(e.g.foo/bar/jaz/rock/roll.py
), starting from the left, this function will strip the parts of the path matching the package parts and return a new string (e.gjaz/rock/roll.py
).The function will work as expected for either Windows or Unix-style
module_file
and this independently of the platform.
Internal CMake Modules¶
targetLinkLibrariesWithDynamicLookup¶
Public Functions¶
The following functions are defined:
- target_link_libraries_with_dynamic_lookup¶
target_link_libraries_with_dynamic_lookup(<Target> [<Libraries>])
Useful to “weakly” link a loadable module. For example, it should be used when compiling a loadable module when the symbols should be resolve from the run-time environment where the module is loaded, and not a specific system library.
Like proper linking, except that the given <Libraries>
are not necessarily
linked. Instead, the <Target>
is produced in a manner that allows for
symbols unresolved within it to be resolved at runtime, presumably by the
given <Libraries>
. If such a target can be produced, the provided
<Libraries>
are not actually linked.
It links a library to a target such that the symbols are resolved at run-time not link-time.
The linker is checked to see if it supports undefined symbols when linking a shared library. If it does then the library is not linked when specified with this function.
On platforms that do not support weak-linking, this function works just
like target_link_libraries
.
Note
For OSX it uses undefined dynamic_lookup
. This is similar to using
-shared
on Linux where undefined symbols are ignored.
For more details, see blog from Tim D. Smith.
- check_dynamic_lookup¶
Check if the linker requires a command line flag to allow leaving symbols
unresolved when producing a target of type <TargetType>
that is
weakly-linked against a dependency of type <LibType>
.
<TargetType>
can be one of “STATIC”, “SHARED”, “MODULE”, or “EXE”.
<LibType>
can be one of “STATIC”, “SHARED”, or “MODULE”.
Long signature:
check_dynamic_lookup(<TargetType>
<LibType>
<ResultVar>
[<LinkFlagsVar>])
Short signature:
check_dynamic_lookup(<ResultVar>) # <TargetType> set to "MODULE"
# <LibType> set to "SHARED"
The result is cached between invocations and recomputed only when the value
of CMake’s linker flag list changes; CMAKE_STATIC_LINKER_FLAGS
if
<TargetType>
is “STATIC”, and CMAKE_SHARED_LINKER_FLAGS
otherwise.
Defined variables:
<ResultVar>
Whether the current C toolchain supports weak-linking for target binaries of type
<TargetType>
that are weakly-linked against a dependency target of type<LibType>
.<LinkFlagsVar>
List of flags to add to the linker command to produce a working target binary of type
<TargetType>
that is weakly-linked against a dependency target of type<LibType>
.HAS_DYNAMIC_LOOKUP_<TargetType>_<LibType>
Cached, global alias for
<ResultVar>
DYNAMIC_LOOKUP_FLAGS_<TargetType>_<LibType>
Cached, global alias for
<LinkFlagsVar>
Private Functions¶
The following private functions are defined:
Warning
These functions are not part of the scikit-build API. They exist purely as an implementation detail and may change from version to version without notice, or even be removed.
We mean it.
- _get_target_type¶
_get_target_type(<ResultVar> <Target>)
Shorthand for querying an abbreviated version of the target type
of the given <Target>
.
<ResultVar>
is set to:
“STATIC” for a STATIC_LIBRARY,
“SHARED” for a SHARED_LIBRARY,
“MODULE” for a MODULE_LIBRARY,
and “EXE” for an EXECUTABLE.
Defined variables:
<ResultVar>
The abbreviated version of the
<Target>
’s type.
- _test_weak_link_project¶
_test_weak_link_project(<TargetType>
<LibType>
<ResultVar>
<LinkFlagsVar>)
Attempt to compile and run a test project where a target of type
<TargetType>
is weakly-linked against a dependency of type <LibType>
:
<TargetType>
can be one of “STATIC”, “SHARED”, “MODULE”, or “EXE”.<LibType>
can be one of “STATIC”, “SHARED”, or “MODULE”.
Defined variables:
<ResultVar>
Whether the current C toolchain can produce a working target binary of type
<TargetType>
that is weakly-linked against a dependency target of type<LibType>
.<LinkFlagsVar>
List of flags to add to the linker command to produce a working target binary of type
<TargetType>
that is weakly-linked against a dependency target of type<LibType>
.
Credits¶
Please see the GitHub project page at https://github.com/scikit-build/scikit-build/graphs/contributors
Release Notes¶
This is the list of changes to scikit-build between each release. For full details, see the commit logs at https://github.com/scikit-build/scikit-build
Next Release¶
We are hard at work on the next generation of scikit-build scikit-build-core, which will eventually replace the backend here. We are also continuing to fix bugs, make improvements, and backport changes here.
Scikit-build 0.17.6¶
A small fix release with some new platforms and better testing, including CPython 3.12.0b1.
Bug fixes¶
Support added for AIX (with recent CMake) by @bhuntsman in #988.
Testing¶
Miscellaneous¶
Docs improvements in #979.
Scikit-build 0.17.5¶
A small fix release fixing the passing on of generator specific arguments. This fixes some cases where the Ninja generator was found but then was unable to build. NetBSD was reported to work, so was added to the BSD’s supported.
Bug fixes¶
Scikit-build 0.17.4¶
A followup fix to the issue 0.17.3 tried to fix. We now have a method to manually test downstream packages, too.
Bug fixes¶
Make sure include dir is found even if the lib is not present in #974.
Scikit-build 0.17.3¶
A small release related to PYTHON_LIBRARY
handling changes in 0.17.2;
scikit-build 0.17.3 returns an empty string from get_python_library
if no
Python library is present (like on manylinux), where 0.17.2 returned None, and
previous versions returned a non-existent path. Note that adding REQUIRED
to find_package(PythonLibs
will fail, but it is incorrect (you must not
link to libPython.so
) and was really just injecting a non-existent path
before.
Bug fixes¶
Scikit-build 0.17.2¶
Another small release with fixes for non-MSVC Windows platforms.
Bug fixes¶
Testing¶
Hide a few warnings that are expected in #948.
Scikit-build 0.17.1¶
This is a small release fixing a few bugs; the primary one being a change that was triggering a bug in older FindPython. The unused variable messages have been deactivated to simplify output, as well.
Bug fixes¶
Testing¶
Scikit-build 0.17.0¶
A lot of bug fixes are present in this release, focusing on Windows, PyPy, and cross compiling. We’ve also improved the compatibility with default setuptools behaviors a little, and enabled some things that were previously unavailable, like overriding the build type via the cmake argument environment variables. We’ve expanded our CI matrix to include Windows and macOS PyPy and some Fortran tests on Linux. This release requires Python 3.7+.
Bug fixes¶
Match setuptools behavior for
include_package_data
default. by @vyasr in #873.Misc. fixes for F2PY and PythonExtensions modules by @benbovy in #495.
Provide more useful error if user provides
CMAKE_INSTALL_PREFIX
by @vyasr in #872.Stop assuming that
.pyx
files are in the same directory asCMakeLists.txt
by @vyasr in #871.Allow build type overriding in #902.
Detect PyPy library correctly on Windows by user:gershnik in #904.
Include library for FindPython for better Windows cross-compiles in #913. Thanks to user:maxbachmann for testing.
Fix logic for default generator when cross-compiling for ARM on Windows in #917 by @dlech.
Use f2py’s
get_include
if present in #877.Fix support for cross-compilation exception using
targetLinkLibrariesWithDynamicLookup
by @erykoff in #901.Treat empty
MACOSX_DEPLOYMENT_TARGET
as if it was unset in #918.
Testing¶
Miscellaneous¶
Scikit-build 0.16.7¶
This is expected to be the final release series supporting Python 3.6. 0.17 will require Python 3.7+ and start removing deprecated functionality.
Added
SKBUILD_GNU_SKIP_LOCAL_SYMBOL_EXPORT_OVERRIDE
to disable script in #848, thanks to @aaron-bray and @vyasr.Address a new warning from setuptools in our test suite in #859.
Move to using Ruff, update to Black 23, and use Flynt to move more code to f-strings.
Scikit-build 0.16.6¶
Scikit-build 0.16.5¶
Use cmake module if installed over system installs in #839.
Support setting of
-DCMAKE_SYSTEM_PROCESSOR
if passed for selecting an arch, useful for cross compiling on conda-forge in #843.Fixed a rare encoded error output string on Windows in #842.
Better granularity in extras in #838.
Add test markers for nosetuptoolsscm and isolated (helpful for package distributions building scikit-build itself like conda) in #837.
Scikit-build 0.16.4¶
This releases backports additions for Windows ARM cross-compiling via cibuildwheel from scikit-build-core 0.1.4.
Scikit-build 0.16.3¶
This release fixes logging issues using setuptools 65.6+ affecting our tests.
Pytest 7.2+ is now supported. setup.py <command>
and setup_requires
are deprecated, and tests are marked as such.
Scikit-build 0.16.2¶
This addresses one more small regression with the FindPython change from 0.16.0 that was affecting conda. #793.
Scikit-build 0.16.1¶
This was a quick patch release that fixed a missing Python requires setting and some missing files #790, and addressed a warning from setuptools in the tests.
Ignored distutils warning #785. thanks to @bnavigator.
Scikit-build 0.16.0¶
This release adds support for Python 3.11 and removes support for Python 2.7 and 3.5 (#688). Testing and static checking improved, including being fully statically typed internally (though setuptools is not fully typed, so it is of limited use).
All deprecated setuptools/distutils features are also deprecated in
scikit-build, like the test
command, easy_install
, etc. Editable mode
is still unsupported. Python 3.6 support is deprecated. Older versions of
CMake (<3.15) are not recommended; a future version will remove support for older
CMake’s (along with providing a better mechanism for ensuring a proper CMake is
available). If you need any of these features, please open or find an issue
explaining what and why you need something.
New Features¶
Bug fixes¶
Documentation¶
scikit-build mailing list transitioned to the scikit-build GitHub Discussions board. See #800. * Transitioning away from the mailing list and adopting the GitHub Discussions will provide a more integrated platform enabling us to more effectively engage with the community. * After sending a last message describing the transition, the mailing list was updated to be read-only and the welcome message was updated to redirect visitor toward the Discussions board.
Scikit-build 0.15.0¶
This release is the final (again) release for Python < 3.6 and MSVC<2017. Support for FindPython from CMake 3.12+ was added, including FindPython2. Support for Cygwin added.
New Features¶
Bug fixes¶
Fixed issue with distutils usage in Python 3.10. Thanks to @SuperSandro2000 for the contribution in #700.
Scikit-build 0.14.1¶
This release fixes a regression, and reverts a fix in 0.14.0. Some changes made to CI to fix recent removals.
Bug fixes¶
Fix issue with
SKBUILD_CONFIGURE_OPTIONS
not being read.Reverted manifest install changes.
Scikit-build 0.14.0¶
This is the final release for Python < 3.6 and MSVC<2017.
New Features¶
Bug fixes¶
The manifest install location computation was fixed. Thanks @kratsg for the contribution in #682. (Reverted in 0.14.1)
Byte-compilation was skipped due to a missing return. Thanks @pekkarr in #678.
Packages can now be computed from the same shared collections, before this could confuse Scikit-build. Thanks @vyasr in #675.
Fixed library detection for PyPy 3.9. Thanks @rkaminsk in #673.
Internal¶
Scikit-build 0.13.1¶
This release fixes two bugs affecting Windows. Users should use "ninja;
platform_system!='Windows"
, at least for now, since MSVC ships with Ninja,
and that Ninja is better at finding the matching MSVC than the Python package
is. Including it may slow down the search and force the IDE generator instead,
but will at least no longer discover GCC instead.
Bug fixes¶
Scikit-build 0.13.0¶
This is likely one of the final releases to support Python 2.7 and 3.5; future releases will likely target at least Python 3.6+ and MSCV 2017+.
If you are using scikit-build via pyproject.toml
, please remember to
include setuptools
and wheel
. A future version of scikit-build may
remove the setuptools install-time hard requirement.
New Features¶
CMake module Cython now uses Cython default arguments. This no longer adds
--no-docstrings
in Release and MinSizeRel builds, so Cython docstrings are now retained by default. Additionally,--embed-positions
is no longer added to Debug and RelWithDebInfo builds. Users can enable these and other Cython arguments via the optionCYTHON_FLAGS
. See #518 and #519, thanks to @bdice for the improvement.Experimental support for ARM64 on Windows. Thanks to @gaborkertesz-linaro in #612.
Support for MSVC 2022. Thanks to @tttapa for the contribution in #627.
Support the modern form of
target_link_libraries
, viaSKBUILD_LINK_LIBRARIES_KEYWORD
(somewhat experimental). Thanks to @maxbachmann in #611.
Bug fixes¶
Update the Ninja path if using the
ninja
package. This fixes repeated isolated builds. Further path inspection and updates for isolated builds may be considered in the future. #631, thanks to @RUrlus and @segevfiner for help in tracking this down.Allow OpenBSD to pass the platform check (untested). See #586.
Avoid forcing the min macOS version. Behaviour is now inline with setuptools. Users should set
MACOSX_DEPLOYMENT_TARGET
when building (automatic with cibuildwheel), otherwise you will get the same value Python was compiled with. Note: This may seem like a regression for PyPy until the next release (7.3.8), since it was compiled with 10.7, which is too old to build with on modern macOS - manually setMACOSX_DEPLOYMENT_TARGET
(including setting it if unset in yoursetup.py
) for PyPy until 7.3.8. #607Fix logging issue when using Setuptools 60.2+. #623
MacOS cross compiling support fix (for conda-forge) for built-in modules. Thanks to @isuruf for the contribution in #622.
Better detection of the library path, fixes some issues with PyPy. Thanks to @rkaminsk for the contribution in #620 and #630. PyPy is now part of our testing matrix as of #624. Also @robtaylor in #632.
Fixed issue when cross-compiling on conda-forge (probably upstream bug, but easy to avoid). #646.
Scikit-build 0.12.0¶
The scikit-build GitHub organization welcomes @henryiii and @mayeut as core contributors and maintainers. Both are also maintainers of cibuildwheel.
@henryiii is a pybind11 and pypa/build maintainer, has been instrumental in adding Apple Silicon support, adding support for Visual Studio 2019, updating
the Continuous Integration infrastructure, as well as helping review & integrate contributions, and addressing
miscellaneous issues. Additionally, @henryiii has worked on an example project to build with pybind11
and scikit-build
.
@mayeut is a manylinux maintainer and
focused his effort on updating the cmake-python-distributions
and ninja-python-distributions
so
that the corresponding wheels are available on all supported platforms including Apple Silicon and all flavors
of manylinux.
New Features¶
Support Apple Silicon, including producing Universal2 wheels (#530) and respecting standard setuptools cross-compile variables (#555). Thanks to @YannickJadoul for the contributions.
Support MSVC 2019 without having to run it with the MSVC activation variables, just like 2017 and earlier versions. Thanks to @YannickJadoul for the contribution in #526.
Bug fixes¶
Support
-A
and-T
internally when setting up MSVC generators. Architecture now always passed through-A
to MSVC generators. Thanks @YannickJadoul for the contribution. See #557 and #536.Fixed a regression that caused setuptools to complain about unknown setup option (cmake_process_manifest_hook). Thanks @Jmennius for the contribution. See #498.
If it applies, ensure generator toolset is used to configure the project. Thanks @YannickJadoul for the contributions. See #526.
Read
CYTHON_FLAGS
where needed, instead of once, allowing the user to define multiple modules with different flags. Thanks @oiffrig for the contributions in #536.Avoid an IndexError if prefix was empty. Thanks @dfaure for the contributions in #522.
Documentation¶
Update
Conda: Step-by-step
release guide available in Making a release section.Update links to CMake documentation pages in C Runtime, Compiler and Build System Generator. Thanks @Eothred for the contributions in #508.
Tests¶
Improve and simplify Continuous Integration infrastructure.
Support
nox
for running the tests locally. See #540.Use GitHub Actions for Continuous Integration and remove use of scikit-ci, tox, TravisCI, AppVeyor and CircleCI. See #549, #551 and #552.
Add support for testing against Python 3.10. See #565.
Style checking handled by pre-commit. See #541.
Check for misspellings adding GitHub Actions workflow using codespell. See #541.
Fix linting error F522 reported with flake8 >= 3.8.x. Thanks @benbovy for the contributions. See #494.
Fix regex in tests to support Python 3.10. Thanks @mgorny for the contributions in #544.
Scikit-build 0.11.1¶
Bug fixes¶
Support using scikit-build with conan where
distro<1.2.0
is required. Thanks @AntoinePrv and @Chrismarsh for reporting issues #472 and #488.
Documentation¶
Fix link in
Conda: Step-by-step
release guide available in Making a release section.
Scikit-build 0.11.0¶
New Features¶
Add a hook to process the cmake install manifest building the wheel. The hook function can be specified as an argument to the
setup()
function. This can be used e.g. to prevent installing cmake configuration files, headers, or static libraries with the wheel. Thanks @SylvainCorlay for the contribution. See #473.Add support for passing CMake configure options like
-DFOO:STRING:bar
as globalsetuptools
orpip
options.Add support for building project using PyPy or PyPy3. See https://pypy.org See #407.
Add support for OS/400 (now known as IBM i). Thanks @jwoehr for the contribution. See #444.
Display CMake command used to configure the project. Thanks @native-api for the contribution. See #443.
CMake modules:
Improve CMake module F2PY adding
add_f2py_target()
CMake function allowing to generate*-f2pywrappers.f
and *module.c files from*.pyf
files. Thanks @xoviat for the contribution.Update CMake module PythonExtensions adding
add_python_library()
andadd_python_extension()
. Thanks @xoviat for the contribution.
Bug fixes¶
Fix python 2.7 installation ensuring setuptools < 45 is required. See #478.
Fix unclosed file resource in
skbuild.cmaker.CMaker.check_for_bad_installs()
. Thanks @Nic30 for the suggestion. See #429.Update CMake module PythonExtensions:
Honor the
MACOSX_DEPLOYMENT_TARGET
environment variable if it is defined on macOS. Thanks @certik for the contribution. See #441.Fix CMake module F2PY to ensure the
f2py
executable specific to the python version being used is found. See #449. Thanks @bnavigator for the contribution.Replace
platform.linux_distribution()
which was removed in Python 3.8 by a call todistro.id()
. This adds thedistro
package as dependency. See #458. Thanks @bnavigator for the contribution.
Documentation¶
Tests¶
Update
initialize_git_repo_and_commit
to prevent signing message on system with commit signing enabled globally.
Scikit-build 0.10.0¶
New Features¶
Improve message displayed when discovering a working environment for building projects. For example, instead of displaying
-- Trying "Ninja" generator
, it now displays a message like-- Trying "Ninja (Visual Studio 15 2017 Win64 v140)" generator
.
Bug fixes¶
Checking generator candidates can now handle handle paths and binaries with spaces, so that
setup.py --cmake-executable "C:/Program Files (x86)/cmake/cmake.exe"
works as expected. Contributed by @jokva. See #400.Fix sdist command to ensure symlinks in original source tree are maintained. Contributed by @anibali. See #401.
Ensure use of
bdist_egg
orbdist_rpm
commands trigger build using cmake.Fix default value returned by
skbuild.constants.skbuild_plat_name()
on macOS. See #417.
Internal API¶
Documentation¶
Fix typo in example associated with PythonExtensions. Thanks @eirrgang for the contribution.
Update Making a release section to include
Conda: Step-by-step
release guide.
Tests¶
Introduce
check_sdist_content()
and fix tests that are checking content of sdist to account for changes introduced in Python 3.8 and backported to python 2.7, 3.6 and 3.7. The changes introduced in python/cpython#9419 adds directory entries to ZIP files created by distutils. Thanks @anibali for the contribution. See #404.Fix
check_wheel_content()
to consider changes in0.33.1 < wheel.__version__ < 0.33.4
where directory entries are included when building wheel. See pypa/wheel#294 <https://github.com/pypa/wheel/issues/294>.Fix reporting of
AssertionError
raised incheck_wheel_content()
function by relocating the source code into a dedicated moduletests.pytest_helpers
and by adding aconftest.py
configuration file registering it for pytest assertion rewriting. See https://docs.pytest.org/en/latest/writing_plugins.html#assertion-rewriting and #403.Fix
test_generator_selection
when building with “Visual C++ for Python 2.7” installed for all users. This addresses failure associated withwin_c_compilervs2008cxx_compilervs2008python2.7
when running test in scikit-build-feedstock where “Visual C++ for Python 2.7” is installed using (vcpython27 chocolatey package.Continuous Integration
Add support for Azure Pipelines for Python 3.7 32-bit and 64-bit
AppVeyor: Disable test for Python 3.7 32-bit and 64-bit.
CircleCI: Update version of docker images from jessie to stretch. This addresses issue circleci/circleci-images#370.
TravisCI: Remove obsolete Python 3.4 testing. It reached end-of-life on March 18 2019.
Scikit-build 0.9.0¶
New Features¶
Bug fixes¶
Fix build of wheels if path includes spaces. See issue #375. Thanks @padraic-padraic for the contribution.
Ensure wheel platform name is correctly set when providing custom
CMAKE_OSX_DEPLOYMENT_TARGET
andCMAKE_OSX_ARCHITECTURES
values are provided. Thanks @nonhermitian for the contribution. See #377.Fix testing with recent version of pytest by updating the pytest-runner requirements expression in
setup.py
. Thanks @mackelab for the contribution.
Scikit-build 0.8.1¶
Bug fixes¶
Fix
bdist_wheel
command to supportwheel >= 0.32.0
. Thanks @fbudin69500 for reporting issue #360.
Tests¶
Fix
test_distribution.py
updating use ofPath.files()
and requiringpath.py>=11.5.0
.
Scikit-build 0.8.0¶
New Features¶
Introduced
skbuild.constants.CMAKE_DEFAULT_EXECUTABLE
to facilitate distribution of scikit-build in package manager like Nixpkgs where all paths to dependencies are hardcoded. Suggested by @FRidh.Setup keywords:
If not already set,
zip_safe
option is set toFalse
. Suggested by @blowekamp.
Add support for
--skip-generator-test
when a generator is explicitly selected using--generator
. This allows to speed up overall build when the build environment is known.
Bug fixes¶
Fix support for building project with CMake source directory outside of the
setup.py
directory. See #335 fixed by @massich.Fix reading of
.cmake
files having any character not available in CP-1252 (the default code page on windows). See #334 fixed by @bgermann.Fix parsing of macOS specific arguments like
--plat-name macosx-X.Y-x86_64
and-DCMAKE_OSX_DEPLOYMENT_TARGET:STRING=X.Y
and ensure that the ones specified as command line arguments override the default values or the one hard-coded in thecmake_args
setup keyword. Thanks @yonip for the help addressing #342.Support case where relative directory set in
package_dir
has an ending slash. For example, specifyingpackage_dir={'awesome': 'src/awesome/'},
is now properly handled.Fix support for isolated build environment ensuring the CMake project is reconfigured when
pip install -e .
is called multiple times. See #352.
Documentation¶
README: Update overall download count.
Add logo and update sphinx configuration. Thanks @SteveJordanKW for the design work.
Update CMake installation section. Thanks @thewtex.
Add Support for isolated build section.
Add Optimized incremental build section.
Update usage documentation to specify that
--universal
and--python-tags
have no effect. Thanks @bgermann for the suggestion. See #353.Simplify documentation merging
Extension Build System
section with theAdvanced Usage
section. Thanks @thewtex for the suggestion.
Tests¶
Add
check_wheel_content
utility function.Skip
test_setup_requires_keyword_include_cmake
if running in conda test environment or if https://pypi.org is not reachable. Suggested by @Luthaf.Continuous Integration
TravisCI:
Remove testing of linux now covered by CircleCI, add testing for Python 3.5, 3.6 and 3.7 on macOS.
Ensure system python uses latest version of pip
AppVeyor, CircleCI: Add testing for Python 3.7
Remove uses of unneeded
$<RUN_ENV>
command wrapper. scikit-build should already take care of setting up the expected environment.Always install up-to-date scikit-ci and scikit-ci-addons.
Simplify release process managing
versioning
with python-versioneer and update Making a release documentation.
Scikit-build 0.7.1¶
Documentation¶
Fix description and classifier list in setup.py.
Fix link in README.
Scikit-build 0.7.0¶
New Features¶
Faster incremental build by re-configuring the project only if needed. This was achieved by (1) adding support to retrieve the environment mapping associated with the generator set in the
CMakeCache.txt
file, (2) introducing aCMake spec file
storing the CMake version as well as the the CMake arguments and (3) re-configuring only if either the generator or the CMake specs change. Thanks @xoviat for the contribution. See #301.CMake modules:
CMake module PythonExtensions: Set symbol visibility to export only the module init function. This applies to GNU and MSVC compilers. Thanks @xoviat. See #299.
Add CMake module F2PY useful to find the
f2py
executable for building Python extensions with Fortran. Thanks to @xoviat for moving forward with the integration. Concept for the module comes from the work of @scopatz done in PyNE project. See #273.Update CMake module NumPy setting variables
NumPy_CONV_TEMPLATE_EXECUTABLE
andNumPy_FROM_TEMPLATE_EXECUTABLE
. Thanks @xoviat for the contribution. See #278.
Setup keywords:
Add support for cmake_languages setup keyword.
Add support for
include_package_data
andexclude_package_data
setup keywords as well as parsing ofMANIFEST.in
. See #315. Thanks @reiver-dev for reporting the issue.Add support for
cmake_minimum_required_version
setup keyword. See #312. Suggested by @henryiii.Install cmake if found in
setup_requires
list. See #313. Suggested by @henryiii.
Add support for
--cmake-executable
scikit-build command line option. Thanks @henryborchers for the suggestion. See #317.Use
_skbuild/platform-X.Y
instead of_skbuild
to build package. This allows to have a different build directory for each python version. Thanks @isuruf for the suggestion and @xoviat for contributing the feature. See #283.Run cmake and
develop
command when commandtest
is executed.
Bug fixes¶
Fix support of
--hide-listing
when building wheel.CMake module Cython: Fix escaping of spaces associated with
CYTHON_FLAGS
when provided as command line arguments to the cython executable through CMake cache entries. See #265 fixed by @neok-m4700.Ensure package data files specified in the
setup()
function usingpackage_data
keyword are packaged and installed.Support specifying a default directory for all packages not already associated with one using syntax like
package_dir={'':'src'}
insetup.py
. Thanks @benjaminjack for reporting the issue. See #274.Improve
--skip-cmake
command line option support so that it can re-generate a source distribution or a python wheel without having to run cmake executable to re-configure and build. Thanks to @jonwoodring for reporting the issue on the mailing list.Set
skbuild <version>
as wheel generator. See PEP-0427 and #191.Ensure
MANIFEST.in
is considered when generating source distribution. Thanks @seanlis for reporting the problem and providing an initial patch, and thanks @henryiii for implementing the corresponding test. See #260.Support generation of source distribution for git repository having submodules. This works only for version of git >= 2.11 supporting the
--recurse-submodules
option withls-files
command.
Internal API¶
Python Support¶
Tests using Python 3.3.x were removed and support for this version of python is not guaranteed anymore. Support was removed following the deprecation warnings reported by version 0.31.0 of wheel package, these were causing the tests
test_source_distribution
andtest_wheel
to fail.
Tests¶
Speedup execution of tests that do not require any CMake language enabled. This is achieved by (1) introducing the test project
hello-no-language
, (2) updating test utility functionsexecute_setup_py
andproject_setup_py_test
to accept the optional parameterdisable_languages_test
allowing to skip unneeded compiler detection in test project used to verify that the selected CMake generator works as expected, and (3) updating relevant tests to use the new test project and parameters.Overall testing time on all continuous integration services was reduced:
AppVeyor:
from ~16 to ~7 minutes for 64 and 32-bit Python 2.7 tests done using Visual Studio Express 2008
from more than 2 hours to ~50 minutes for 64 and 32-bit Python 3.5 tests done using Visual Studio 2015. Improvement specific to Python 3.x were obtained by caching the results of slow calls to
distutils.msvc9compiler.query_vcvarsall
(for Python 3.3 and 3.4) anddistutils._msvccompiler._get_vc_env
(for Python 3.5 and above). These functions were called multiple times to create the list ofskbuild.platform_specifics.windows.CMakeVisualStudioCommandLineGenerator
used inskbuild.platform_specifics.windows.WindowsPlatform
.
CircleCI: from ~7 to ~5 minutes.
TravisCI: from ~21 to ~10 minutes.
Update maximum line length specified in flake8 settings from 80 to 120 characters.
Add
prepend_sys_path
utility function.Ensure that the project directory is prepended to
sys.path
when executing test building sample project with the help ofexecute_setup_py
function.Add codecov config file for better defaults and prevent associated Pull Request checks from reporting failure when coverage only slightly changes.
Documentation¶
Improve internal API documentation:
Split usage documentation into a
Basic Usage
andAdvanced Usage
sections.
Cleanups¶
Fix miscellaneous pylint warnings.
Scikit-build 0.6.1¶
Bug fixes¶
Ensure CMake arguments passed to scikit-build and starting with
-DCMAKE_*
are passed to the test project allowing to determine which generator to use. For example, this ensures that arguments like-DCMAKE_MAKE_PROGRAM:FILEPATH=/path/to/program
are passed. See #256.
Documentation¶
Update Making a release section including instructions to update
README.rst
with up-to-date pypi download statistics based on Google big table.
Scikit-build 0.6.0¶
New features¶
Improve
py_modules
support: Python modules generated by CMake are now properly included in binary distribution.Improve developer mode support for
py_modules
generated by CMake.
Bug fixes¶
Do not implicitly install python modules when the beginning of their name match a package explicitly listed. For example, if a project has a package
foo/__init__.py
and a modulefooConfig.py
, and only packagefoo
was listed insetup.py
,fooConfig.py
is not installed anymore.CMake module targetLinkLibrariesWithDynamicLookup: Fix the caching of dynamic lookup variables. See #240 fixed by @blowekamp.
Requirements¶
wheel: As suggested by @thewtex, unpinning version of the package by requiring
>=0.29.0
instead of==0.29.0
will avoid uninstalling a newer version of wheel package on up-to-date system.
Documentation¶
Add a command line CMake Options section to Usage.
Fix table listing Visual Studio IDE version and corresponding with CPython version in C Runtime, Compiler and Build System Generator.
Improve Making a release section.
Tests¶
Extend
test_hello
,test_setup
, andtest_sdist_hide_listing
to (1) check if python modules are packaged into source and wheel distributions and (2) check if python modules are copied into the source tree when developer mode is enabled.
Internal API¶
Fix
skbuild.setuptools_wrap.strip_package()
to handle empty package.Teach
skbuild.command.build_py.build_py.find_modules()
function to look forpy_module
file inCMAKE_INSTALL_DIR
.Teach
skbuild.utils.PythonModuleFinder
to search forpython module
in the CMake install tree.Update
skbuild.setuptools_wrap._consolidate()
to copy file into the CMake tree only if it exists.Update
skbuild.setuptools_wrap._copy_file()
to create directory only if there is one associated with the destination file.
Scikit-build 0.5.1¶
Bug fixes¶
Ensure file copied in “develop” mode have “mode bits” maintained.
Scikit-build 0.5.0¶
New features¶
Improve user experience by running CMake only if needed. See #207
Add support for cmake_with_sdist setup keyword argument.
Add support for
--force-cmake
and--skip-cmake
global setup command-line options.scikit-build conda-forge recipe added by @isuruf. See conda-forge/staged-recipes#1989
Add support for development mode. (#187).
Improved C Runtime, Compiler and Build System Generator selection:
If available, uses Ninja build system generator on all platforms. An advantages is that ninja automatically parallelizes the build based on the number of CPUs.
Automatically set the expected
Visual Studio
environment whenNinja
orNMake Makefiles
generators are used.Support Microsoft Visual C++ Compiler for Python 2.7. See #216.
Prompt for user to install the required compiler if it is not available. See #27.
Improve targetLinkLibrariesWithDynamicLookup CMake Module extending the API of
check_dynamic_lookup
function:
Update long signature:
<LinkFlagsVar>
is now optionalAdd support for short signature:
check_dynamic_lookup(<ResultVar>)
. See SimpleITK/SimpleITK#80.
Bug fixes¶
Documentation¶
add C Runtime, Compiler and Build System Generator section
add Release Notes section
allow github issues and users to easily be referenced using
:issue:`XY`
and:user:`username`
markups. This functionality is enabled by the sphinx-issue sphinx extensionmake_a_release: Ensure uploaded distributions are signed
usage:
Add empty cross-compilation / wheels building sections
Add Setup options section
hacking:
Add Internal API section generated using
sphinx-apidoc
.Add Internal CMake Modules to document targetLinkLibrariesWithDynamicLookup CMake module.
Requirements¶
setuptools: As suggested by @mivade in #212, remove the hard requirement for
==28.8.0
and require version>= 28.0.0
. This allows to “play” nicely with conda where it is problematic to update the version of setuptools. See pypa/pip#2751 and ContinuumIO/anaconda-issues#542.
Tests¶
Improve “push_dir” tests to not rely on build directory name. Thanks @isuruf for reporting the issue.
travis/install_pyenv: Improve MacOSX build time updating scikit-ci-addons
Add
get_cmakecache_variables
utility function.
Internal API¶
skbuild.cmaker.CMaker.configure()
: Change parameter name fromgenerator_id
togenerator_name
. This is consistent with how generator are identified in CMake documentation. This change breaks backward compatibility.skbuild.platform_specifics.abstract.CMakePlatform.get_best_generator()
: Change parameter name fromgenerator
togenerator_name
. Note that this function is also directly importable fromskbuild.platform_specifics
. This change breaks backward compatibility.skbuild.platform_specifics.abstract.CMakeGenerator
: This class allows to handle generators as sophisticated object instead of simple string. This is done anticipating the support for CMAKE_GENERATOR_PLATFORM and CMAKE_GENERATOR_TOOLSET. Note also that the class is directly importable fromskbuild.platform_specifics
and is now returned byskbuild.platform_specifics.get_best_generator()
. This change breaks backward compatibility.
Cleanups¶
appveyor.yml:
Remove unused “on_failure: event logging” and “notifications: GitHubPullRequest”
Remove unused SKIP env variable
Scikit-build 0.4.0¶
New features¶
Add support for
--hide-listing
option
allow to build distributions without displaying files being included
useful when building large project on Continuous Integration service limiting the amount of log produced by the build
CMake module:
skbuild/resources/cmake/FindPythonExtensions.cmake
Function
python_extension_module
: add support for module suffix
Bug fixes¶
Do not package python modules under “purelib” dir in non-pure wheel
CMake module:
skbuild/resources/cmake/targetLinkLibrariesWithDynamicLookup.cmake
:
Fix the logic checking for cross-compilation (the regression was introduced by #51 and #47
It configure the text project setting CMAKE_ENABLE_EXPORTS to ON. Doing so ensure the executable compiled in the test exports symbols (if supported by the underlying platform)
Docs¶
Add short note explaining how to include scikit-build CMake module
Move “Controlling CMake using scikit-build” into a “hacking” section
Add initial version of “extension_build_system” documentation
Tests¶
tests/samples: Simplify project removing unneeded install rules and file copy
Simplify continuous integration
use scikit-ci and scikit-ci-addons
speed up build setting up caching
Makefile:
Fix
coverage
targetAdd
docs-only
target allowing to regenerate the Sphinx documentation without opening a new page in the browser.
Scikit-build 0.3.0¶
New features¶
Improve support for “pure”, “CMake” and “hybrid” python package
a “pure” package is a python package that have all files living in the project source tree
an “hybrid” package is a python package that have some files living in the project source tree and some files installed by CMake
a “CMake” package is a python package that is fully generated and installed by CMake without any of his files existing in the source tree
Add support for source distribution. See #84
Add support for setup arguments specific to scikit-build:
cmake_args
: additional option passed to CMake
cmake_install_dir
: relative directory where the CMake project being built should be installed
cmake_source_dir
: location of the CMake project
Add CMake module
FindNumPy.cmake
Automatically set
package_dir
to reasonable defaultsSupport building project without CMakeLists.txt
Bug fixes¶
Documentation¶
Improvement of documentation published on http://scikit-build.readthedocs.io/en/latest/
Add docstrings for most of the modules, classes and functions
Tests¶
Ensure each test run in a dedicated temporary directory
Add tests to raise coverage from 70% to 91%
Refactor CI testing infrastructure introducing CI drivers written in python for AppVeyor, CircleCI and TravisCI
Switch from
nose
topy.test
Relocate sample projects into a dedicated home: https://github.com/scikit-build/scikit-build-sample-projects
Cleanups¶
Refactor commands introducing
set_build_base_mixin
andnew_style
Remove unused code
History¶
PyCMake was created at SciPy 2014 in response to general difficulties building C++ and Fortran based Python extensions across platforms. It was renamed to “scikit-build” in 2016.
Making a release¶
A core developer should use the following steps to create a release X.Y.Z
of
scikit-build on PyPI and Conda.
Prerequisites¶
All CI tests are passing on GitHub Actions and Azure Pipelines.
You have a GPG signing key.
Documentation conventions¶
The commands reported below should be evaluated in the same terminal session.
Commands to evaluate starts with a dollar sign. For example:
$ echo "Hello"
Hello
means that echo "Hello"
should be copied and evaluated in the terminal.
Setting up environment¶
First, register for an account on PyPI.
If not already the case, ask to be added as a
Package Index Maintainer
.Create a
~/.pypirc
file with your login credentials:[distutils] index-servers = pypi pypitest [pypi] username=<your-username> password=<your-password> [pypitest] repository=https://test.pypi.org/legacy/ username=<your-username> password=<your-password>
where
<your-username>
and<your-password>
correspond to your PyPI account.
PyPI: Step-by-step¶
Make sure that all CI tests are passing on GitHub Actions and Azure Pipelines.
Download the latest sources (or use an existing git checkout)
$ cd /tmp && \ git clone git@github.com:scikit-build/scikit-build && \ cd scikit-build
List all tags sorted by creation date
$ git tag -l --sort creatordate
Choose the next release version number
$ release=X.Y.ZWarning
To ensure the packages are uploaded on PyPI, tags must match this regular expression:
^[0-9]+(\.[0-9]+)*(\.post[0-9]+)?$
.
In
CHANGES.rst
replaceNext Release
section header withScikit-build X.Y.Z
and commit the changes.
$ git add CHANGES.rst && \ git commit -m "Scikit-build $release"
Tag the release
$ git tag --sign -m "Scikit-build $release" $release mainWarning
We recommend using a GPG signing key to sign the tag.
Publish both the release tag and the main branch
$ git push origin $release && \ git push origin main
Make a GitHub release. Paste the converted release notes as markdown; convert using
cat CHANGES.rst | pandoc -f rst -t gfmand then edit the result (it will not be perfect) to prepare the body of the release. You can also try clipboardtomarkdown or copying to a draft discord post. PRs should be converted to simple
#<number>
form. Be sure to use the tag you just pushed as the tag version, andScikit-build X.Y.Z
should be the name.Note
For examples of releases, see https://github.com/scikit-build/scikit-build/releases
Add a
Next Release
section back inCHANGES.rst
, commit and push local changes.
$ git add CHANGES.rst && \ git commit -m "CHANGES.rst: Add \"Next Release\" section [ci skip]" && \ git push origin main
Add an entry to the
Announcements
category of the scikit-build discussions board.
Note
For examples of announcements, see https://github.com/orgs/scikit-build/discussions/categories/announcements
Conda: Step-by-step¶
Warning
Publishing on conda requires to have corresponding the corresponding Github release.
After a GitHub release is created in the scikit-build project and after the conda-forge Autoticking Bot creates a pull request on the scikit-build-feedstock , follow these steps to finalize the conda package release:
Review the pull-request
Merge pull-request
In case the bot failed (e.g because of GH rate limitation) and in order to explicitly release a new version on conda-forge, follow the steps below:
Choose the next release version number (that matches with the PyPI version last published)
$ release=X.Y.Z
Fork scikit-build-feedstock
First step is to fork scikit-build-feedstock repository. This is the recommended best practice by conda.
Clone forked feedstock
Fill the YOURGITHUBUSER part.
$ YOURGITHUBUSER=user $ cd /tmp && git clone https://github.com/$YOURGITHUBUSER/scikit-build-feedstock.git
Download corresponding source for the release version
$ cd /tmp && \ wget https://github.com/scikit-build/scikit-build/archive/$release.tar.gz
Create a new branch
$ cd scikit-build-feedstock && \ git checkout -b $release
Modify
meta.yaml
Update the version string and sha256.
We have to modify the sha and the version string in the
meta.yaml
file.For linux flavors:
$ sed -i "1s/.*/{% set version = \"$release\" %}/" recipe/meta.yaml && \ sha=$(openssl sha256 /tmp/$release.tar.gz | awk '{print $2}') && \ sed -i "2s/.*/{% set sha256 = \"$sha\" %}/" recipe/meta.yaml
For macOS:
$ sed -i -- "1s/.*/{% set version = \"$release\" %}/" recipe/meta.yaml && \ sha=$(openssl sha256 /tmp/$release.tar.gz | awk '{print $2}') && \ sed -i -- "2s/.*/{% set sha256 = \"$sha\" %}/" recipe/meta.yaml
Commit local changes.
$ git add recipe/meta.yaml && \ git commit -m "scikit-build v$release version"
Push the changes
$ git push origin $release
Create a Pull Request
Create a pull request against the main repository. If the tests are passed a new release will be published on Anaconda cloud.
Indices and tables¶
Publications¶
Please use the first citation when referencing scikit-build in scientific publications.
Jean-Christophe Fillion-Robin, Matt McCormick, Omar Padron, Max Smolens, Michael Grauer, & Michael Sarahan. (2018, July 13). jcfr/scipy_2018_scikit-build_talk: SciPy 2018 Talk | scikit-build: A Build System Generator for CPython C/C++/Fortran/Cython Extensions. Zenodo. https://doi.org/10.5281/zenodo.2565368
Schreiner, Henry, Rickerby, Joe, Grosse-Kunstleve, Ralf, Jakob, Wenzel, Darbois, Matthieu, Gokaslan, Aaron, Fillion-Robin, Jean-Christophe, & McCormick, Matt. (2022, August 1). Building Binary Extensions with pybind11, scikit-build, and cibuildwheel. https://doi.org/10.25080/majora-212e5952-033
History¶
PyCMake was created at SciPy 2014 in response to general difficulties building C++ and Fortran based Python extensions across platforms. It was renamed to “scikit-build” in 2016. Scikit-build-core was started in 2022.
Known Issues¶
These issues are likely to be addressed in upcoming releases, and are already addressed in scikit-build-core.
Editable installs do not work with the latest versions of Setuptools (and had issues with older versions, too).
Configuration scikit-build cares about _must_ be specified in
setup()
currently.The cache directory (
_skbuild
) may need to be deleted between builds in some cases (like rebuilding with a different Python interpreter).AIX requires a newer version of CMake than the IBM-supplied CMake 3.22.0 from the AIX Toolbox for Open Source Software. We currently recommend building CMake from source on AIX.
We are also working on improving scikit-build, so there are some upcoming changes and deprecations:
All deprecated setuptools/distutils features are also deprecated in scikit-build, like the
test
command,easy_install
, etc.Older versions of CMake (<3.15) are not recommended; a future version will remove support for older CMake’s (along with providing a better mechanism for ensuring a proper CMake is available).
If you need any of these features, please open or find an issue explaining what and why you need something.
Miscellaneous¶
Free software: MIT license
Documentation: http://scikit-build.readthedocs.org
Source code: https://github.com/scikit-build/scikit-build
Discussions: https://github.com/orgs/scikit-build/discussions
Scikit-build-core: https://github.com/scikit-build/scikit-build-core
Support for this work was provided by NSF grant OAC-2209877.