Options

Build selection

platform

Override the auto-detected target platform

Options:autolinuxmacoswindowsiospyodide

Default:auto

auto will build wheels for the current platform.

  • Forlinux, you needDocker or Podman running, on Linux, macOS, or Windows.
  • Formacos andwindows, you need to be running on the respective system, with a working compiler toolchain installed - Xcode Command Line tools for macOS, and MSVC for Windows.
  • Forios you need to be running on macOS, with Xcode and the iOS simulator installed.
  • Forpyodide, you need a Linux or macOS machine.

Check theplatforms page for more information on platform requirements.

This option can also be set using thecommand-line option--platform. This option is not available in thepyproject.toml config.

Tip

You can use this option to locally debug your cibuildwheel config on Linux, instead of pushing to CI to test every change. For example:

export CIBW_BUILD='cp37-*'export CIBW_TEST_COMMAND='pytest {project}/tests'cibuildwheel --platform linux .

Linux builds are the easiest to test locally, because all the build tools are supplied in the container, and they run exactly the same locally as in CI.

This is even more convenient if you store your cibuildwheel config inpyproject.toml.

You can also run a single identifier with--only <identifier>. This willnot require--platform or--arch, and will override any build/skipconfiguration.

build,skip

Choose the Python versions to build

List of builds to build and skip. Each build has an identifier likecp38-manylinux_x86_64 orcp37-macosx_x86_64 - you can list specific ones to build and cibuildwheel will only build those, and/or list ones to skip and cibuildwheel won't try to build them.

When both options are specified, both conditions are applied and only builds with a tag that matchesbuild and does not matchskip will be built.

When setting the options, you can use shell-style globbing syntax, as perfnmatch with the addition of curly bracket syntax{option1,option2}, provided bybracex. All the build identifiers supported by cibuildwheel are shown below:

macOSWindowsLinux IntelLinux OtheriOSpyodide (WASM)
Python 3.8cp38-macosx_x86_64
cp38-macosx_universal2
cp38-macosx_arm64
cp38-win_amd64
cp38-win32
cp38-manylinux_x86_64
cp38-manylinux_i686
cp38-musllinux_x86_64
cp38-musllinux_i686
cp38-manylinux_aarch64
cp38-manylinux_ppc64le
cp38-manylinux_s390x
cp38-manylinux_armv7l
cp38-manylinux_riscv64
cp38-musllinux_aarch64
cp38-musllinux_ppc64le
cp38-musllinux_s390x
cp38-musllinux_armv7l
cp38-musllinux_riscv64
Python 3.9cp39-macosx_x86_64
cp39-macosx_universal2
cp39-macosx_arm64
cp39-win_amd64
cp39-win32
cp39-win_arm64
cp39-manylinux_x86_64
cp39-manylinux_i686
cp39-musllinux_x86_64
cp39-musllinux_i686
cp39-manylinux_aarch64
cp39-manylinux_ppc64le
cp39-manylinux_s390x
cp39-manylinux_armv7l
cp39-manylinux_riscv64
cp39-musllinux_aarch64
cp39-musllinux_ppc64le
cp39-musllinux_s390x
cp39-musllinux_armv7l
cp39-musllinux_riscv64
Python 3.10cp310-macosx_x86_64
cp310-macosx_universal2
cp310-macosx_arm64
cp310-win_amd64
cp310-win32
cp310-win_arm64
cp310-manylinux_x86_64
cp310-manylinux_i686
cp310-musllinux_x86_64
cp310-musllinux_i686
cp310-manylinux_aarch64
cp310-manylinux_ppc64le
cp310-manylinux_s390x
cp310-manylinux_armv7l
cp310-manylinux_riscv64
cp310-musllinux_aarch64
cp310-musllinux_ppc64le
cp310-musllinux_s390x
cp310-musllinux_armv7l
cp310-musllinux_riscv64
Python 3.11cp311-macosx_x86_64
cp311-macosx_universal2
cp311-macosx_arm64
cp311-win_amd64
cp311-win32
cp311-win_arm64
cp311-manylinux_x86_64
cp311-manylinux_i686
cp311-musllinux_x86_64
cp311-musllinux_i686
cp311-manylinux_aarch64
cp311-manylinux_ppc64le
cp311-manylinux_s390x
cp311-manylinux_armv7l
cp311-manylinux_riscv64
cp311-musllinux_aarch64
cp311-musllinux_ppc64le
cp311-musllinux_s390x
cp311-musllinux_armv7l
cp311-musllinux_riscv64
Python 3.12cp312-macosx_x86_64
cp312-macosx_universal2
cp312-macosx_arm64
cp312-win_amd64
cp312-win32
cp312-win_arm64
cp312-manylinux_x86_64
cp312-manylinux_i686
cp312-musllinux_x86_64
cp312-musllinux_i686
cp312-manylinux_aarch64
cp312-manylinux_ppc64le
cp312-manylinux_s390x
cp312-manylinux_armv7l
cp312-manylinux_riscv64
cp312-musllinux_aarch64
cp312-musllinux_ppc64le
cp312-musllinux_s390x
cp312-musllinux_armv7l
cp312-musllinux_riscv64
cp312-pyodide_wasm32
Python 3.13cp313-macosx_x86_64
cp313-macosx_universal2
cp313-macosx_arm64
cp313-win_amd64
cp313-win32
cp313-win_arm64
cp313-manylinux_x86_64
cp313-manylinux_i686
cp313-musllinux_x86_64
cp313-musllinux_i686
cp313-manylinux_aarch64
cp313-manylinux_ppc64le
cp313-manylinux_s390x
cp313-manylinux_armv7l
cp313-manylinux_riscv64
cp313-musllinux_aarch64
cp313-musllinux_ppc64le
cp313-musllinux_s390x
cp313-musllinux_armv7l
cp313-musllinux_riscv64
cp313-ios_arm64_iphoneos
cp313-ios_arm64_iphonesimulator
cp313-ios_x86_64_iphonesimulator
cp313-pyodide_wasm32
Python 3.14cp314-macosx_x86_64
cp314-macosx_universal2
cp314-macosx_arm64
cp314-win_amd64
cp314-win32
cp314-win_arm64
cp314-manylinux_x86_64
cp314-manylinux_i686
cp314-musllinux_x86_64
cp314-musllinux_i686
cp314-manylinux_aarch64
cp314-manylinux_ppc64le
cp314-manylinux_s390x
cp314-manylinux_armv7l
cp314-manylinux_riscv64
cp314-musllinux_aarch64
cp314-musllinux_ppc64le
cp314-musllinux_s390x
cp314-musllinux_armv7l
cp314-musllinux_riscv64
cp314-ios_arm64_iphoneos
cp314-ios_arm64_iphonesimulator
cp314-ios_x86_64_iphonesimulator
PyPy3.8 v7.3pp38-macosx_x86_64
pp38-macosx_arm64
pp38-win_amd64pp38-manylinux_x86_64
pp38-manylinux_i686
pp38-manylinux_aarch64
PyPy3.9 v7.3pp39-macosx_x86_64
pp39-macosx_arm64
pp39-win_amd64pp39-manylinux_x86_64
pp39-manylinux_i686
pp39-manylinux_aarch64
PyPy3.10 v7.3pp310-macosx_x86_64
pp310-macosx_arm64
pp310-win_amd64pp310-manylinux_x86_64
pp310-manylinux_i686
pp310-manylinux_aarch64
PyPy3.11 v7.3pp311-macosx_x86_64
pp311-macosx_arm64
pp311-win_amd64pp311-manylinux_x86_64
pp311-manylinux_i686
pp311-manylinux_aarch64
GraalPy 3.11 v24.2gp311_242-macosx_x86_64
gp311_242-macosx_arm64
gp311_242-win_amd64gp311_242-manylinux_x86_64gp311_242-manylinux_aarch64

The list of supported and currently selected build identifiers can also be retrieved by passing the--print-build-identifiers flag to cibuildwheel.The format ispython_tag-platform_tag, with tags similar to those inPEP 425.

Windows arm64 platform support is experimental.Linux riscv64 platform support is experimental and requires an explicit opt-in throughenable.

