CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-cibuildwheel

Build Python wheels on CI with minimal configuration.

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

configuration.mddocs/

Configuration

Cibuildwheel provides a comprehensive configuration system supporting TOML files, environment variables, and command-line options with validation and schema support.

Capabilities

Options Container

Main container for all build configuration options.

@dataclasses.dataclass(frozen=True, kw_only=True)
class Options:
    globals: GlobalOptions
    
    def build_options(self, identifier: str) -> BuildOptions:
        """
        Get build-specific options for a given build identifier.
        
        Args:
            identifier: Build identifier (e.g., 'cp311-linux_x86_64')
            
        Returns:
            BuildOptions instance with configuration for this build
        """
    
    def check_for_invalid_configuration(self, identifiers: Sequence[str]) -> None:
        """
        Validate configuration against actual build identifiers.
        
        Args:
            identifiers: List of build identifiers that will be built
            
        Raises:
            ValueError: If configuration contains invalid settings
        """
    
    def summary(self, identifiers: Sequence[str]) -> str:
        """
        Generate a human-readable summary of the configuration.
        
        Args:
            identifiers: List of build identifiers
            
        Returns:
            Formatted string summarizing the build configuration
        """

Global Options

Configuration that applies to all builds.

@dataclasses.dataclass(frozen=True, kw_only=True)
class GlobalOptions:
    package_dir: Path
    output_dir: Path
    build_selector: BuildSelector
    test_selector: TestSelector
    architectures: set[Architecture]
    allow_empty: bool

Build Options

Configuration specific to individual builds.

@dataclasses.dataclass(frozen=True, kw_only=True)
class BuildOptions:
    globals: GlobalOptions
    environment: ParsedEnvironment
    build_frontend: BuildFrontendConfig
    dependency_constraints: DependencyConstraints | None
    before_all: str
    before_build: str
    repair_wheel_command: str | None
    test_command: str
    test_requires: list[str]
    test_extras: str
    config_settings: dict[str, str | list[str]]
    # ... many more build-specific options

Command Line Arguments

Parsed command-line arguments structure.

@dataclasses.dataclass(kw_only=True)
class CommandLineArguments:
    platform: Literal["auto", "linux", "macos", "windows"] | None
    archs: str | None
    output_dir: Path
    only: str | None
    config_file: str
    package_dir: Path
    print_build_identifiers: bool
    allow_empty: bool
    debug_traceback: bool
    enable: list[str]
    clean_cache: bool

Options Computation

Main function for computing final options from all sources.

def compute_options(
    platform: PlatformName, 
    command_line_arguments: CommandLineArguments, 
    env: Mapping[str, str]
) -> Options:
    """
    Compute final build options from all configuration sources.
    
    Args:
        platform: Target platform name
        command_line_arguments: Parsed CLI arguments
        env: Environment variables
        
    Returns:
        Complete Options object with resolved configuration
        
    Raises:
        ConfigurationError: If configuration is invalid or conflicting
    """

Build Frontend Configuration

Configuration for the tool used to build wheels.

BuildFrontendName = Literal["pip", "build", "build[uv]"]

@dataclasses.dataclass(frozen=True)
class BuildFrontendConfig:
    name: BuildFrontendName
    args: Sequence[str] = ()

Configuration Sources

TOML Configuration Files

Primary configuration method using pyproject.toml or dedicated config files:

[tool.cibuildwheel]
# Build selection
build = "cp39-* cp310-* cp311-*"
skip = "*-win32 *-linux_i686"

# Build customization  
build-frontend = "build"
config-settings = {cmake.define.BUILD_TESTING = "OFF"}

# Environment variables
environment = {CFLAGS = "-O2", LDFLAGS = "-s"}

# Testing
test-command = "pytest {project}/tests"
test-requires = ["pytest", "numpy"]

# Platform-specific overrides
[tool.cibuildwheel.linux]
before-all = "yum install -y cmake"
manylinux-x86_64-image = "manylinux2014"

[tool.cibuildwheel.windows]
before-build = "pip install delvewheel"

[tool.cibuildwheel.macos]
archs = ["universal2"]

Environment Variables

Configuration via environment variables with CIBW_ prefix:

# Build selection
export CIBW_BUILD="cp39-* cp310-* cp311-*"
export CIBW_SKIP="*-win32 *-linux_i686"

# Build customization
export CIBW_BUILD_FRONTEND="build"
export CIBW_ENVIRONMENT="CFLAGS=-O2 LDFLAGS=-s"

# Testing  
export CIBW_TEST_COMMAND="pytest {project}/tests"
export CIBW_TEST_REQUIRES="pytest numpy"

# Platform-specific (Linux example)
export CIBW_BEFORE_ALL_LINUX="yum install -y cmake"
export CIBW_MANYLINUX_X86_64_IMAGE="manylinux2014"

Command Line Options

Override configuration via command-line arguments:

cibuildwheel \
  --platform linux \
  --archs x86_64,aarch64 \
  --output-dir wheelhouse \
  --config-file custom-build.toml

Configuration Hierarchy

Configuration sources are merged in this priority order (highest to lowest):

  1. Command-line arguments
  2. Environment variables
  3. TOML configuration files
  4. Default values

Platform-Specific Overrides

Platform-specific settings override global settings:

[tool.cibuildwheel]
# Global setting
build = "cp39-* cp310-* cp311-*"

