Skip to content

Replace setuptools/bundled-capnproto build with conan-py-build + CMake [looking for feedback] - #404

Draft
czoido wants to merge 33 commits into
capnproto:masterfrom
czoido:conan-py-build
Draft

Replace setuptools/bundled-capnproto build with conan-py-build + CMake [looking for feedback]#404
czoido wants to merge 33 commits into
capnproto:masterfrom
czoido:conan-py-build

Conversation

@czoido

@czoido czoido commented Jun 15, 2026

Copy link
Copy Markdown

Hi from the Conan team!

We recently released conan-py-build, a PEP 517 build backend that uses Conan to manage C/C++ dependencies, and we're testing it on several popular Python extensions that we think could benefit from it.

Here's the launch blog post: https://blog.conan.io/cpp/conan/python/2026/05/05/Introducing-conan-py-build.html
And the repo and docs: https://github.com/conan-io/conan-py-build · https://conan-py-build.conan.io/

We wanted to share this port of pycapnp to conan-py-build to get some comments and feedback from the project. The capnproto C++ library is fetched from Conan Center Index instead of being downloaded as a tarball from capnproto.org at build time.

This is a draft PR for sharing the work to get your thoughts on whether this direction is interesting to the project.

Some notes about the migration:

  • No bundled tarball. setup.py previously downloaded capnproto-c++-1.0.1.tar.gz from capnproto.org at build time. Conan now fetches and builds capnproto/1.0.1 from Conan Center Index.
  • Build tools managed by Conan. Building capnproto requires autotools (m4, etc.) to be present on the system. Conan manages these build tools as well.
  • Explicit, versioned C++ dependency. Bumping the C++ library is a one-line change in conanfile.py.
  • setup.py + buildutils/ removed. ~350 lines of build machinery replaced by a minimal conanfile.py and a standard CMakeLists.txt.
  • capnp/version.py simplified. Previously generated dynamically by setup.py; now it's a static file using importlib.metadata.
  • Same CI workflow. cibuildwheel keeps driving multi-platform builds with minimal changes.
  • Equivalent wheels. We compared the output against the 2.2.3 PyPI release file-by-file across all platforms. The only differences are cosmetic metadata.

CI results: https://github.com/czoido/pycapnp/actions/runs/27526912439

Any feedback is very welcome!

Thanks a lot 🙂

@haata haata left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for the delay, not sure why I didn't see this.

Comment thread conanfile.py Outdated
settings = "os", "compiler", "build_type", "arch"

def requirements(self):
self.requires("capnproto/1.0.1")

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This part isn't clear to me.

Is it looking for the system library libcapnproto 1.0.1? Or is it trying to download 1.0.1?

It's not clear to me how this setup supports either using a system provided libcapnproto or using a bundled libcapnproto that is built and bundled together with pycapnp.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See this page for the current workflows that are supported: https://capnproto.github.io/pycapnp/install.html#from-source

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

self.requires("capnproto/<version>") always resolves through Conan: it pulls the package from Conan Center Index, downloading a prebuilt binary if one matches, or building it from source otherwise, it doesn't pick up an already-installed system libcapnp.
So yes, this drops the "system-installed libcapnp" workflow that install.html#from-source documents today, but it's possible to support a similar workflow with some changes.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will this work for all the different architectures that are currently supported? And for the various glibc/musl forms? Basically, we have to be careful with prebuilt. See here for the various versions supported today: https://pypi.org/project/pycapnp/2.2.4/#files

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it works. I compared the 98 wheels produced by this PR's CI run against the 98 wheels currently published on PyPI for 2.2.4 and filenames match exactly: same manylinux_2_28/musllinux_1_2 for x86_64/i686/aarch64/ppc64le/s390x, same macOS x86_64/arm64, same Windows win32/win_amd64, all CPython versions including cp314t. Nothing missing.

The backend always builds the capnproto package with --build=missing, so when Conan Center has no matching prebuilt (the normal case for musllinux), it compiles capnproto from source in that same container against its actual glibc/musl.

Comment thread pyproject.toml

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've recently updated pyproject.toml so some of this may need to be updated.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, I have just updated the PR merging the changes

Comment thread setup.py Outdated

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now that setup.py can be laid to rest (yay!), what's the equivalent for python setup.py clean?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think clean existed because the Cython build wrote generated files straight into the capnp/ source tree (capnp/lib/capnp.cpp, capnp/lib/capnp.h, etc.).

With the changes, nothing lands in the source tree anymore, the generated Cython .cpp, the capnproto build, and the copied schemas all stay inside CMake's/Conan's own folders. So no dedicated command should be needed.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In that case it would be good to have a note in the document on what clean would be (i.e. what the default command to clean things up).

@czoido

czoido commented Jul 7, 2026

Copy link
Copy Markdown
Author

Sorry for the delay, not sure why I didn't see this.

No worries at all, thanks for taking the time to review it!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants