Skip to main content

A minimal PEP 517 compliant build backend that uses Conan to build Python C/C++ extensions

Project description

conan-py-build

Note: The contents of this repository are a proof of concept and highly experimental. Not recommended for production use.

A minimal PEP 517 compliant build backend that uses Conan to build Python C/C++ extensions.

Installation

From PyPI (typical use):

pip install conan-py-build

To work on this repository or try the current main:

git clone https://github.com/conan-io/conan-py-build.git
cd conan-py-build
pip install -e .

Quick Start

  1. Create a pyproject.toml for your package:
[build-system]
requires = ["conan-py-build"]
build-backend = "conan_py_build.build"

[project]
name = "mypackage"
version = "0.1.0"
  1. Create a conanfile.py with your C++ dependencies and build logic. Your CMakeLists.txt must use install(TARGETS ... DESTINATION <package_name>) so extensions end up in the wheel:
from conan import ConanFile
from conan.tools.cmake import CMake, cmake_layout

class MyPackageConan(ConanFile):
    settings = "os", "compiler", "build_type", "arch"
    generators = "CMakeToolchain", "CMakeDeps"

    def layout(self):
        cmake_layout(self)

    def requirements(self):
        self.requires("fmt/12.1.0")

    def build(self):
        cmake = CMake(self)
        cmake.configure()
        cmake.build()

    def package(self):
        cmake = CMake(self)
        cmake.install()
  1. Build the wheel:
pip wheel . -w dist/ -vvv

For a complete basic working example, see the basic example.

Configuration

Pass configuration options via --config-settings:

Option Description Default
host-profile Conan profile for host context default
build-profile Conan profile for build context default
build-dir Persistent build directory temp dir

Configure options in pyproject.toml (nested under [tool.conan-py-build]):

Option TOML section Description Default
conanfile-path [tool.conan-py-build] Path to the Conan recipe (directory containing conanfile.py or path to the file), relative to project root "." (project root)
extra-profile, extra-profile-host, … [tool.conan-py-build] Extra Conan profile file(s) — see Profiles (none)
version.file [tool.conan-py-build.version] Python file containing __version__ = "x.y.z" (see Dynamic version) (none)
version.provider [tool.conan-py-build.version] Set to "setuptools_scm" for version from git tags. Mutually exclusive with version.file. (none)
packages [tool.conan-py-build.wheel] List of paths (relative to project root) of Python packages in the wheel. Each path must be a directory with __init__.py ["src/<normalized_name>"]
include / exclude [tool.conan-py-build.sdist] Paths or glob patterns to add to or remove from the sdist [] / []

Dynamic version

Set dynamic = ["version"] in [project] (no version key) and configure the version source in [tool.conan-py-build.version]:

From a file — reads __version__ = "x.y.z" from a Python file:

[tool.conan-py-build.version]
file = "src/mypackage/__init__.py"

From git tags (setuptools-scm) — resolves version from VCS tags (e.g. v1.0.01.0.0):

[tool.conan-py-build.version]
provider = "setuptools_scm"

The setuptools-scm options are configured in [tool.setuptools_scm] — see the setuptools-scm docs for available options.

Note: version.file and provider = "setuptools_scm" are mutually exclusive.

License files (PEP 639)

The backend supports PEP 639 license metadata. Set [project].license-files in pyproject.toml to a list of glob patterns (e.g. ["LICENSE"]) to include those files in the wheel under .dist-info/licenses/ and add License-File entries to METADATA and to the sdist PKG-INFO. If license-files is not set, no license files are included.

Wheel packages

You can control which Python packages are included in the wheel via [tool.conan-py-build.wheel] in pyproject.toml:

  • packages: list of paths (relative to the project root) that are Python packages to include in the wheel. Each path must be a directory inside the project.

If packages is not set, the backend includes a single package at src/<normalized_project_name> (hyphens in the project name become underscores, e.g. my-packagesrc/my_package).

Conan recipe path. If your recipe lives outside the project root (e.g. subfolder/conanfile.py), set conanfile-path so the backend runs conan source, conan build and conan export-pkg on that path:

[tool.conan-py-build]
conanfile-path = "subfolder"
[tool.conan-py-build.wheel]
packages = ["src/mypackage", "src/other_package"]

See basic-pybind11 for multiple packages (python/... + src/...).

Sdist include / exclude