See thecibuildwheel 2 documentation for past end-of-life versions of Python.

Examples

pyproject.toml

[tool.cibuildwheel]# Only build on CPython 3.8build = "cp38-*"# Skip building on CPython 3.8 on the Macskip = "cp38-macosx_x86_64"# Skip building on CPython 3.8 on all platformsskip = "cp38-*"# Skip CPython 3.8 on Windowsskip = "cp38-win*"# Skip CPython 3.8 on 32-bit Windowsskip = "cp38-win32"# Skip CPython 3.8 and CPython 3.9skip = ["cp38-*", "cp39-*"]# Skip Python 3.8 on Linuxskip = "cp38-manylinux*"# Skip 32-bit buildsskip = ["*-win32", "*-manylinux_i686"]# Disable building PyPy wheels on all platformsskip = "pp*"

Environment variables

# Only build on CPython 3.8CIBW_BUILD: cp38-*# Skip building on CPython 3.8 on the MacCIBW_SKIP: cp38-macosx_x86_64# Skip building on CPython 3.8 on all platformsCIBW_SKIP: cp38-*# Skip CPython 3.8 on WindowsCIBW_SKIP: cp38-win*# Skip CPython 3.8 on 32-bit WindowsCIBW_SKIP: cp38-win32# Skip CPython 3.8 and CPython 3.9CIBW_SKIP: cp38-* cp39-*# Skip Python 3.8 on LinuxCIBW_SKIP: cp38-manylinux*# Skip 32-bit buildsCIBW_SKIP: "*-win32 *-manylinux_i686"# Disable building PyPy wheels on all platformsCIBW_SKIP: pp*

Separate multiple selectors with a space.

It is generally recommended to setCIBW_BUILD as an environment variable, thoughskiptends to be useful in a config file; you can statically declare that you don'tsupport a specific build, for example.

archs

Change the architectures built on your machine by default.

A list of architectures to build.

On macOS, this option can be used tocross-compile betweenx86_64,universal2 andarm64.

On Linux, this option can be used to buildnon-native architectures under emulation.

On Windows, this option can be used tocompile forARM64 from an Intel machine, provided the cross-compiling tools are installed.

Options:

  • Linux:x86_64i686aarch64ppc64les390xarmv7lriscv64
  • macOS:x86_64arm64universal2
  • Windows:AMD64x86ARM64
  • Pyodide:wasm32
  • iOS:arm64_iphoneosarm64_iphonesimulatorx86_64_iphonesimulator
  • auto: The recommended archs for your machine - see the table below.
  • auto64: The 64-bit arch(s) supported by your machine (includes device and simulator for iOS)
  • auto32: The 32-bit arch supported by your machine
  • native: the native arch of the build machine - matchesplatform.machine().
  • all : expands to all the architectures supported on this OS. You may want to usebuild with this option to target specific architectures via build selectors.

Linux riscv64 platform support is experimental and requires an explicit opt-in throughenable.

Default:auto

Runnernativeautoauto64auto32
Linux / Intel 64-bitx86_64x86_64x86_64i686
Linux / Intel 32-biti686i686i686
Linux / Arm 64-bitaarch64aarch64aarch64armv7l¹
Linux / Arm 32-bitarmv7larmv7larmv7l
Windows / Intel 64-bitAMD64AMD64x86AMD64x86
Windows / Intel 32-bitx86x86x86
Windows / ARM64ARM64ARM64ARM64
macOS / Intelx86_64x86_64x86_64
macOS / Apple Siliconarm64arm64arm64
iOS on macOS / Intelx86_64_iphonesimulatorx86_64_iphonesimulatorx86_64_iphonesimulator
iOS on macOS / Apple Siliconarm64_iphonesimulatorarm64_iphoneosarm64_iphonesimulatorarm64_iphoneosarm64_iphonesimulator

¹: This will only be included if the runner supports it.

If not listed above,auto is the same asnative.

Warning

Theauto option only includes 32-bit architectures if they arecommonly built.cibuildwheel 3.0 removed 32-bit Linux builds fromauto,and a future release may remove 32-bit Windows builds fromauto as well.If you know you need them, please includeauto32. Note that modernmanylinux image do not support 32-bit builds. If you want to avoid 32-bitWindows builds today, feel free to useauto64.

Note

Pyodide currently ignores the architecture setting, as it always builds forwasm32.

Platform-specific environment variables are also available:
CIBW_ARCHS_MACOS |CIBW_ARCHS_WINDOWS |CIBW_ARCHS_LINUX |CIBW_ARCHS_IOS

This option can also be set using thecommand-line option--archs. This option cannot be set in anoverrides section inpyproject.toml.

Examples

pyproject.toml

# Build `universal2` and `arm64` wheels on an Intel runner.# Note that the `arm64` wheel and the `arm64` part of the `universal2`# wheel cannot be tested in this configuration.[tool.cibuildwheel.macos]archs = ["x86_64", "universal2", "arm64"]# On an Linux Intel runner with qemu installed, build Intel and ARM wheels[tool.cibuildwheel.linux]archs = ["auto", "aarch64"]# Build all 32-bit and 64-bit wheels natively buildable on the image[tool.cibuildwheel]archs = ["auto64", "auto32"]

Environment variables

# Build `universal2` and `arm64` wheels on an Intel runner.# Note that the `arm64` wheel and the `arm64` part of the `universal2`# wheel cannot be tested in this configuration.CIBW_ARCHS_MACOS: "x86_64 universal2 arm64"# On an Linux Intel runner with qemu installed, build Intel and ARM wheelsCIBW_ARCHS_LINUX: "auto aarch64"# Build all 32-bit and 64-bit wheels natively buildable on the imageCIBW_ARCHS: "auto64 auto32"

Separate multiple archs with a space.

It is generally recommended to use the environment variable orcommand-line option for Linux, as selecting archs often dependson your specific runner having qemu installed.

project-requires-python

Manually set the Python compatibility of your project

By default, cibuildwheel reads your package's Python compatibility frompyproject.toml following theproject metadata specificationor fromsetup.cfg; finally it will try to inspect the AST ofsetup.py for asimple keyword assignment in a top level function call. If you need to overridethis behaviour for some reason, you can use this option.

When setting this option, the syntax is the same asproject.requires-python,using 'version specifiers' like>=3.8, according toPEP440.

Default: reads your package's Python compatibility frompyproject.toml(project.requires-python) orsetup.cfg (options.python_requires) orsetup.pysetup(python_requires="..."). If not found, cibuildwheel assumesthe package is compatible with all versions of Python that it can build.

Note

Rather than using this environment variable, it's recommended you set this valuestatically in a way that your build backend can use it, too. This ensuresthat your package's metadata is correct when published on PyPI. Thiscibuildwheel-specific option is provided as an override, and therefore is onlyavailable in environment variable form.

  • If you have apyproject.toml containing a[project] table, you can specifyrequires-python there.

    [project]...requires-python = ">=3.8"

    Note that not all build backends fully support using a[project] table yet;specifically setuptools just added experimental support in version 61.Adding[project] topyproject.toml requires all the other supportedvalues to be specified there, or to be listed indynamic.

  • If you're using setuptools,you can set this value insetup.cfg (preferred) orsetup.py and cibuildwheel will read it from there.

Examples

Environment variables

CIBW_PROJECT_REQUIRES_PYTHON: ">=3.8"

enable

Enable building with extra categories of selectors present.

This option lets you opt-in to non-default builds, like pre-releases andfree-threaded Python. These are not included by default to give a nice defaultfor new users, but can be added to the selectors available here. The allowedvalues are:

  • cpython-prerelease: Enables beta versions of Pythons if any are available (May-July, approximately).
  • cpython-freethreading:PEP 703 introduced variants of CPython that can be built without the Global Interpreter Lock (GIL). Those variants are also known as free-threaded / no-gil. This will enable building these wheels while they are experimental. The build identifiers for those variants have at suffix in theirpython_tag (e.g.cp313t-manylinux_x86_64).
  • pypy: Enable PyPy.
  • pypy-eol: Enable PyPy versions that have passed end of life (if still available).
  • cpython-experimental-riscv64: Enable experimental riscv64 builds. Those builds are disabled by default as they can't be uploaded to PyPI and a PEP will most likely be required before this can happen.
  • graalpy: Enable GraalPy.
  • pyodide-prerelease: Pyodide versions that haven't released yet, if one is available. Safe if you are shipping a site with an early build, not for general distribution.
  • all: Enable all of the above.

