Improved build system generator for Python C/C++/Fortran/Cython extensions
—
Custom setuptools command classes that extend standard distutils/setuptools commands with CMake integration. These commands handle the build process orchestration between Python packaging and CMake, providing seamless integration of compiled extensions into Python packages.
Base mixin class that provides common functionality for overriding setuptools command behavior.
class set_build_base_mixin:
"""
Mixin class for overriding distutils and setuptools commands.
Provides functionality to modify build_base directory and other
common command behaviors across different setuptools commands.
"""Extended versions of core setuptools build commands with CMake integration for handling compiled extensions.
class build:
"""
Custom build command with CMake integration.
Extends distutils.command.build to coordinate CMake builds with
Python package building, handling the overall build orchestration.
"""
class build_py:
"""
Custom build_py command for Python modules.
Extends setuptools build_py to handle Python modules alongside
CMake-built extensions, ensuring proper integration of pure Python
and compiled components.
"""
class build_ext:
"""
Custom build_ext command for C/C++ extensions.
Replaces the standard setuptools build_ext with CMake-based building,
allowing complex C/C++/Fortran extensions to be built using CMake
instead of distutils compilation.
"""Enhanced installation commands that handle both Python packages and CMake-built extensions.
class install:
"""
Custom install command with CMake support.
Extends setuptools install command to handle installation of
CMake-built extensions alongside Python packages, managing
the complete installation process.
"""
class install_lib:
"""
Custom install_lib command for library installation.
Handles installation of Python libraries and CMake-built shared
libraries, ensuring proper placement and permissions.
"""
class install_scripts:
"""
Custom install_scripts command for script installation.
Manages installation of Python scripts and any executable files
generated by the CMake build process.
"""Commands for creating distributable packages that include CMake-built components.
class sdist:
"""
Custom sdist command for source distributions.
Creates source distributions that include CMake files, build
configurations, and all necessary components for building
extensions from source.
"""
class bdist:
"""
Custom bdist command for binary distributions.
Creates binary distributions containing pre-built extensions
and properly configured Python packages.
"""
class bdist_wheel:
"""
Custom bdist_wheel command for wheel distributions.
Generates wheel files that include CMake-built extensions with
proper platform tags and dependency information.
"""Commands for cleaning build artifacts and managing project state.
class clean:
"""
Custom clean command for build cleanup.
Removes CMake build directories, generated files, and other
build artifacts in addition to standard Python build cleanup.
"""Commands for generating package metadata and information.
class egg_info:
"""
Custom egg_info command for package metadata.
Generates package metadata that includes information about
CMake-built extensions and their dependencies.
"""
class generate_source_manifest:
"""
Custom command for generating source manifest files.
Creates manifest files that track all source files including
CMake configuration, build scripts, and extension sources.
"""from skbuild.command import build, clean
from setuptools import Distribution
# Create a distribution for command execution
dist = Distribution({
'name': 'my-extension',
'cmake_source_dir': 'src'
})
# Execute build command
build_cmd = build(dist)
build_cmd.finalize_options()
build_cmd.run()
# Execute clean command
clean_cmd = clean(dist)
clean_cmd.finalize_options()
clean_cmd.run()from skbuild import setup
from skbuild.command import build_ext
class CustomBuildExt(build_ext):
"""Custom build_ext with additional functionality."""
def run(self):
# Custom pre-build steps
print("Performing custom pre-build operations...")
# Call parent build_ext
super().run()
# Custom post-build steps
print("Performing custom post-build operations...")
setup(
name="custom-extension",
cmdclass={'build_ext': CustomBuildExt},
cmake_source_dir="native"
)Commands can be invoked directly from the command line when using scikit-build:
# Build the project
python setup.py build
# Build only extensions
python setup.py build_ext
# Clean build artifacts
python setup.py clean --all
# Create source distribution
python setup.py sdist
# Create wheel distribution
python setup.py bdist_wheel
# Install the package
python setup.py installfrom skbuild import setup
setup(
name="advanced-extension",
# Command class customization
cmdclass={
'build': CustomBuild,
'clean': CustomClean,
},
# Command options
options={
'build': {
'build_base': 'custom_build',
},
'build_ext': {
'parallel': 4, # Parallel builds
},
'bdist_wheel': {
'universal': False, # Platform-specific wheels
}
},
cmake_source_dir="src",
cmake_args=["-DCMAKE_BUILD_TYPE=Release"]
)from skbuild.command import build, build_ext, install
from setuptools import Distribution
class CoordinatedBuild:
"""Coordinate multiple build commands."""
def __init__(self, dist):
self.dist = dist
def build_all(self):
"""Execute build commands in proper order."""
# Build Python modules first
build_py_cmd = self.dist.get_command_class('build_py')(self.dist)
build_py_cmd.ensure_finalized()
build_py_cmd.run()
# Build extensions
build_ext_cmd = build_ext(self.dist)
build_ext_cmd.ensure_finalized()
build_ext_cmd.run()
# Overall build coordination
build_cmd = build(self.dist)
build_cmd.ensure_finalized()
build_cmd.run()
# Usage
dist = Distribution({'name': 'coordinated-build'})
builder = CoordinatedBuild(dist)
builder.build_all()from skbuild.command import build_ext
from skbuild.exceptions import SKBuildError
class SafeBuildExt(build_ext):
"""Build command with comprehensive error handling."""
def run(self):
try:
super().run()
except SKBuildError as e:
print(f"Build failed: {e}")
# Attempt recovery or provide helpful messages
if "generator" in str(e).lower():
print("Try: python setup.py build_ext --generator 'Unix Makefiles'")
elif "cmake" in str(e).lower():
print("Try: python setup.py build_ext --cmake-executable /path/to/cmake")
raise
except Exception as e:
print(f"Unexpected error during build: {e}")
print("Please check CMakeLists.txt and build configuration")
raise
setup(
name="safe-extension",
cmdclass={'build_ext': SafeBuildExt}
)Install with Tessl CLI
npx tessl i tessl/pypi-scikit-build