[tool.cibuildwheel.linux]  
# Linux override - adds cp312
build = "cp39-* cp310-* cp311-* cp312-*"

[tool.cibuildwheel.windows]
# Windows override - removes cp39
build = "cp310-* cp311-*"

Key Configuration Options

Build Selection

[tool.cibuildwheel]
# Python versions to build
build = "cp39-* cp310-* cp311-*"

# Python versions/platforms to skip
skip = ["*-win32", "*-linux_i686", "pp*"]

# Enable additional build categories
enable = ["pypy", "graalpy"]

# Allow empty build selection
allow-empty = true

# Project's Python compatibility
project-requires-python = ">=3.9"

Build Customization

[tool.cibuildwheel]
# Build tool selection
build-frontend = {name = "build", args = ["--installer", "uv"]}

# Build backend config settings
config-settings = "cmake.define.BUILD_TESTING=OFF"

# Environment variables for builds
environment = {CFLAGS = "-O2", LDFLAGS = "-s"}

# Environment variables to pass from host
environment-pass = ["SECRET_TOKEN", "API_KEY"]

# Commands to run before builds
before-all = "yum install -y cmake"
before-build = "pip install cython"

# Custom wheel repair command
repair-wheel-command = "auditwheel repair -w {dest_dir} {wheel}"

Testing Configuration

[tool.cibuildwheel]
# Test command template
test-command = "pytest {project}/tests"

# Test dependencies
test-requires = ["pytest", "numpy", "scipy"]

# Test extras (optional dependencies)
test-extras = ["test", "docs"]

# Skip tests for certain builds
test-skip = ["*-linux_ppc64le", "*-linux_s390x"]

Container Configuration (Linux)

[tool.cibuildwheel.linux]
# Custom container images
manylinux-x86_64-image = "quay.io/pypa/manylinux2014_x86_64"
musllinux-x86_64-image = "quay.io/pypa/musllinux_1_1_x86_64"

# Container engine selection
container-engine = "docker"  # or "podman"

Schema Validation

Schema Access

Access the JSON schema for configuration validation.

def get_schema(tool_name: str = "cibuildwheel") -> dict[str, Any]:
    """
    Get the JSON schema for cibuildwheel configuration.
    
    Args:
        tool_name: Name of the tool section in pyproject.toml
        
    Returns:
        JSON schema dictionary for validation
    """

PyProject.toml Integration

Cibuildwheel provides a schema entry point for validate-pyproject:

# Entry point: validate_pyproject.tool_schema
"cibuildwheel" = "cibuildwheel.schema:get_schema"

IDE Integration

Many IDEs can use the schema for autocomplete and validation:

{
  "$schema": "https://json.schemastore.org/pyproject.json",
  "tool": {
    "cibuildwheel": {
      "build": "cp39-* cp310-* cp311-*"
    }
  }
}

Advanced Configuration

Dynamic Configuration

# Use environment variables for dynamic config
import os
import sys

# Conditional builds based on CI environment
if os.environ.get("CI_QUICK_BUILD"):
    CIBW_BUILD = f"cp{sys.version_info.major}{sys.version_info.minor}-*"
else:
    CIBW_BUILD = "cp39-* cp310-* cp311-*"

Multi-Stage Configuration

[tool.cibuildwheel]
# Base configuration
build = "cp39-* cp310-* cp311-*"
test-command = "pytest"

# Development profile
[tool.cibuildwheel.dev]
build = "cp311-*"  # Only current version
test-skip = "*"    # Skip tests
archs = "native"   # Native arch only

# Release profile  
[tool.cibuildwheel.release]
build = "*"        # All versions
enable = ["pypy"]  # Include PyPy
test-command = "pytest --cov"

Configuration Validation

from cibuildwheel.options import compute_options, CommandLineArguments
from cibuildwheel.errors import ConfigurationError

try:
    options = compute_options(
        platform="linux",
        command_line_arguments=args,
        env=os.environ
    )
    # Configuration is valid
except ConfigurationError as e:
    print(f"Configuration error: {e}")

Configuration Examples

Minimal Configuration

[tool.cibuildwheel]
build = "cp311-*"
test-command = "python -m pytest"

Full-Featured Configuration

[tool.cibuildwheel]
# Build all recent Python versions
build = "cp39-* cp310-* cp311-* cp312-*"
skip = ["*-win32", "*-linux_i686"]  # Skip 32-bit
enable = ["pypy"]

# Build customization
build-frontend = "build"
environment = {CFLAGS = "-O2"}
before-build = "pip install cython numpy"

# Testing
test-command = "pytest {project}/tests -x -v"
test-requires = ["pytest", "pytest-xdist"]
test-extras = ["test"]

# Platform overrides
[tool.cibuildwheel.linux]
before-all = "yum install -y cmake gcc-c++"
manylinux-x86_64-image = "manylinux2014"

[tool.cibuildwheel.macos]
archs = ["universal2"]
environment = {MACOSX_DEPLOYMENT_TARGET = "10.14"}

[tool.cibuildwheel.windows]
before-build = "pip install delvewheel"

Install with Tessl CLI

npx tessl i tessl/pypi-cibuildwheel

docs

architecture.md

build-selection.md

ci-integration.md

cli.md

configuration.md

environment.md

errors.md

index.md

platforms.md

utilities.md

tile.json