Caution

cpython-prerelease is provided for testing purposes only. It is notrecommended to distribute wheels built with beta releases, such asuploading to PyPI. Pleasedo not upload these wheels to PyPI (except forpre-releases), as they are not guaranteed to work with the final Pythonrelease. Once Python is ABI stable and enters the release candidate phase,that version of Python will become available without this flag.

Note

Free threading is experimental:What’s New In Python 3.13

Default: empty.

This option doesn't support overrides or platform specific variants; it isintended as a way to acknowledge that a project is aware that these extraselectors exist. If you need to enable/disable it per platform or pythonversion, set this option totrue and usebuild/skip options to filter thebuilds.

Unlike all other cibuildwheel options, the environment variable setting willonly add to the TOML config; you can't remove an enable by setting an empty orpartial list in environment variables; useCIBW_SKIP instead. This way, ifyou applycpython-prerelease during the beta period usingCIBW_ENABLEwithout disabling your other enables.

Examples

pyproject.toml

[tool.cibuildwheel]# Enable free-threaded supportenable = ["cpython-freethreading"]# Skip building free-threaded compatible wheels on Windowsenable = ["cpython-freethreading"]skip = "*t-win*"# Include all PyPy versionsenable = ["pypy", "pypy-eol"]

Environment variables

# Include latest Python betaCIBW_ENABLE: cpython-prerelease# Include free-threaded supportCIBW_ENABLE: cpython-freethreading# Include bothCIBW_ENABLE: cpython-prerelease cpython-freethreading# Skip building free-threaded compatible wheels on WindowsCIBW_ENABLE: cpython-freethreadingCIBW_SKIP: *t-win*# Include all PyPy versionsCIBW_ENABLE = pypy pypy-eol

allow-empty

Suppress the error code if no wheels match the specified build identifiers

When none of the specified build identifiers match any available versions,cibuildwheel will typically return error code 3, indicating that there areno wheels to build. Enabling this option will suppress this error, allowingthe build process to complete without signaling an error.

Default: Off (0). Error code 3 is returned when no builds are selected.

This option can also be set using thecommand-line option--allow-empty. This option is not available in thepyproject.toml config.

Examples

Environment variables

# Prevent an error code if the build does not match any wheelsCIBW_ALLOW_EMPTY: True

Build customization

build-frontend

Set the tool to use to build, either "build" (default), "build[uv]", or "pip"

Options:

  • build[;args: ...]
  • build[uv][;args: ...]
  • pip[;args: ...]

Default:build

Choose which build frontend to use.

You can use "build[uv]", which will use an externaluv everywherepossible, both through--installer=uv passed to build, as well as when makingall build and test environments. This will generally speed up cibuildwheel.Make sure you have an external uv on Windows and macOS, either bypre-installing it, or installing cibuildwheel with the uv extra,cibuildwheel[uv]. You cannot use uv currently on Windows for ARM, formusllinux on s390x, or for iOS, as binaries are not provided by uv. Legacy dependencies likesetuptools on Python < 3.12 and pip are not installed if using uv.

Pyodide ignores this setting, as only "build" is supported.

You can specify extra arguments to pass to the build frontend using theoptionalargs option.

Warning

If you are usingbuild[uv] and are passing--no-isolation or-n, wewill detect this and avoid passing--installer=uv to build, but stillinstall all packages with uv. We do not currently detect combined shortoptions, like-xn!

Examples

pyproject.toml

[tool.cibuildwheel]# Switch to using pipbuild-frontend = "pip"# supply an extra argument to 'pip wheel'build-frontend = { name = "pip", args = ["--no-build-isolation"] }# Use uv and buildbuild-frontend = "build[uv]"# Use uv and build with an argumentbuild-frontend = { name = "build[uv]", args = ["--no-isolation"] }

Environment variables

# Switch to using pipCIBW_BUILD_FRONTEND: "pip"# supply an extra argument to 'pip wheel'CIBW_BUILD_FRONTEND: "pip; args: --no-build-isolation"# Use uv and buildCIBW_BUILD_FRONTEND: "build[uv]"# Use uv and build with an argumentCIBW_BUILD_FRONTEND: "build[uv]; args: --no-isolation"

config-settings

Specify config-settings for the build backend.

Specify config settings for the build backend. Each space separateditem will be passed via--config-setting. In TOML, you can specifya table of items, including arrays.

Tip

Currently, "build" supports arrays for options, but "pip" only supportssingle values.

Platform-specific environment variables also available:
CIBW_CONFIG_SETTINGS_MACOS |CIBW_CONFIG_SETTINGS_WINDOWS |CIBW_CONFIG_SETTINGS_LINUX |CIBW_CONFIG_SETTINGS_IOS |CIBW_CONFIG_SETTINGS_PYODIDE

Examples

pyproject.toml

[tool.cibuildwheel.config-settings]--build-option = "--use-mypyc"

Environment variables

CIBW_CONFIG_SETTINGS: "--build-option=--use-mypyc"

environment

Set environment variables

A list of environment variables to set during the build and test phases. Bash syntax should be used, even on Windows.

You must use this variable to pass variables to Linux builds, since they execute in a container. It also works for the other platforms.

You can use$PATH syntax to insert other variables, or the$(pwd) syntax to insert the output of other shell commands.

To specify more than one environment variable, separate the assignments by spaces.

Platform-specific environment variables are also available:
CIBW_ENVIRONMENT_MACOS |CIBW_ENVIRONMENT_WINDOWS |CIBW_ENVIRONMENT_LINUX |CIBW_ENVIRONMENT_IOS |CIBW_ENVIRONMENT_PYODIDE

Examples

pyproject.toml

[tool.cibuildwheel]# Set some compiler flagsenvironment = "CFLAGS='-g -Wall' CXXFLAGS='-Wall'"# Set some compiler flags using a TOML tableenvironment = { CFLAGS="-g -Wall", CXXFLAGS="-Wall" }# Append a directory to the PATH variable (this is expanded in the build environment)environment = { PATH="$PATH:/usr/local/bin" }# Prepend a directory containing spaces on Windows.[tool.cibuildwheel.windows]environment = { PATH='C:\\Program Files\\PostgreSQL\\13\\bin;$PATH' }# Set BUILD_TIME to the output of the `date` commandenvironment = { BUILD_TIME="$(date)" }# Supply options to `pip` to affect how it downloads dependenciesenvironment = { PIP_EXTRA_INDEX_URL="https://pypi.myorg.com/simple" }# Any pip command-line option can be set using the PIP_ prefix# https://pip.pypa.io/en/stable/topics/configuration/#environment-variablesenvironment = { PIP_GLOBAL_OPTION="build_ext -j4" }# Set two flags on linux only[tool.cibuildwheel.linux]environment = { BUILD_TIME="$(date)", SAMPLE_TEXT="sample text" }# Alternate form with out-of-line table for setting a few values[tool.cibuildwheel.linux.environment]BUILD_TIME = "$(date)"SAMPLE_TEXT = "sample text"

In configuration files, you can use a [TOML][] table instead of a raw string as shown above.

Environment variables

# Set some compiler flagsCIBW_ENVIRONMENT: CFLAGS='-g -Wall' CXXFLAGS='-Wall'# Append a directory to the PATH variable (this is expanded in the build environment)CIBW_ENVIRONMENT: PATH=$PATH:/usr/local/bin# Prepend a directory containing spaces on Windows.CIBW_ENVIRONMENT_WINDOWS: >  PATH="C:\\Program Files\\PostgreSQL\\13\\bin;$PATH"# Set BUILD_TIME to the output of the `date` commandCIBW_ENVIRONMENT: BUILD_TIME="$(date)"# Supply options to `pip` to affect how it downloads dependenciesCIBW_ENVIRONMENT: PIP_EXTRA_INDEX_URL=https://pypi.myorg.com/simple# Any pip command-line options can be set using the PIP_ prefix# https://pip.pypa.io/en/stable/topics/configuration/#environment-variablesCIBW_ENVIRONMENT: PIP_GLOBAL_OPTION="build_ext -j4"# Set two flags on linux onlyCIBW_ENVIRONMENT_LINUX: BUILD_TIME="$(date)" SAMPLE_TEXT="sample text"

