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

environment.mddocs/

Environment Handling

Cibuildwheel provides advanced environment variable parsing with bash syntax support and context-aware evaluation for comprehensive build customization.

Capabilities

Environment Parsing

Parse environment variable specifications from configuration strings.

def parse_environment(env_string: str) -> ParsedEnvironment:
    """
    Parse environment variable specification string.
    
    Args:
        env_string: Environment specification (e.g., "VAR1=value1 VAR2=value2")
        
    Returns:
        ParsedEnvironment object containing parsed assignments
        
    Raises:
        EnvironmentParseError: If parsing fails due to syntax errors
    """

Parsed Environment Container

Container for environment variable assignments with evaluation capabilities.

@dataclasses.dataclass(kw_only=True)
class ParsedEnvironment:
    assignments: list[EnvironmentAssignment]
    
    def as_dictionary(
        self, 
        prev_environment: Mapping[str, str], 
        executor: bashlex_eval.EnvironmentExecutor | None = None
    ) -> dict[str, str]:
        """
        Convert parsed environment to a dictionary with evaluated values.
        
        Args:
            prev_environment: Existing environment variables for context
            executor: Optional bash expression executor
            
        Returns:
            Dictionary of environment variable names to evaluated values
        """
    
    def add(self, name: str, value: str, prepend: bool = False) -> None:
        """
        Add a new environment variable assignment.
        
        Args:
            name: Variable name
            value: Variable value (can contain expressions)
            prepend: If True, add to beginning of assignments list
        """

Environment Assignment Interface

Protocol defining how environment assignments are evaluated.

class EnvironmentAssignment(Protocol):
    name: str
    
    def evaluated_value(
        self, 
        *, 
        environment: Mapping[str, str], 
        executor: bashlex_eval.EnvironmentExecutor | None = None
    ) -> str:
        """
        Evaluate the assignment value in the given environment context.
        
        Args:
            environment: Current environment variables
            executor: Optional bash expression executor
            
        Returns:
            Evaluated string value
        """

Assignment Types

Different types of environment variable assignments.

class EnvironmentAssignmentRaw:
    """Simple string assignment without expression evaluation."""
    name: str
    value: str

class EnvironmentAssignmentBash:
    """Assignment with bash expression evaluation support."""
    name: str
    value: str

Environment Parse Error

Exception raised when environment parsing fails.

class EnvironmentParseError(Exception):
    """Raised when environment variable parsing fails."""

Environment Specification Syntax

Simple Assignments

# Basic key=value pairs
env_string = "CFLAGS=-O2 LDFLAGS=-s DEBUG=1"

# With quotes for values containing spaces
env_string = 'CFLAGS="-O2 -g" DESCRIPTION="My Package"'

Bash Expression Support

# Variable expansion
env_string = "PATH=$PATH:/usr/local/bin HOME_BIN=$HOME/bin"

# Command substitution
env_string = "VERSION=$(python setup.py --version) BUILD_DATE=$(date)"

# Conditional expressions
env_string = "CFLAGS=${CFLAGS:--O2} DEBUG=${DEBUG:-0}"

Multi-line Specifications

# Line continuation
env_string = """
CFLAGS=-O2 \\
LDFLAGS=-s \\
DEBUG=1
"""

# Multiple assignments
env_string = """
CC=gcc
CXX=g++
CFLAGS=-O2 -g
LDFLAGS=-s
"""

Configuration Methods

TOML Configuration

[tool.cibuildwheel]
# Simple environment variables
environment = {CFLAGS = "-O2", LDFLAGS = "-s", DEBUG = "1"}

# With bash expressions
environment = {
    PATH = "$PATH:/usr/local/bin",
    VERSION = "$(python setup.py --version)",
    BUILD_TYPE = "${BUILD_TYPE:-release}"
}

# Platform-specific environments
[tool.cibuildwheel.linux]
environment = {
    CC = "gcc",
    CXX = "g++",
    CFLAGS = "-O2 -fPIC"
}

[tool.cibuildwheel.windows]  
environment = {
    CC = "cl.exe",
    CXX = "cl.exe",
    CFLAGS = "/O2"
}

Environment Variables

# Single assignment
export CIBW_ENVIRONMENT="CFLAGS=-O2"

# Multiple assignments
export CIBW_ENVIRONMENT="CFLAGS=-O2 LDFLAGS=-s DEBUG=1"

# With bash expressions
export CIBW_ENVIRONMENT="PATH=\$PATH:/usr/local/bin VERSION=\$(python setup.py --version)"

# Platform-specific
export CIBW_ENVIRONMENT_LINUX="CC=gcc CXX=g++"
export CIBW_ENVIRONMENT_WINDOWS="CC=cl.exe CXX=cl.exe"

String Format

# Space-separated key=value pairs
"CFLAGS=-O2 LDFLAGS=-s DEBUG=1"

# Quoted values for spaces
'CFLAGS="-O2 -g" DESCRIPTION="My Package"'

# Bash expressions
"PATH=$PATH:/usr/local/bin VERSION=$(python setup.py --version)"

Environment Pass-Through

Host Environment Variables

Pass specific environment variables from the host to the build environment:

[tool.cibuildwheel]
# Pass through authentication tokens
environment-pass = ["API_TOKEN", "SECRET_KEY", "GITHUB_TOKEN"]

# Platform-specific pass-through
[tool.cibuildwheel.linux]
environment-pass = ["DOCKER_HOST", "DOCKER_CERT_PATH"]
# Via environment variable
export CIBW_ENVIRONMENT_PASS="API_TOKEN SECRET_KEY GITHUB_TOKEN"
export CIBW_ENVIRONMENT_PASS_LINUX="DOCKER_HOST DOCKER_CERT_PATH"

CI Environment Detection

Automatically pass common CI environment variables:

# Common CI variables that are often needed:
CI_VARS = [
    "CI", "GITHUB_ACTIONS", "GITHUB_TOKEN", "GITHUB_REF",
    "TRAVIS", "TRAVIS_TAG", "TRAVIS_BRANCH", 
    "APPVEYOR", "APPVEYOR_REPO_TAG_NAME",
    "AZURE_PIPELINES", "BUILD_SOURCEBRANCH"
]

Advanced Environment Features

Dynamic Environment Generation

import os
from cibuildwheel.environment import parse_environment

# Generate environment based on conditions
if os.environ.get("DEBUG"):
    env_string = "CFLAGS=-g -O0 DEBUG=1"
else:
    env_string = "CFLAGS=-O2 -DNDEBUG DEBUG=0"

parsed_env = parse_environment(env_string)

Environment Inheritance and Merging

# Base environment
base_env = parse_environment("CC=gcc CFLAGS=-O2")

# Add platform-specific variables
if platform == "linux":
    base_env.add("LDFLAGS", "-s")
elif platform == "windows":
    base_env.add("CC", "cl.exe")

Build-Specific Environment Variables

Cibuildwheel provides special variables during builds:

  • {project}: Path to the project being built
  • {package}: Path to the package directory
  • {wheel}: Path to the built wheel (in repair commands)
  • {dest_dir}: Destination directory for repaired wheels
[tool.cibuildwheel]
# Use in test commands
test-command = "cd {project} && python -m pytest tests/"

# Use in repair commands  
repair-wheel-command = "auditwheel repair -w {dest_dir} {wheel}"

Usage Examples

Basic Environment Setup

from cibuildwheel.environment import parse_environment

# Parse simple environment
env = parse_environment("CFLAGS=-O2 LDFLAGS=-s")
env_dict = env.as_dictionary({})
# Result: {"CFLAGS": "-O2", "LDFLAGS": "-s"}

Bash Expression Evaluation

import os
from cibuildwheel.environment import parse_environment

# Environment with expressions
env_string = "PATH=$PATH:/usr/local/bin HOME_BIN=$HOME/bin"
env = parse_environment(env_string)

# Evaluate with current environment
current_env = dict(os.environ)
evaluated = env.as_dictionary(current_env)
# Result: {"PATH": "/usr/bin:/usr/local/bin", "HOME_BIN": "/home/user/bin"}

Platform-Specific Configuration

[tool.cibuildwheel]
# Base environment for all platforms
environment = {DEBUG = "0", OPTIMIZE = "1"}

[tool.cibuildwheel.linux]
# Linux-specific compiler settings
environment = {
    CC = "gcc",
    CXX = "g++", 
    CFLAGS = "-O2 -fPIC",
    LDFLAGS = "-s"
}

[tool.cibuildwheel.windows]
# Windows-specific compiler settings
environment = {
    CC = "cl.exe",
    CXX = "cl.exe",
    CFLAGS = "/O2 /MD",
    LDFLAGS = "/LTCG"
}

[tool.cibuildwheel.macos]
# macOS-specific settings
environment = {
    CC = "clang",
    CXX = "clang++",
    CFLAGS = "-O2 -arch x86_64 -arch arm64",
    MACOSX_DEPLOYMENT_TARGET = "10.14"
}

Complex Build Environment

[tool.cibuildwheel]
environment = {
    # Build configuration
    BUILD_TYPE = "${BUILD_TYPE:-Release}",
    CMAKE_BUILD_PARALLEL_LEVEL = "${CMAKE_BUILD_PARALLEL_LEVEL:-4}",
    
    # Compiler flags
    CFLAGS = "${CFLAGS:--O2} -DVERSION=$(python setup.py --version)",
    CXXFLAGS = "${CXXFLAGS:--O2} -std=c++17",
    
    # Paths
    PKG_CONFIG_PATH = "/usr/local/lib/pkgconfig:$PKG_CONFIG_PATH",
    LD_LIBRARY_PATH = "/usr/local/lib:$LD_LIBRARY_PATH"
}

# Pass through CI variables
environment-pass = [
    "GITHUB_TOKEN", "CI", "GITHUB_ACTIONS",
    "TRAVIS", "APPVEYOR", "AZURE_PIPELINES"
]

Error Handling

from cibuildwheel.environment import parse_environment, EnvironmentParseError

try:
    # This might fail due to syntax errors
    env = parse_environment("INVALID SYNTAX")
except EnvironmentParseError as e:
    print(f"Environment parsing failed: {e}")

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