You can control what goes into the source distribution (sdist) via [tool.conan-py-build.sdist] in pyproject.toml:

  • sdist.include: paths to add to the sdist (e.g. files in default exclude like build/, or extra dirs like ["docs/"]).
  • sdist.exclude: paths or patterns to remove from the sdist (e.g. default includes you don't want, like ["README.md"], or ["tests"]).

By default the sdist includes pyproject.toml, CMakeLists.txt, conanfile.py, cmake/, src/, include/, README and LICENSE, and excludes __pycache__, *.pyc, .git, build, dist and the like.

[tool.conan-py-build.sdist]
include = ["docs/", "misc/"]
exclude = [".github", "scripts", "README.md"]

Profiles

Host and build profiles are set via --config-settings (see table above): host-profile and build-profile, defaulting to Conan’s default profile. Example with Jinja profiles under examples/profiles/ that use include(default) and set WHEEL_* for wheel tags. Set CONAN_CPYTHON_VERSION to the full interpreter version, e.g. 3.12.12:

export CONAN_CPYTHON_VERSION=3.12.12
pip wheel . --no-build-isolation \
    --config-settings="host-profile=examples/profiles/linux.jinja" \
    --config-settings="build-dir=./build" \
    -w dist/

Extra profile in pyproject.toml. You can add one extra Conan profile file via [tool.conan-py-build].extra-profile. It is composed on top of the profiles applied first (default or those passed via -C). The extra profile is applied last, so it lets you override values. For example, if your extension needs at least C++17, put compiler.cppstd=17 in a profile file and set extra-profile = "cpp17.profile" so that override is applied on top of the default or CI profile.

Keys: extra-profile, extra-profile-host, extra-profile-build, extra-profile-all. Path relative to project root.

[tool.conan-py-build]
extra-profile = "cpp17.profile"

Conan home and default profile

The backend always uses Conan’s default home (e.g. ~/.conan2), or the one set via CONAN_HOME or the .conanrc file.

By default the backend uses Conan's default profile. To use an autodetected profile, set CONAN_PY_BUILD_PROFILE_AUTODETECT=1 (or true / yes).

Support for shared library builds

If your extension links to shared libs from Conan, the backend collects them during the build and merges that output into the wheel staging root next to your packages (RPATH is fixed on the extension to point at the parent directory so those libs resolve).

Examples

See the examples/ directory for complete working examples:

  • basic: Extension with fmt, recipe in conan/ via conanfile-path
  • basic-pybind11: pybind11 + fmt (dynamic version from __init__.py, custom wheel.packages, PEP 639 license files)
  • basic-nanobind: nanobind + fmt, with extra-profile for C++17
  • external-sources: pybind11. C++ dependency fetched in source()
  • cibw-example: pybind11 + cibuildwheel (profiles under examples/cibw-example/profiles/, see CI workflow)

Development

To try changes against a project that uses this backend (e.g. one of the examples), install the backend in editable mode and build with no isolation so it uses your local copy:

pip install -e .   # from the conan-py-build repo root
cd examples/basic  # or your own project
pip wheel . --no-build-isolation -w dist/

Running tests

Install the build backend in editable mode with dev dependencies:

pip install -e ".[dev]"

Run the test suite:

pytest tests/ -v

License

MIT License - see LICENSE for details.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

conan_py_build-0.3.0.tar.gz (20.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

conan_py_build-0.3.0-py3-none-any.whl (14.0 kB view details)

Uploaded Python 3

File details

Details for the file conan_py_build-0.3.0.tar.gz.

File metadata

  • Download URL: conan_py_build-0.3.0.tar.gz
  • Upload date:
  • Size: 20.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for conan_py_build-0.3.0.tar.gz
Algorithm Hash digest
SHA256 fc4e539c7c0d1afdb128a858dd52e4a100875c00a4e212fe6b037667ee918a3f
MD5 05888fc6fcb7607bf47db37ca12456bb
BLAKE2b-256 948c03755a8e8f3ca71ae04fb24d5907df873f518f7a5a806127c58a0d236f5f

See more details on using hashes here.

Provenance

The following attestation bundles were made for conan_py_build-0.3.0.tar.gz:

Publisher: release.yml on conan-io/conan-py-build

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file conan_py_build-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: conan_py_build-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 14.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for conan_py_build-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 fa612550321e0203384c6e23bbf013a10b82930d6f4d4bcefc74fe81618a3cf7
MD5 5164748145ed2733f3faf723c72c9a94
BLAKE2b-256 abc8b6d7dda3df4a2721a1779ab42d617ac93fefef74c63317081de166ff77b5

See more details on using hashes here.

Provenance

The following attestation bundles were made for conan_py_build-0.3.0-py3-none-any.whl:

Publisher: release.yml on conan-io/conan-py-build

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page