Separate multiple values with a space.

Note

cibuildwheel always defines the environment variableCIBUILDWHEEL=1. This can be useful forbuilding wheels with optional extensions.

Note

To do its work, cibuildwheel sets the variablesVIRTUALENV_PIP,DIST_EXTRA_CONFIG,SETUPTOOLS_EXT_SUFFIX,PIP_DISABLE_PIP_VERSION_CHECK,PIP_ROOT_USER_ACTION, and it extends the variablesPATH andPIP_CONSTRAINT. Your assignments to these options might be replaced or extended.

environment-pass

Set environment variables on the host to pass-through to the container.

A list of environment variables to pass into the linux container during each build and test. It has no effect on the other platforms, which can already access all environment variables directly.

To specify more than one environment variable, separate the variable names by spaces.

Note

cibuildwheel automatically passes the environment variableSOURCE_DATE_EPOCH if defined.

Examples

pyproject.toml

[tool.cibuildwheel.linux]# Export a variableenvironment-pass = ["CFLAGS"]# Set two flags variablesenvironment-pass = ["BUILD_TIME", "SAMPLE_TEXT"]

In configuration files, you can use a [TOML][] list instead of a raw string as shown above.

Environment variables

# Export a variableCIBW_ENVIRONMENT_PASS_LINUX: CFLAGS# Set two flags variablesCIBW_ENVIRONMENT_PASS_LINUX: BUILD_TIME SAMPLE_TEXT

Separate multiple values with a space.

before-all

Execute a shell command on the build system before any wheels are built.

Shell command that runs before any builds are run, to build or install parts that do not depend on the specific version of Python.

This option is very useful for the Linux build, where builds take place in isolated containers managed by cibuildwheel. This command will run inside the container before the wheel builds start. Note, if you're building bothx86_64 andi686 wheels (the default), your build uses two different container images. In that case, this command will execute twice - once per build container.

The placeholder{package} can be used here; it will be replaced by the path to the package being built by cibuildwheel.

On Windows and macOS, the version of Python available insidebefore-all is whatever is available on the host machine. On Linux, a modern Python version is available on PATH.

This option has special behavior in the overrides section inpyproject.toml.On linux, overriding it triggers a new container launch. It cannot be overriddenon macOS and Windows.

Platform-specific environment variables also available:
CIBW_BEFORE_ALL_MACOS |CIBW_BEFORE_ALL_WINDOWS |CIBW_BEFORE_ALL_LINUX |CIBW_BEFORE_ALL_IOS |CIBW_BEFORE_ALL_PYODIDE

Note

This command is executed in a different Python environment from the builds themselves. So you can'tpip install a Python dependency inbefore-all and use it in the build. Instead, look atbefore-build, or, if your project uses pyproject.toml, thebuild-system.requires field.

Examples

pyproject.toml

# Build third party library[tool.cibuildwheel]before-all = "make -C third_party_lib"# Install system library[tool.cibuildwheel.linux]before-all = "yum install -y libffi-devel"# Run multiple commands using an arraybefore-all = [  "yum install bzip2 -y",  "make third_party",]

In configuration files, you can use a TOML array, and each line will be run sequentially - joined with&&.

Environment variables

# Build third party libraryCIBW_BEFORE_ALL: make -C third_party_lib# Install system libraryCIBW_BEFORE_ALL_LINUX: yum install -y libffi-devel# Chain multiple commands using && and > in a YAML file, like:CIBW_BEFORE_ALL: >  yum install bzip2 -y &&  make third_party

For multiline commands, see the last example. The character> means thatwhitespace is collapsed to a single line, and '&&' between each commandensures that errors are not ignored.Further reading on multiline YAMLhere..

Note thatmanylinux_2_31 builds occur inside a Debian derivative dockercontainer, wheremanylinux2014 builds occur inside a CentOS one. So formanylinux_2_31 thebefore-all command must useapt-get -yinstead.

before-build

Execute a shell command preparing each wheel's build

A shell command to run before building the wheel. This option allows you to run a command ineach Python environment before thepip wheel command. This is useful if you need to set up some dependency so it's available during the build.

If dependencies are required to build your wheel (for example if you include a header from a Python module), instead of using this command, we recommend adding requirements to apyproject.toml file'sbuild-system.requires array instead. This is reproducible, and users who do not get your wheels (such as Alpine or ClearLinux users) will still benefit.

The active Python binary can be accessed usingpython, and pip withpip; cibuildwheel makes sure the right version of Python and pip will be executed. The placeholder{package} can be used here; it will be replaced by the path to the package being built by cibuildwheel.

The command is run in a shell, so you can write things likecmd1 && cmd2.

Platform-specific environment variables are also available:
CIBW_BEFORE_BUILD_MACOS |CIBW_BEFORE_BUILD_WINDOWS |CIBW_BEFORE_BUILD_LINUX |CIBW_BEFORE_BUILD_IOS |CIBW_BEFORE_BUILD_PYODIDE

Examples

pyproject.toml

[tool.cibuildwheel]# Install something required for the build# (you might want to use build-system.requires instead)before-build = "pip install pybind11"# Chain commands using && or make an array.before-build = "python scripts/install-deps.py && make clean"before-build = [    "python scripts/install-deps.py",    "make clean",]# Run a script that's inside your projectbefore-build = "bash scripts/prepare_for_build.sh"# If cibuildwheel is called with a package_dir argument, it's available as {package}before-build = "{package}/script/prepare_for_build.sh"

In configuration files, you can use a array, and the items will be joinedwith&&. In TOML, using a single-quote string will avoid escapes - useful forWindows paths.

Environment variables

# Install something required for the build (you might want to use pyproject.toml instead)CIBW_BEFORE_BUILD: pip install pybind11# Chain commands using &&CIBW_BEFORE_BUILD_LINUX: python scripts/install-deps.py && make clean# Run a script that's inside your projectCIBW_BEFORE_BUILD: bash scripts/prepare_for_build.sh# If cibuildwheel is called with a package_dir argument, it's available as {package}CIBW_BEFORE_BUILD: "{package}/script/prepare_for_build.sh"

Note

If you need Python dependencies installed for the build, we recommend usingpyproject.toml'sbuild-system.requires instead. This is an examplepyproject.toml file:

[build-system]requires = [    "setuptools>=42",    "Cython",    "numpy",]build-backend = "setuptools.build_meta"

ThisPEP 517/PEP 518 style build allows you to completely controlthe build environment in cibuildwheel,PyPA-build, and pip, doesn'tforce downstream users to install anything they don't need, and lets you domore complex pinning.

xbuild-tools

Binaries on the path that should be included in an isolated cross-build environment.

When building in a cross-platform environment, it is sometimes necessary to isolate thePATH so that binaries from the build machine don't accidentally get linked into the cross-platform binary. However, this isolation process will also hide tools that might be required to build your wheel.

If there are binaries present on thePATH when you invoke cibuildwheel, and those binaries are required to build your wheels, those binaries can be explicitly included in the isolated cross-build environment usingxbuild-tools. The binaries listed in this setting will be linked into an isolated location, and that isolated location will be put on thePATH of the isolated environment. You do not need to provide the full path to the binary - only the executable name that would be found by the shell.

If you declare a tool as a cross-build tool, and that tool cannot be found in the runtime environment, an error will be raised.

If you do not definexbuild-tools, and you build for a platform that uses a cross-platform environment, a warning will be raised. If your project does not require any cross-build tools, you can setxbuild-tools to an empty list to silence this warning.

Any tool used by the build process must be included in thexbuild-tools list, not just tools that cibuildwheel will invoke directly. For example, if your build invokescmake, and thecmake script invokesmagick to perform some image transformations, bothcmake andmagick must be included in your safe tools list.

Platform-specific environment variables are also available on platforms that use cross-platform environment isolation:
CIBW_XBUILD_TOOLS_IOS

