Building & Compiling C Extensions¶
Once you have written a C extension module (such as fastmath.c), you must compile it into a shared library (.so on Linux, .dylib on macOS, or .pyd on Windows) that Python can import.
Compiler Prerequisites¶
To compile C code, your system needs an appropriate C compiler:
- Windows: Install the Visual Studio C++ Build Tools (select "Desktop development with C++").
- macOS: Install the Xcode Command Line Tools:
- Linux (Ubuntu/Debian): Install
build-essentialandpython3-dev:
Building with setuptools and setup.py¶
While modern pure-Python packaging uses declarative pyproject.toml, compiled C extensions use setuptools.Extension:
# setup.py
from setuptools import setup, Extension
# Define the C extension module
fastmath_module = Extension(
name="fastmath",
sources=["src/fastmath.c"],
include_dirs=["include"],
extra_compile_args=["-O3"] # Enable compiler optimizations
)
setup(
name="fastmath",
version="1.0.0",
description="Optimized C extension module",
ext_modules=[fastmath_module]
)
Pair this with pyproject.toml:
Compiling for Local Development: --inplace¶
To compile the C source code and place the resulting .so or .pyd directly into your working directory for immediate testing:
You can immediately open a Python REPL in the same folder and test your module:
Automated Multi-Platform Wheels with cibuildwheel¶
Compiling C extensions for PyPI is challenging because Linux distributions require standard manylinux glibc compatibility, macOS requires Universal2 (Intel + Apple Silicon) architectures, and Windows requires MSVC runtimes.
The Python Packaging Authority provides cibuildwheel, which compiles binary wheels inside Docker containers in GitHub Actions:
# .github/workflows/wheels.yml
name: Build Wheels
on: [push, pull_request]
jobs:
build_wheels:
name: Build wheels on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
steps:
- uses: actions/checkout@v4
- name: Build wheels
uses: pypa/cibuildwheel@v2.18.0
- uses: actions/upload-artifact@v4
with:
name: cibw-wheels-${{ matrix.os }}
path: ./wheelhouse/*.whl
Running cibuildwheel generates fully compliant, self-contained .whl files ready for distribution to end-users without requiring them to have C compilers.
Modern Next-Gen Build Backends¶
For modern multi-language projects: - scikit-build-core: High-performance CMake-based build system for C, C++, and CUDA. - meson-python: Lightning-fast Meson build backend (used by SciPy and NumPy). - maturin: Zero-configuration packaging backend for compiling Rust extensions via PyO3.