CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-setuptools-rust

Setuptools Rust extension plugin

Pending
Overview
Eval results
Files

commands.mddocs/

Build Commands

Distutils commands for building and cleaning Rust extensions, providing seamless integration with standard Python packaging workflows. These commands handle the cargo build process and manage build artifacts.

Capabilities

Rust Extension Building

Build Rust extensions using cargo, with support for cross-compilation, custom build options, and integration with Python packaging.

class build_rust(RustCommand):
    description = "build Rust extensions (compile/link to build directory)"
    user_options = [
        (
            "inplace",
            "i",
            "ignore build-lib and put compiled extensions into the source "
            + "directory alongside your pure Python modules",
        ),
        ("debug", "d", "Force debug to true for all Rust extensions "),
        ("release", "r", "Force debug to false for all Rust extensions "),
        ("qbuild", None, "Force enable quiet option for all Rust extensions "),
        (
            "build-temp",
            "t",
            "directory for temporary files (cargo 'target' directory) ",
        ),
        ("target=", None, "Build for the target triple"),
    ]
    boolean_options = ["inplace", "debug", "release", "qbuild"]

    def initialize_options(self) -> None:
        """Initialize all command options to default values."""

    def finalize_options(self) -> None:
        """Finalize and validate command options."""

    def run_for_extension(self, ext: RustExtension) -> None:
        """
        Build a single Rust extension.

        Parameters:
        - ext: RustExtension instance to build
        """

    def build_extension(
        self, 
        ext: RustExtension, 
        forced_target_triple: Optional[str] = None
    ) -> List[_BuiltModule]:
        """
        Build a Rust extension using cargo.

        Parameters:
        - ext: RustExtension to build
        - forced_target_triple: Override target triple for cross-compilation

        Returns:
        List[_BuiltModule]: List of built module information
        """

    def install_extension(
        self, 
        ext: RustExtension, 
        dylib_paths: List[_BuiltModule]
    ) -> None:
        """
        Install built extension to the appropriate location.

        Parameters:
        - ext: RustExtension that was built
        - dylib_paths: List of built modules to install
        """

    def get_dylib_ext_path(
        self, 
        ext: RustExtension, 
        target_fname: str
    ) -> str:
        """
        Get the installation path for a built extension.

        Parameters:
        - ext: RustExtension being installed
        - target_fname: Target filename

        Returns:
        str: Full path where extension should be installed
        """

    def install_extension(
        self, 
        ext: RustExtension, 
        dylib_paths: List[_BuiltModule]
    ) -> None:
        """
        Install built extension to the appropriate location.

        Parameters:
        - ext: RustExtension that was built
        - dylib_paths: List of built modules to install
        """

Rust Extension Cleaning

Clean build artifacts and temporary files created during Rust extension building.

class clean_rust(RustCommand):
    description = "clean Rust extensions (compile/link to build directory)"

    def initialize_options(self) -> None:
        """Initialize all command options to default values."""

    def run_for_extension(self, ext: RustExtension) -> None:
        """
        Clean build artifacts for a single Rust extension.

        Parameters:
        - ext: RustExtension to clean
        """

Base Command Class

Abstract base class providing common functionality for Rust extension commands.

class RustCommand(Command, ABC):
    """Abstract base class for Rust extension commands."""

    def initialize_options(self) -> None:
        """Initialize all command options to default values."""

    def finalize_options(self) -> None:
        """Finalize and validate command options."""

    def run(self) -> None:
        """Run the command for all Rust extensions."""

    @abstractmethod
    def run_for_extension(self, extension: RustExtension) -> None:
        """
        Run command for a single extension (must be implemented by subclasses).

        Parameters:
        - extension: RustExtension to process
        """

Usage Examples

Command Line Usage

# Build all Rust extensions
python setup.py build_rust

# Build with debug information
python setup.py build_rust --debug

# Build in release mode
python setup.py build_rust --release

# Build in-place (for development)
python setup.py build_rust --inplace

# Quiet build (suppress cargo output)
python setup.py build_rust --qbuild

# Custom cargo arguments
python setup.py build_rust --cargo-args="--features=extra"

# Clean build artifacts
python setup.py clean_rust

Integration with Other Commands

# Build everything including Rust extensions
python setup.py build

# Install including Rust extensions
python setup.py install

# Create wheel with Rust extensions
python setup.py bdist_wheel

# Development installation with in-place Rust builds
pip install -e .

Programmatic Usage

from setuptools import setup, Distribution
from setuptools_rust import build_rust, RustExtension

# Create a distribution with Rust extensions
dist = Distribution({
    'name': 'my-package',
    'rust_extensions': [
        RustExtension('my_package.rust_module', 'Cargo.toml')
    ]
})

# Build the Rust extensions
build_cmd = build_rust(dist)
build_cmd.initialize_options()
build_cmd.finalize_options()
build_cmd.run()

Custom Build Configuration

class CustomBuildRust(build_rust):
    """Custom build command with additional options."""
    
    user_options = build_rust.user_options + [
        ("custom-flag", None, "enable custom build flag"),
    ]
    
    def initialize_options(self):
        super().initialize_options()
        self.custom_flag = None
    
    def run_for_extension(self, ext):
        if self.custom_flag:
            # Add custom build logic
            ext.args = list(ext.args) + ["--features", "custom"]
        super().run_for_extension(ext)

Command Integration

The build commands integrate automatically with setuptools through entry points defined in pyproject.toml:

[project.entry-points."distutils.commands"]
build_rust = "setuptools_rust:build_rust"
clean_rust = "setuptools_rust:clean_rust"

This allows the commands to be discovered and used by setuptools automatically when setuptools-rust is installed.

Build Process Flow

  1. Initialization: Command options are initialized and validated
  2. Extension Discovery: All RustExtension instances are collected from the distribution
  3. Cargo Execution: For each extension, cargo is invoked with appropriate arguments
  4. Artifact Management: Built libraries are moved to correct locations
  5. Integration: Extensions are integrated with Python's import system

Environment Integration

The commands respect standard environment variables and setuptools configuration:

  • CARGO: Path to cargo executable
  • CARGO_BUILD_TARGET: Default target triple
  • RUSTFLAGS: Additional rustc flags
  • SETUPTOOLS_RUST_CARGO_PROFILE: Override cargo profile

Type Definitions

from typing import List, Optional
from abc import ABC, abstractmethod
from distutils.cmd import Command

class _BuiltModule:
    """Internal type representing information about a built module."""

Install with Tessl CLI

npx tessl i tessl/pypi-setuptools-rust

docs

commands.md

configuration.md

extension-building.md

index.md

tile.json