Examples

pyproject.toml

[tool.cibuildwheel]# Allow access to the cmake and rustc binaries in the isolated cross-build environment.xbuild-tools = ["cmake", "rustc"]# No cross-build tools are requiredxbuild-tools = []

Environment variables

# Allow access to the cmake and rustc binaries in the isolated cross-build environment.CIBW_XBUILD_TOOLS: cmake rustc# No cross-build tools are requiredCIBW_XBUILD_TOOLS:

repair-wheel-command

Execute a shell command to repair each built wheel

Default:

  • on Linux:'auditwheel repair -w {dest_dir} {wheel}'
  • on macOS:'delocate-wheel --require-archs {delocate_archs} -w {dest_dir} -v {wheel}'
  • on Windows:''
  • on iOS:''
  • on Pyodide:''

A shell command to repair a built wheel by copying external library dependencies into the wheel tree and relinking them.The command is run on each built wheel (except for pure Python ones) before testing it.

The following placeholders must be used inside the command and will be replaced by cibuildwheel:

  • {wheel} for the absolute path to the built wheel
  • {dest_dir} for the absolute path of the directory where to create the repaired wheel
  • {delocate_archs} (macOS only) comma-separated list of architectures in the wheel.

The command is run in a shell, so you can run multiple commands likecmd1 && cmd2.

Platform-specific environment variables are also available:
CIBW_REPAIR_WHEEL_COMMAND_MACOS |CIBW_REPAIR_WHEEL_COMMAND_WINDOWS |CIBW_REPAIR_WHEEL_COMMAND_LINUX |CIBW_REPAIR_WHEEL_COMMAND_IOS |CIBW_REPAIR_WHEEL_COMMAND_PYODIDE

Tip

cibuildwheel doesn't yet ship a default repair command for Windows.

If that's an issue for you, check outdelvewheel - a new package that aims to do the same as auditwheel or delocate for Windows.

Because delvewheel is still relatively early-stage, cibuildwheel does not yet run it by default. However, we'd recommend giving it a try! See the examples below for usage.

Tip

When using--platform pyodide,pyodide build is used to do the build,which already usesauditwheel-emscripten to repair the wheel, so the defaultrepair command is empty. If there is a way to do this in two steps in the future,this could change.

Examples

pyproject.toml

# Use delvewheel on windows[tool.cibuildwheel.windows]before-build = "pip install delvewheel"repair-wheel-command = "delvewheel repair -w {dest_dir} {wheel}"# Don't repair macOS wheels[tool.cibuildwheel.macos]repair-wheel-command = ""# Pass the `--lib-sdir .` flag to auditwheel on Linux[tool.cibuildwheel.linux]repair-wheel-command = "auditwheel repair --lib-sdir . -w {dest_dir} {wheel}"# Multi-line example[tool.cibuildwheel]repair-wheel-command = [  'python scripts/repair_wheel.py -w {dest_dir} {wheel}',  'python scripts/check_repaired_wheel.py -w {dest_dir} {wheel}',]# Use abi3audit to catch issues with Limited API wheels[tool.cibuildwheel.linux]repair-wheel-command = [  "auditwheel repair -w {dest_dir} {wheel}",  "pipx run abi3audit --strict --report {wheel}",][tool.cibuildwheel.macos]repair-wheel-command = [  "delocate-wheel --require-archs {delocate_archs} -w {dest_dir} -v {wheel}",  "pipx run abi3audit --strict --report {wheel}",][tool.cibuildwheel.windows]repair-wheel-command = [  "copy {wheel} {dest_dir}",  "pipx run abi3audit --strict --report {wheel}",]

In configuration files, you can use an inline array, and the items will be joined with&&.

Environment variables

# Use delvewheel on windowsCIBW_BEFORE_BUILD_WINDOWS: "pip install delvewheel"CIBW_REPAIR_WHEEL_COMMAND_WINDOWS: "delvewheel repair -w {dest_dir} {wheel}"# Don't repair macOS wheelsCIBW_REPAIR_WHEEL_COMMAND_MACOS: ""# Pass the `--lib-sdir .` flag to auditwheel on LinuxCIBW_REPAIR_WHEEL_COMMAND_LINUX: "auditwheel repair --lib-sdir . -w {dest_dir} {wheel}"# Multi-line example - use && to join on all platformsCIBW_REPAIR_WHEEL_COMMAND: >  python scripts/repair_wheel.py -w {dest_dir} {wheel} &&  python scripts/check_repaired_wheel.py -w {dest_dir} {wheel}# Use abi3audit to catch issues with Limited API wheelsCIBW_REPAIR_WHEEL_COMMAND_LINUX: >  auditwheel repair -w {dest_dir} {wheel} &&  pipx run abi3audit --strict --report {wheel}CIBW_REPAIR_WHEEL_COMMAND_MACOS: >  delocate-wheel --require-archs {delocate_archs} -w {dest_dir} -v {wheel} &&  pipx run abi3audit --strict --report {wheel}CIBW_REPAIR_WHEEL_COMMAND_WINDOWS: >  copy {wheel} {dest_dir} &&  pipx run abi3audit --strict --report {wheel}

manylinux-*-image,musllinux-*-image

Specify manylinux / musllinux container images

The available options are:

OptionDefault
manylinux_x86_64-imagemanylinux_2_28
manylinux-i686-imagemanylinux2014
manylinux-pypy_x86_64-imagemanylinux_2_28
manylinux-aarch64-imagemanylinux_2_28
manylinux-ppc64le-imagemanylinux_2_28
manylinux-s390x-imagemanylinux_2_28
manylinux-armv7l-imagemanylinux_2_31
manylinux-riscv64-imageNo default
manylinux-pypy_aarch64-imagemanylinux_2_28
manylinux-pypy_i686-imagemanylinux2014
musllinux_x86_64-imagemusllinux_1_2
musllinux-i686-imagemusllinux_1_2
musllinux-aarch64-imagemusllinux_1_2
musllinux-ppc64le-imagemusllinux_1_2
musllinux-s390x-imagemusllinux_1_2
musllinux-armv7l-imagemusllinux_1_2
musllinux-riscv64-imageNo default

Set the Docker image to be used for buildingmanylinux / musllinux wheels.

Formanylinux-*-image, exceptmanylinux-armv7l-image, the value of this option can either be set tomanylinux2014,manylinux_2_28 ormanylinux_2_34 to use a pinned version of theofficial manylinux images. Alternatively, set these options to any other valid Docker image name.manylinux_2_28 andmanylinux_2_34 are not supported fori686 architecture.

Formanylinux-armv7l-image, the value of this option can either be set tomanylinux_2_31 or a custom image. Support is experimental for now. Themanylinux_2_31 value is only available forarmv7.

Formusllinux-*-image, the value of this option can either be set tomusllinux_1_2 or a custom image.

If this option is blank, it will fall though to the next available definition (environment variable -> pyproject.toml -> default).

If setting a custom image, you'll need to make sure it can be used in the same way as the default images: all necessary Python and pip versions need to be present in/opt/python/, and the auditwheel tool needs to be present for cibuildwheel to work. Apart from that, the architecture and relevant shared system libraries need to be compatible to the relevant standard to produce valid manylinux2014/manylinux_2_28/manylinux_2_34/musllinux_1_2 wheels (seepypa/manylinux on GitHub,PEP 599,PEP 600 andPEP 656 for more details).

Auditwheel detects the version of the manylinux / musllinux standard in the image through theAUDITWHEEL_PLAT environment variable, as cibuildwheel has no way of detecting the correct--plat command line argument to pass to auditwheel for a custom image. If a custom image does not correctly set thisAUDITWHEEL_PLAT environment variable, theCIBW_ENVIRONMENT option can be used to do so (e.g.,CIBW_ENVIRONMENT='AUDITWHEEL_PLAT="manylinux2014_$(uname -m)"').

Warning

On x86_64,manylinux_2_34 is usingx86-64-v2 target architecture.

While manylinux worked around that when building extensions from sources by intercepting compiler callsto target x86_64 instead, every library installed with dnf will most likely target the morerecent x86-64-v2 which, if grafted into a wheel, will fail to run on older hardware.

The workaround does not work for executables as they are always being linked with x86-64-v2 object files.

There's no PEP to handle micro-architecture variants yet when it comes to packaging orinstalling wheels. Auditwheel doesn't detect this either.

Please check the tracking issue inpypa/manylinux

Examples

pyproject.toml

[tool.cibuildwheel]# Build using the manylinux2014 imagemanylinux-x86_64-image = "manylinux2014"manylinux-i686-image = "manylinux2014"manylinux-pypy_x86_64-image = "manylinux2014"manylinux-pypy_i686-image = "manylinux2014"# Build using the latest manylinux2010 releasemanylinux-x86_64-image = "quay.io/pypa/manylinux2010_x86_64:latest"manylinux-i686-image = "quay.io/pypa/manylinux2010_i686:latest"manylinux-pypy_x86_64-image = "quay.io/pypa/manylinux2010_x86_64:latest"manylinux-pypy_i686-image = "quay.io/pypa/manylinux2010_i686:latest"# Build using a different image from the docker registrymanylinux-x86_64-image = "dockcross/manylinux-x64"manylinux-i686-image = "dockcross/manylinux-x86"# Build musllinux wheels using the musllinux_1_1 imagemusllinux-x86_64-image = "quay.io/pypa/musllinux_1_1_x86_64:latest"musllinux-i686-image = "quay.io/pypa/musllinux_1_1_i686:latest"

Like any other option, these can be placed in[tool.cibuildwheel.linux]if you prefer; they have no effect onmacos andwindows.

Environment variables

# Build using the manylinux2014 imageCIBW_MANYLINUX_X86_64_IMAGE: manylinux2014CIBW_MANYLINUX_I686_IMAGE: manylinux2014CIBW_MANYLINUX_PYPY_X86_64_IMAGE: manylinux2014CIBW_MANYLINUX_PYPY_I686_IMAGE: manylinux2014# Build using the latest manylinux2010 releaseCIBW_MANYLINUX_X86_64_IMAGE: quay.io/pypa/manylinux2010_x86_64:latestCIBW_MANYLINUX_I686_IMAGE: quay.io/pypa/manylinux2010_i686:latestCIBW_MANYLINUX_PYPY_X86_64_IMAGE: quay.io/pypa/manylinux2010_x86_64:latestCIBW_MANYLINUX_PYPY_I686_IMAGE: quay.io/pypa/manylinux2010_i686:latest# Build using a different image from the docker registryCIBW_MANYLINUX_X86_64_IMAGE: dockcross/manylinux-x64CIBW_MANYLINUX_I686_IMAGE: dockcross/manylinux-x86# Build musllinux wheels using the musllinux_1_1 imageCIBW_MUSLLINUX_X86_64_IMAGE: quay.io/pypa/musllinux_1_1_x86_64:latestCIBW_MUSLLINUX_I686_IMAGE: quay.io/pypa/musllinux_1_1_i686:latest

container-engine

Specify the container engine to use when building Linux wheels

Options:

  • docker[;create_args: ...][;disable_host_mount: true/false]
  • podman[;create_args: ...][;disable_host_mount: true/false]

Default:docker

Set the container engine to use. Docker is the default, or you can switch toPodman. To use Docker, you need to have a Docker daemonrunning anddocker available on PATH. To use Podman, it needs to beinstalled andpodman available on PATH.

Options can be supplied after the name.

Option nameDescription
create_argsSpace-separated strings, which are passed to the container engine on the command line when it's creating the container. If you want to include spaces inside a parameter, use shell-style quoting.
disable_host_mountBy default, cibuildwheel will mount the root of the host filesystem as a volume at/host in the container. To disable the host mount, passtrue to this option.

Tip

While most users will stick with Docker, Podman is available in differentcontexts - for example, it can be run inside a Docker container, or withoutroot access. Thanks to theOCI, images are compatible between engines, soyou can still use the regular manylinux/musllinux containers.

Examples

pyproject.toml

[tool.cibuildwheel]# use podman instead of dockercontainer-engine = "podman"# pass command line options to 'docker create'container-engine = { name = "docker", create-args = ["--gpus", "all"]}# disable the /host mountcontainer-engine = { name = "docker", disable-host-mount = true }

Environment variables

# use podman instead of dockerCIBW_CONTAINER_ENGINE: podman# pass command line options to 'docker create'CIBW_CONTAINER_ENGINE: "docker; create_args: --gpus all"# disable the /host mountCIBW_CONTAINER_ENGINE: "docker; disable_host_mount: true"

dependency-versions

Control the versions of the tools cibuildwheel uses

Options:pinnedlatestpackages: SPECIFIER...<your constraints file>

Default:pinned

Ifdependency-versions ispinned, cibuildwheel uses versions of toolslikepip,setuptools,virtualenv that were pinned with that release ofcibuildwheel. This represents a known-good set of dependencies, and isrecommended for build repeatability.

If set tolatest, cibuildwheel will use the latest of these packages thatare available on PyPI. This might be preferable if these packages have bugfixes that can't wait for a new cibuildwheel release.

To control the versions of dependencies yourself, you can supply apipconstraints filehere and it will be used instead. Alternatively, you can list constraintspecifiers inline with thepackages: SPECIFIER... syntax.

Note

If you need different dependencies for each python version, provide themin the same folder with a-pythonXY suffix. e.g. if yourdependency-versions="./constraints.txt", cibuildwheel will use./constraints-python38.txt on Python 3.8, or fallback to./constraints.txt if that's not found.

Platform-specific environment variables are also available:
CIBW_DEPENDENCY_VERSIONS_MACOS |CIBW_DEPENDENCY_VERSIONS_WINDOWS |CIBW_DEPENDENCY_VERSIONS_IOS |CIBW_DEPENDENCY_VERSIONS_PYODIDE

Note

This option does not affect the tools used on the Linux build - those versionsare bundled with the manylinux/musllinux image that cibuildwheel uses. To changedependency versions on Linux, use themanylinux-* /musllinux-*options.

Examples

pyproject.toml

[tool.cibuildwheel]# Use tools versions that are bundled with cibuildwheel (this is the default)dependency-versions = "pinned"# Use the latest versions available on PyPIdependency-versions = "latest"# Use your own pip constraints filedependency-versions = { file = "./constraints.txt" }# Specify requirements inlinedependency-versions = { packages = ["auditwheel==6.2.0"] }[tool.cibuildwheel.pyodide]# Choose a specific pyodide-build versiondependency-versions = { packages = ["pyodide-build==0.29.1"] }

Environment variables

# Use tools versions that are bundled with cibuildwheel (this is the default)CIBW_DEPENDENCY_VERSIONS: pinned# Use the latest versions available on PyPICIBW_DEPENDENCY_VERSIONS: latest# Use your own pip constraints fileCIBW_DEPENDENCY_VERSIONS: ./constraints.txt# Specify requirements inlineCIBW_DEPENDENCY_VERSIONS: "packages: auditwheel==6.2.0"# Choose a specific pyodide-build versionCIBW_DEPENDENCY_VERSIONS_PYODIDE: "packages: pyodide-build==0.29.1"# Use shell-style quoting around spaces package specifiersCIBW_DEPENDENCY_VERSIONS: "packages: 'pip >=16.0.0, !=17'"

pyodide-version

Specify the Pyodide version to use forpyodide platform builds

This option allows you to specify a specific version of Pyodide to be used when building wheels for thepyodide platform. If unset, cibuildwheel will use a pinned Pyodide version.

This option is particularly useful for:

  • Testing against specific Pyodide alpha or older releases.
  • Ensuring reproducibility by targeting a known Pyodide version.

The available Pyodide versions are determined by the version ofpyodide-build being used. You can list the compatible versions using the commandpyodide xbuildenv search --all as described in thePyodide platform documentation.

Tip

You can set the version ofpyodide-build using thedependency-versions option.

Warning

This option is considered experimental, and might be converted to a more general mechanism in a future minor cibuildwheel release.

Warning

Make sure to scope it to one specific pyodide identifier with overrides if using thepyodide-prerelease enable.

Examples

pyproject.toml

