Support consuming an external CppInterOp via CppInterOp_DIR - #48
Open
guitargeek wants to merge 1 commit into
Open
Support consuming an external CppInterOp via CppInterOp_DIR#48guitargeek wants to merge 1 commit into
guitargeek wants to merge 1 commit into
Conversation
Contributor
|
I’d think providing just CPPINTEROP_DIR should make this use case work… |
guitargeek
force-pushed
the
external-cppinterop
branch
from
August 29, 2026 10:23
51352db to
13499e1
Compare
Collaborator
Author
|
That's also possible. I have rewritten the logic such that the external CpInterOp path is triggered when the |
vgvassilev
reviewed
Aug 29, 2026
| # the LLVM version the library embeds, so no LLVM is needed to build the | ||
| # wrapper itself; version compatibility was already enforced when that | ||
| # CppInterOp was built. | ||
| find_package(CppInterOp CONFIG REQUIRED) |
Contributor
There was a problem hiding this comment.
I think we don't need the extra _cppjit_external_cppinterop but we can provide a HINT or an extra PATH and find_package will do the rest..
Collaborator
Author
There was a problem hiding this comment.
Right! I updated the PR.
Providing CppInterOp_DIR selects external mode: cppjit consumes that
CppInterOp install through find_package(CppInterOp) instead of building
one with ExternalProject and bundling it into the wheel.
In this mode nothing is bundled: the library and include paths from the
package config are baked into the wrapper as absolute paths, which
works because cppinterop_paths() joins with std::filesystem's
operator/, where an absolute right-hand side replaces the anchor. The
clang major comes from CPPINTEROP_LLVM_VERSION_MAJOR in the config, so
no LLVM is needed to build the wrapper itself; the LLVM discovery and
version gate only run in the default bundled mode, since compatibility
was already enforced when the external CppInterOp was built.
The mode is keyed to the explicitly provided CppInterOp_DIR variable,
not to find_package succeeding through ambient search paths: otherwise
a pip install inside e.g. a conda environment that happens to carry
CppInterOp would silently produce a wheel that does not bundle its
interpreter, making the wheel's composition depend on what the build
environment has lying around.
An external CppInterOp carries no clang builtin headers, and clang's
compiled-in resource dir default resolves relative to the library
location, so CPPJIT_CLANG_RESOURCE_DIR should point at the resource dir
matching the CppInterOp's clang. It is optional: when unset, CMake
warns and the wrapper falls back to the existing runtime
DetectResourceDir("clang-<major>") probe, which works wherever a
versioned clang is on PATH (e.g. conda environments). Distributions
where it is not (e.g. NixOS) pass the resource dir explicitly.
The config file's CPPINTEROP_INSTALL_PREFIX is captured immediately
after find_package, before the site-packages staging logic reuses that
variable name.
Intended for distribution packaging (e.g. Nix), where CppInterOp is a
separate package and duplicating its build in every consumer is wasted
work (e.g. for the matrix of different LLVM and Python versions
supported by Nix).
guitargeek
force-pushed
the
external-cppinterop
branch
from
August 29, 2026 12:55
13499e1 to
986f057
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Providing CppInterOp_DIR selects external mode: cppjit consumes that CppInterOp install through find_package(CppInterOp) instead of building one with ExternalProject and bundling it into the wheel.
In this mode nothing is bundled: the library and include paths from the package config are baked into the wrapper as absolute paths, which works because cppinterop_paths() joins with std::filesystem's operator/, where an absolute right-hand side replaces the anchor. The clang major comes from CPPINTEROP_LLVM_VERSION_MAJOR in the config, so no LLVM is needed to build the wrapper itself; the LLVM discovery and version gate only run in the default bundled mode, since compatibility was already enforced when the external CppInterOp was built.
The mode is keyed to the explicitly provided CppInterOp_DIR variable, not to find_package succeeding through ambient search paths: otherwise a pip install inside e.g. a conda environment that happens to carry CppInterOp would silently produce a wheel that does not bundle its interpreter, making the wheel's composition depend on what the build environment has lying around.
An external CppInterOp carries no clang builtin headers, and clang's compiled-in resource dir default resolves relative to the library location, so CPPJIT_CLANG_RESOURCE_DIR should point at the resource dir matching the CppInterOp's clang. It is optional: when unset, CMake warns and the wrapper falls back to the existing runtime DetectResourceDir("clang-") probe, which works wherever a versioned clang is on PATH (e.g. conda environments). Distributions where it is not (e.g. NixOS) pass the resource dir explicitly.
The config file's CPPINTEROP_INSTALL_PREFIX is captured immediately after find_package, before the site-packages staging logic reuses that variable name.
Intended for distribution packaging (e.g. Nix), where CppInterOp is a separate package and duplicating its build in every consumer is wasted work (e.g. for the matrix of different LLVM and Python versions supported by Nix).