Skip to content

Add a C ABI library option to the cpp template - #220

Merged
timkpaine merged 1 commit into
mainfrom
cpp-c-abi-library
Nov 14, 2026
Merged

timkpaine merged 1 commit into
mainfrom
cpp-c-abi-library

Conversation

@timkpaine

Copy link
Copy Markdown
Member

Description

add_c_abi now also applies to the cpp template. With it, the generated project has:

  • cpp/<name>/: C++ code plus c_api.cpp, built by hatch-cpp as the generic library <module>/lib/lib<module> with hidden visibility. hatch-cpp checks its exports against the header and the <MODULE>_ABI_VERSION string.
  • <module>/include/<module>/<module>.h: the C header with the export macro. It is checked in inside the package, because hatch-cpp does not copy headers and an editable install has to find it in the same place as a wheel does.
  • cpp/python/extension.cpp: the pybind11 extension, linked against the library through depends.
  • cpp/CMakeLists.txt: builds and installs the library without Python, with an exported target, a relocatable package config, a pkg-config file, an @rpath install name, and VERSION/SOVERSION. bump-my-version updates its version.
  • get_prefix, get_include, get_library_dirs, and get_libraries in the package, and os.add_dll_directory for the bundled lib on Windows.
  • auditwheel and delocate repair commands that leave the bundled library in place, and HATCH_CPP_LIBRARY_SOURCE=direct for Pyodide.
  • Tests that load the library, compile a C program against the installed package, and build a find_package consumer against the CMake install.

The option requires hatch-cpp>=0.6.0. Without add_c_abi the generated project is unchanged apart from the new answer in .copier-answers.yaml.

Checked on macOS with the cpp-capi example: make lint, make lint-docs, make checks, and make test pass. A wheel repaired with the delocate command passes the tests in a clean environment, and the package builds and imports with HATCH_CPP_LIBRARY_SOURCE set to external (against the CMake install) and direct. The Windows and Pyodide parts have not been run.

Type of Change

  • Bug fix
  • New feature
  • Documentation update
  • Refactor / code cleanup
  • CI / build configuration
  • Other (describe below)

Checklist

  • Linting passes (make lint)
  • Tests pass (make test)
  • New tests added for new functionality
  • Documentation updated (if applicable)
  • Changelog / version bump (if applicable)

add_c_abi now also applies to the cpp template. It splits the sources
into cpp/<name>, which builds lib<module> with an extern "C" surface
over the C++ code, and cpp/python, the pybind11 extension. hatch-cpp
builds the library as a generic entry under <module>/lib, checks its
exports against the header, and links the extension to it through
depends. The header is checked in under <module>/include/<module> so
editable installs and wheels find it in the same place.

The package exposes get_prefix, get_include, get_library_dirs, and
get_libraries, and adds its lib directory to the Windows DLL search
path. Wheel repair keeps the bundled library, and Pyodide builds
compile the library sources into the extension.

cpp/CMakeLists.txt builds and installs the library without Python, with
an exported target, a relocatable package config, and a pkg-config
file. The tests compile a C program against the installed package and
build a find_package consumer against the CMake install.

A cpp-capi example and gen/test targets exercise the option in CI.

Signed-off-by: Tim Paine <3105306+timkpaine@users.noreply.github.com>
@timkpaine
timkpaine merged commit c40b5eb into main Nov 14, 2026
25 checks passed
@timkpaine
timkpaine deleted the cpp-c-abi-library branch November 14, 2026 00:23
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.

1 participant