[tool.cibuildwheel.pyodide]# Build Pyodide wheels using Pyodide version 0.27.6pyodide-version = "0.27.6"[tool.cibuildwheel.pyodide]# Build Pyodide wheels using a specific alpha releasepyodide-version = "0.28.0a2"

Environment variables

# Build Pyodide wheels using Pyodide version 0.27.6CIBW_PYODIDE_VERSION: 0.27.6# Build Pyodide wheels using a specific alpha releaseCIBW_PYODIDE_VERSION: 0.28.0a2

Testing

test-command

The command to test each built wheel

Shell command to run tests after the build. The wheel will be installedautomatically and available for import from the tests. If this variable is notset, your wheel will not be installed after building.

To ensure the wheel is imported by your tests (instead of your source copy),Tests are executed from a temporary directory, outside of your sourcetree. To access your test code, you have a couple of options:

  • You can use thetest-sources setting to copy specific files from your source tree into the temporary directory. When using test-sources, use relative paths in your test command, as if they were relative to the project root.

  • You can use the{package} or{project} placeholders in yourtest-command to refer to the package being built or the project root, respectively.

    • {package} is the path to the package being built - thepackage_dir argument supplied to cibuildwheel on the command line.
    • {project} is an absolute path to the project root - the working directory where cibuildwheel was called.

On all platforms other than iOS, the command is run in a shell, so you can write things likecmd1 && cmd2.

On iOS, the value of thetest-command setting must follow the formatpython-m MODULE [ARGS...] - where MODULE is a Python module name, followed byarguments that will be assigned tosys.argv. Other commands cannot be used.

Platform-specific environment variables are also available:
CIBW_TEST_COMMAND_MACOS |CIBW_TEST_COMMAND_WINDOWS |CIBW_TEST_COMMAND_LINUX |CIBW_TEST_COMMAND_IOS |CIBW_TEST_COMMAND_PYODIDE

Examples

pyproject.toml

[tool.cibuildwheel]# Run the package tests using `pytest`test-command = "pytest {project}/tests"# Trigger an install of the package, but run nothing of notetest-command = "echo Wheel installed"# Multiline exampletest-command = [  "pytest {project}/tests",  "python {project}/test.py",]# run tests on ios - when test-sources is set, use relative paths, not {project} or {package}[tool.cibuildwheel.ios]test-sources = ["tests"]test-command = "python -m pytest ./tests"

In configuration files, you can use an array, and the items will be joined with&&.

Environment variables

# Run the package tests using `pytest`CIBW_TEST_COMMAND: pytest {project}/tests# Trigger an install of the package, but run nothing of noteCIBW_TEST_COMMAND: "echo Wheel installed"# Multi-line example - join with && on all platformsCIBW_TEST_COMMAND: >  pytest {project}/tests &&  python {project}/test.py# run tests on ios - when test-sources is set, use relative paths, not {project} or {package}CIBW_TEST_SOURCES_IOS: testsCIBW_TEST_COMMAND_IOS: python -m pytest ./tests

before-test

Execute a shell command before testing each wheel

A shell command to run ineach test virtual environment, before your wheel is installed and tested. This is useful if you need to install a non-pip package, invoke pip with different environment variables,or perform a multi-step pip installation (e.g. installing scikit-build or Cython before installing test package).

The active Python binary can be accessed usingpython, and pip withpip; cibuildwheel makes sure the right version of Python and pip will be executed. The placeholder{package} can be used here; it will be replaced by the path to the package being built by cibuildwheel.

The command is run in a shell, so you can write things likecmd1 && cmd2.

Platform-specific environment variables are also available:
CIBW_BEFORE_TEST_MACOS |CIBW_BEFORE_TEST_WINDOWS |CIBW_BEFORE_TEST_LINUX |CIBW_BEFORE_TEST_IOS |CIBW_BEFORE_TEST_PYODIDE

Examples

pyproject.toml

[tool.cibuildwheel]# Install test dependencies with overwritten environment variables.before-test = "CC=gcc CXX=g++ pip install -r requirements.txt"# Chain commands using && or using an arraybefore-test = "rm -rf ./data/cache && mkdir -p ./data/cache"before-test = [    "rm -rf ./data/cache",    "mkdir -p ./data/cache",]# Install non pip python packagebefore-test = [    "cd some_dir",    "./configure",    "make",    "make install",]# Install python packages that are required to install test dependencies[tool.cibuildwheel]before-test = "pip install cmake scikit-build"

In configuration files, you can use an array, and the items will be joined with&&.

Environment variables

# Install test dependencies with overwritten environment variables.CIBW_BEFORE_TEST: CC=gcc CXX=g++ pip install -r requirements.txt# Chain commands using &&CIBW_BEFORE_TEST: rm -rf ./data/cache && mkdir -p ./data/cache# Install non pip python packageCIBW_BEFORE_TEST: >  cd some_dir &&  ./configure &&  make &&  make install# Install python packages that are required to install test dependenciesCIBW_BEFORE_TEST: pip install cmake scikit-build

test-sources

Files and folders from the source tree that are copied into an isolated tree before running the tests

A space-separated list of files and folders, relative to the root of theproject, required for running the tests. If specified, these files and folderswill be copied into a temporary folder, and that temporary folder will be usedas the working directory for running the test suite.

The use oftest-sources isrequired for iOS builds. This is because thesimulator does not have access to the project directory, as it is not stored onthe simulator device. On iOS, the files will be copied into the test application,rather than a temporary folder.

Platform-specific environment variables are also available:
CIBW_TEST_SOURCES_MACOS |CIBW_TEST_SOURCES_WINDOWS |CIBW_TEST_SOURCES_LINUX |CIBW_TEST_SOURCES_IOS |CIBW_TEST_SOURCES_PYODIDE

Examples

pyproject.toml

# Copy the "tests" folder, plus "data/test-image.png" from the source folder to the test folder.[tool.cibuildwheel]test-sources = ["tests", "data/test-image.png"]

In configuration files, you can use an array, and the items will be joined with a space.

Environment variables

# Copy the "tests" folder, plus "data/test-image.png" from the source folder to the test folder.CIBW_TEST_SOURCES: tests data/test-image.png

test-requires

Install Python dependencies before running the tests

Space-separated list of dependencies required for running the tests.

Platform-specific environment variables are also available:
CIBW_TEST_REQUIRES_MACOS |CIBW_TEST_REQUIRES_WINDOWS |CIBW_TEST_REQUIRES_LINUX |CIBW_TEST_REQUIRES_IOS |CIBW_TEST_REQUIRES_PYODIDE

Examples

pyproject.toml

# Install pytest before running test-command[tool.cibuildwheel]test-requires = "pytest"# Install specific versions of test dependencies[tool.cibuildwheel]test-requires = ["pytest==8.2.2", "packaging==24.1"]

In configuration files, you can use an array, and the items will be joined with a space.

Environment variables

# Install pytest before running CIBW_TEST_COMMANDCIBW_TEST_REQUIRES: pytest# Install specific versions of test dependenciesCIBW_TEST_REQUIRES: pytest==8.2.2 packaging==24.1

test-extras

Install your wheel for testing usingextras_require

List ofextras_requireoptions that should be included when installing the wheel prior to running thetests. This can be used to avoid having to redefine test dependencies intest-requires if they are already defined inpyproject.toml,setup.cfg orsetup.py.

Platform-specific environment variables are also available:
CIBW_TEST_EXTRAS_MACOS |CIBW_TEST_EXTRAS_WINDOWS |CIBW_TEST_EXTRAS_LINUX |CIBW_TEST_EXTRAS_IOS |CIBW_TEST_EXTRAS_PYODIDE

Examples

pyproject.toml

[tool.cibuildwheel]# Will cause the wheel to be installed with `pip install <wheel_file>[test,qt]`test-extras = ["test", "qt"]

In configuration files, you can use an inline array, and the items will be joined with a comma.

Environment variables

# Will cause the wheel to be installed with `pip install <wheel_file>[test,qt]`CIBW_TEST_EXTRAS: "test,qt"

Separate multiple items with a comma.

test-groups

Specify test dependencies from your project'sdependency-groups

