Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ target_compile_definitions(cppjit PRIVATE
CPPINTEROP_LIBRARY="cppjit_backend/lib/libclangCppInterOp${CMAKE_SHARED_LIBRARY_SUFFIX}"
CPPINTEROP_INCLUDE_DIR="cppjit_backend/include"
CPPJIT_CLANG_MAJOR="${LLVM_VERSION_MAJOR}"
CPPJIT_CLANG_INCLUDE_DIR="cppjit_backend/lib/clang/${LLVM_VERSION_MAJOR}"
)

target_include_directories(cppjit PRIVATE
Expand Down Expand Up @@ -175,6 +176,18 @@ install(CODE "
file(INSTALL \"${CPPINTEROP_INSTALL_DIR}/include/\" DESTINATION \${CMAKE_INSTALL_PREFIX}/cppjit_backend/include)
")

# ship the builtin headers of the build clang, laid out as a headers-only
# resource dir: only include/ ships
set(_clang_resource_dir "${LLVM_LIBRARY_DIR}/clang/${LLVM_VERSION_MAJOR}")
if(NOT EXISTS "${_clang_resource_dir}/include")
message(FATAL_ERROR
"No builtin headers at ${_clang_resource_dir}/include; the LLVM at "
"${LLVM_DIR} carries no clang resource directory")
endif()
install(DIRECTORY "${_clang_resource_dir}/include/"
DESTINATION "cppjit_backend/lib/clang/${LLVM_VERSION_MAJOR}/include"
)
Comment thread
aaronj0 marked this conversation as resolved.

# the public cpyrt API headers keep their installed cpyrt/ prefix
install(FILES
src/cpyrt/API.h
Expand Down
28 changes: 20 additions & 8 deletions src/interop/interop_wrapper.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ static inline bool is_integral(std::string& s) {
struct InterOpPaths {
std::string Library;
std::string IncludeDir;
std::string ClangIncludeDir; // empty when the bundled headers are absent
};

// One relative layout, two anchors: prefer CppInterOp next to our own load
Expand All @@ -94,8 +95,17 @@ static InterOpPaths cppinterop_paths() {
anchor = here;
}
#endif
return {(anchor / CPPINTEROP_LIBRARY).string(),
(anchor / CPPINTEROP_INCLUDE_DIR).string()};
InterOpPaths Paths{(anchor / CPPINTEROP_LIBRARY).string(),
(anchor / CPPINTEROP_INCLUDE_DIR).string(),
{}};
// The builtin headers of the build clang ship with every installed
// package (see the CMake install rule); a raw build tree has none and
// falls back to resource-dir detection.
const std::filesystem::path bundled = anchor / CPPJIT_CLANG_INCLUDE_DIR;
std::error_code ec;
if (std::filesystem::exists(bundled / "include", ec))
Paths.ClangIncludeDir = bundled.string();
return Paths;
}

// The one place libclangCppInterOp is dlopen'd.
Expand All @@ -109,7 +119,8 @@ static bool loadDispatchAPI(const InterOpPaths& Paths) {

// CppInterOp itself appends CPPINTEROP_EXTRA_INTERPRETER_ARGS inside
// CreateInterpreter, so nothing needs to be forwarded from here.
static interop::TInterp_t acquireOrCreateInterpreter() {
static interop::TInterp_t
acquireOrCreateInterpreter(const InterOpPaths& Paths) {
if (auto existingInterp = Cpp::GetInterpreter())
return existingInterp;

Expand All @@ -119,10 +130,11 @@ static interop::TInterp_t acquireOrCreateInterpreter() {
args.push_back("-march=native");
#endif
// Without clang's builtin headers the interpreter fails at its first
// #include. CppInterOp probes only bare `clang`; when just
// clang-<major> is installed, resolve and pass it explicitly.
std::string resourceDir;
if (Cpp::DetectResourceDir("clang").empty())
// #include. Prefer the bundled copy: it matches the build clang and
// needs no LLVM on the host. DetectResourceDir refuses version
// mismatches, and CppInterOp itself probes only bare `clang`.
std::string resourceDir = Paths.ClangIncludeDir;
if (resourceDir.empty())
resourceDir = Cpp::DetectResourceDir("clang-" CPPJIT_CLANG_MAJOR);
if (!resourceDir.empty()) {
args.push_back("-resource-dir");
Expand Down Expand Up @@ -219,7 +231,7 @@ extern "C" int LoadCppInterOp() {
if (!loadDispatchAPI(Paths))
return;

acquireOrCreateInterpreter();
acquireOrCreateInterpreter(Paths);
configureInterpreter(Paths);
preloadHeaders();
defineRuntimeHelpers();
Expand Down
Loading