List ofdependency-groupsthat should be included when installing the wheel prior to running thetests. This can be used to avoid having to redefine test dependencies intest-requires if they are already defined inpyproject.toml.

Platform-specific environment variables are also available:
CIBW_TEST_GROUPS_MACOS |CIBW_TEST_GROUPS_WINDOWS |CIBW_TEST_GROUPS_LINUX |CIBW_TEST_GROUPS_PYODIDE

Examples

pyproject.toml

[tool.cibuildwheel]# Will cause the wheel to be installed with these groups of dependenciestest-groups = ["test", "qt"]

In configuration files, you can use an inline array, and the items will be joined with a space.

Environment variables

# Will cause the wheel to be installed with these groups of dependenciesCIBW_TEST_GROUPS: "test qt"

Separate multiple items with a space.

test-skip

Skip running tests on some builds

This will skip testing on any identifiers that match the given skip patterns (seeskip). This can be used to mask out tests for wheels that have missing dependencies upstream that are slow or hard to build, or to skip slow tests on emulated architectures.

With macOSuniversal2 wheels, you can also skip the individual archs inside the wheel using an:arch suffix. For example,cp39-macosx_universal2:x86_64 orcp39-macosx_universal2:arm64.

This option is not supported in the overrides section inpyproject.toml.

Examples

pyproject.toml

[tool.cibuildwheel]# Will avoid testing on emulated architecturestest-skip = "*-*linux_{aarch64,ppc64le,s390x,armv7l}"# Skip trying to test arm64 builds on Intel Macstest-skip = "*-macosx_arm64 *-macosx_universal2:arm64"

Environment variables

# Will avoid testing on emulated architecturesCIBW_TEST_SKIP: "*-*linux_{aarch64,ppc64le,s390x,armv7l}"# Skip trying to test arm64 builds on Intel MacsCIBW_TEST_SKIP: "*-macosx_arm64 *-macosx_universal2:arm64"

test-environment

Set environment variables for the test environment

A space-separated list of environment variables to set in the test environment.

The syntax is the same as forenvironment.

Platform-specific environment variables are also available:
CIBW_TEST_ENVIRONMENT_MACOS |CIBW_TEST_ENVIRONMENT_WINDOWS |CIBW_TEST_ENVIRONMENT_LINUX |CIBW_TEST_ENVIRONMENT_IOS |CIBW_TEST_ENVIRONMENT_PYODIDE

Examples

pyproject.toml

[tool.cibuildwheel]# Set the environment variable MY_ENV_VAR to "my_value" in the test environmenttest-environment = { MY_ENV_VAR="my_value" }# Set PYTHONSAFEPATH in the test environmenttest-environment = { PYTHONSAFEPATH="1" }

Environment variables

# Set the environment variable MY_ENV_VAR to "my_value" in the test environmentCIBW_TEST_ENVIRONMENT: MY_ENV_VAR=my_value# Set PYTHONSAFEPATH in the test environmentCIBW_TEST_ENVIRONMENT: PYTHONSAFEPATH=1

Debugging

debug-keep-container

Keep the container after running for debugging.

Enable this flag to keep the container around for inspection after a build. Thisoption is provided for debugging purposes only.

Default: Off (0).

Caution

This option can only be set as environment variable on the host machine

Examples

export CIBW_DEBUG_KEEP_CONTAINER=TRUE

debug-traceback

Print full traceback when errors occur.

Print a full traceback for the cibuildwheel process when errors occur. Thisoption is provided for debugging cibuildwheel.

This option can also be set using thecommand-line option--debug-traceback.

Examples

export CIBW_DEBUG_TRACEBACK=TRUE

build-verbosity

Increase/decrease the output of the build

This setting controls-v/-q flags to the build frontend. Since there isno communication between the build backend and the build frontend, buildmessages from the build backend will always be shown with1; higher levelswill not produce more logging about the build itself. Other levels only affectthe build frontend output, which is usually things like resolving anddownloading dependencies. The settings are:

buildpipdesc
-2N/A-qqeven more quiet, where supported
-1N/A-qquiet mode, where supported
0 (default)default for build tool
1-vprint backend output
2-v-vvprint log messages e.g. resolving info
3-vv-vvvprint even more debug info

Settings that are not supported for a specific frontend will log a warning.The default build frontend isbuild, which does show build backend output bydefault.

Platform-specific environment variables are also available:
CIBW_BUILD_VERBOSITY_MACOS |CIBW_BUILD_VERBOSITY_WINDOWS |CIBW_BUILD_VERBOSITY_LINUX |CIBW_BUILD_VERBOSITY_IOS |CIBW_BUILD_VERBOSITY_PYODIDE

Examples

pyproject.toml

[tool.cibuildwheel]# Ensure that the build backend output is presentbuild-verbosity = 1

Environment variables

# Ensure that the build backend output is presentCIBW_BUILD_VERBOSITY: 1

Command line

Options

usage:cibuildwheel [-h] [--platform{auto,linux,macos,windows,pyodide,ios}]                    [--archsARCHS] [--enableGROUP] [--onlyONLY]                    [--output-dirOUTPUT_DIR] [--config-fileCONFIG_FILE]                    [--print-build-identifiers] [--allow-empty]                    [--debug-traceback][PACKAGE]Build wheels for all the platforms.positional arguments:PACKAGE               Path to the package that you want wheels for. Default:                        the working directory. Can be a directory inside the                        working directory, or an sdist. When set to a                        directory, the working directory is still considered                        the 'project' and is copied into the build container                        on Linux. When set to a tar.gz sdist file, --config-                        file and --output-dir are relative to the current                        directory, and other paths are relative to the                        expanded SDist directory.options:-h,--help            show this help message and exit--platform{auto,linux,macos,windows,pyodide,ios}                        Platform to build for. Use this option to override the                        auto-detected platform. Specifying "macos" or                        "windows" only works on that operating system. "linux"                        works on any desktop OS, as long as Docker/Podman is                        installed. "pyodide" only works on linux and macOS.                        "ios" only work on macOS. Default: auto.--archsARCHS         Comma-separated list of CPU architectures to build                        for. When set to 'auto', builds the architectures                        natively supported on this machine. Set this option to                        build an architecture via emulation, for example,                        using binfmt_misc and QEMU. Default: auto. Choices:                        auto, auto64, auto32, native, all, x86_64, i686,                        aarch64, ppc64le, s390x, armv7l, riscv64, universal2,                        arm64, x86, AMD64, ARM64, wasm32, arm64_iphoneos,                        arm64_iphonesimulator, x86_64_iphonesimulator--enableGROUP        Enable an additional category of builds. Use multiple                        times to select multiple groups. Choices: cpython-                        experimental-riscv64, cpython-freethreading, cpython-                        prerelease, graalpy, pypy, pypy-eol, pyodide-                        prerelease.--onlyONLY           Force a single wheel build when given an identifier.                        Overrides CIBW_BUILD/CIBW_SKIP. --platform and --arch                        cannot be specified if this is given.--output-dirOUTPUT_DIR                        Destination folder for the wheels. Default:                        wheelhouse.--config-fileCONFIG_FILE                        TOML config file. Default: "", meaning                        {package}/pyproject.toml, if it exists. To refer to a                        project inside your project, use {package}; this                        matters if you build from an SDist.--print-build-identifiers                        Print the build identifiers matched by the current                        invocation and exit.--allow-empty         Do not report an error code if the build does not                        match any wheels.--debug-traceback     Print a full traceback for all errorsMost options are supplied via environment variables or in --config-file(pyproject.toml usually). See https://github.com/pypa/cibuildwheel#options forinfo.

Return codes

cibuildwheel exits 0 on success, or >0 if an error occurs.

Specific error codes are defined:

  • 2 means a configuration error
  • 3 means no builds are selected (and--allow-empty wasn't passed)
  • 4 means you specified an option that has been deprecated.

Placeholders

Some options support placeholders, like{project},{package} or{wheel}, that are substituted by cibuildwheel before they are used. If, for some reason, you need to write the literal name of a placeholder, e.g. literally{project} in a command that would ordinarily substitute{project}, prefix it with a hash character -#{project}. This is only necessary in commands where the specific string between the curly brackets would be substituted - otherwise, strings not modified.