Skip to content
Merged
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
2 changes: 1 addition & 1 deletion .github/workflows/cppinterop-diff.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,4 @@ jobs:
run: |
rm -rf .git .github discord.svg
- name: Compare
run: diff --exclude=CMakeLists.txt -ur CppInterOp/ root/interpreter/CppInterOp/
run: diff -ur CppInterOp/ root/interpreter/CppInterOp/
2 changes: 1 addition & 1 deletion core/metacling/src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ target_include_directories(MetaCling SYSTEM PRIVATE
${CLANG_INCLUDE_DIRS}
${LLVM_INCLUDE_DIRS}
${CLAD_INCLUDE_DIRS}
${CMAKE_SOURCE_DIR}/interpreter/CppInterOp/include
${CMAKE_BINARY_DIR}/etc/cppinterop
)

target_include_directories(MetaCling PRIVATE
Expand Down
48 changes: 43 additions & 5 deletions interpreter/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -553,20 +553,58 @@ mark_as_advanced(FORCE BUG_REPORT_URL BUILD_CLANG_FORMAT_VS_PLUGIN BUILD_SHARED_
GCC_INSTALL_PREFIX LIBCLANG_BUILD_STATIC TOOL_INFO_PLIST)
mark_as_advanced(CLEAR LLVM_ENABLE_ASSERTIONS LLVM_BUILD_TYPE)

##################### LIBINTEROP ###########################
##################### CPPINTEROP ###########################

#---Set InterOp to build on Cling, this can be toggled to use Clang-REPL-------------------------------------------------------
# Set InterOp to build with Cling, can be toggled to use Clang-REPL
set(CPPINTEROP_USE_CLING ON CACHE BOOL "" FORCE)
set(CPPINTEROP_USE_REPL OFF CACHE BOOL "" FORCE)

#---Disable testing on InterOp if ROOT's testing is OFF (InterOp tests are enabled by default) -------------------------------------------------------
# Suppress CppInterOps install rules: ROOT ships CppInterOps public headers
# under $ROOTSYS/etc/cppinterop and does not install any build artifacts.
# This option adds clangCppInterOp with BUILDTREE_ONLY (add_llvm_library)
set(CPPINTEROP_INSTALL OFF CACHE BOOL "" FORCE)

# Disable testing on InterOp if ROOT's testing is OFF (enabled by default)
if(testing)
set(CPPINTEROP_ENABLE_TESTING ON CACHE BOOL "Enable gtest in CppInterOp")
set(CPPINTEROP_ENABLE_TESTING ON CACHE BOOL "Enable gtest in CppInterOp" FORCE)
else()
set(CPPINTEROP_ENABLE_TESTING OFF CACHE BOOL "Enable gtest in CppInterOp")
set(CPPINTEROP_ENABLE_TESTING OFF CACHE BOOL "Enable gtest in CppInterOp" FORCE)
endif()


add_subdirectory(CppInterOp)
if(TARGET CppInterOpUnitTests)
set_target_properties(CppInterOpUnitTests PROPERTIES EXCLUDE_FROM_ALL OFF)
endif()

# Stage CppInterOp's public headers + tblgen-generated .inc files into
# ${CMAKE_BINARY_DIR}/etc/cppinterop/CppInterOp/. Based on how
# core/clingutils ships Cling runtime headers into etc/cling/
set(cppinterop_etcdir ${CMAKE_BINARY_DIR}/etc/cppinterop/CppInterOp)
set(cppinterop_gen_dir ${CMAKE_BINARY_DIR}/interpreter/CppInterOp/include/CppInterOp)
set(cppinterop_src_files
${CMAKE_CURRENT_SOURCE_DIR}/CppInterOp/include/CppInterOp/CppInterOp.h
${CMAKE_CURRENT_SOURCE_DIR}/CppInterOp/include/CppInterOp/CppInterOpTypes.h
${CMAKE_CURRENT_SOURCE_DIR}/CppInterOp/include/CppInterOp/Dispatch.h
${cppinterop_gen_dir}/BuildInfo.inc
${cppinterop_gen_dir}/CppInterOpAPI.inc
${cppinterop_gen_dir}/CppInterOpDecl.inc
)
set(cppinterop_staged_files)
foreach(src ${cppinterop_src_files})
get_filename_component(name ${src} NAME)
list(APPEND cppinterop_staged_files ${cppinterop_etcdir}/${name})
endforeach()

add_custom_command(
OUTPUT ${cppinterop_staged_files}
COMMAND ${CMAKE_COMMAND} -E make_directory ${cppinterop_etcdir}
COMMAND ${CMAKE_COMMAND} -E copy_if_different
${cppinterop_src_files} ${cppinterop_etcdir}/
DEPENDS ${cppinterop_src_files} CppInterOpTableGen
COMMENT "Staging CppInterOp headers into etc/cppinterop/CppInterOp/")
add_custom_target(CppInterOpEtc DEPENDS ${cppinterop_staged_files})
add_dependencies(clangCppInterOp CppInterOpEtc)

install(FILES ${cppinterop_staged_files}
DESTINATION ${CMAKE_INSTALL_SYSCONFDIR}/cppinterop/CppInterOp)
1 change: 1 addition & 0 deletions interpreter/CppInterOp/.readthedocs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ build:
apt_packages:
- clang-20
- cmake
- doxygen
- libclang-20-dev
- llvm-20-dev
- llvm-20-tools
113 changes: 104 additions & 9 deletions interpreter/CppInterOp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ set(CMAKE_CXX_EXTENSIONS NO)
option(CPPINTEROP_USE_CLING "Use Cling as backend" OFF)
option(CPPINTEROP_USE_REPL "Use clang-repl as backend" ON)
option(CPPINTEROP_ENABLE_TESTING "Enable the CppInterOp testing infrastructure." ON)
option(CPPINTEROP_BUILD_TABLEGEN_ONLY "Only build cppinterop-tblgen (for cross-compilation)" OFF)

#=Set OFF to suppress install() rules and route clangCppInterOp through
# add_llvm_library(... BUILDTREE_ONLY)
option(CPPINTEROP_INSTALL "Generate install rules for CppInterOp" ON)
if(EMSCRIPTEN)
set(CPPINTEROP_EXTRA_WASM_FLAGS "-fwasm-exceptions" CACHE STRING "Extra flags for wasm")
endif()
Expand All @@ -24,6 +29,19 @@ endif()
if( CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR )
project(CppInterOp)

# When only building cppinterop-tblgen for cross-compilation, skip
# all find_package calls and library/test subdirectories. Only needs
# LLVM_DIR pointing to a native LLVM build with libLLVMTableGen.
if(CPPINTEROP_BUILD_TABLEGEN_ONLY)
find_package(LLVM REQUIRED CONFIG)
include_directories(${LLVM_INCLUDE_DIRS})
include(AddLLVM)
include(HandleLLVMOptions)
include(TableGen)
add_subdirectory(utils/TableGen)
return()
endif()

if (NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
message(WARNING "No build type selected. Defaulted CMAKE_BUILD_TYPE=Release.\n"
"Valid options are: None, Debug, Release, RelWithDebInfo, MinSizeRel.")
Expand Down Expand Up @@ -300,10 +318,18 @@ endif()

include(AddLLVM)
include(HandleLLVMOptions)
include(TableGen)
endif()

set(CMAKE_INCLUDE_CURRENT_DIR ON)

# Generated .inc files from cppinterop-tblgen live under our own build
# subtree. Use CMAKE_CURRENT_BINARY_DIR so consumers embedding CppInterOP
# via add_subdirectory() (e.g. ROOT) don't write CppInterOp artifacts into
# top-level build/include
set(CPPINTEROP_GEN_DIR ${CMAKE_CURRENT_BINARY_DIR}/include/CppInterOp)
include_directories(${CMAKE_CURRENT_BINARY_DIR}/include)

# In rare cases we might want to have clang installed in a different place
# than llvm and the header files should be found first (even though the
# LLVM_INCLUDE_DIRS) contain clang headers, too.
Expand All @@ -321,16 +347,53 @@ include_directories(SYSTEM ${LLVM_INCLUDE_DIRS})
separate_arguments(LLVM_DEFINITIONS_LIST NATIVE_COMMAND ${LLVM_DEFINITIONS})
add_definitions(${LLVM_DEFINITIONS_LIST})

string(REGEX REPLACE "/lib/cmake/llvm$" "" LLVM_BINARY_LIB_DIR "${LLVM_DIR}")
add_definitions(-DLLVM_BINARY_LIB_DIR="${LLVM_BINARY_LIB_DIR}")
# Bundle the ORC runtime + executor inside CppInterOp's distribution
# so the OOP-JIT path is self-contained: no extra package to install,
# no resource-dir scan in the host's clang tree at runtime. Paths are
# baked at build time (CPPINTEROP_RUNTIME_{BUILD,INSTALL}_DIR in
# Compatibility.h) and probed via fs::exists.
set(CPPINTEROP_RUNTIME_SUBDIR "cppinterop-rt")
set(CPPINTEROP_RUNTIME_BUILDTREE_DIR
"${CMAKE_BINARY_DIR}/lib/${CPPINTEROP_RUNTIME_SUBDIR}")

if(LLVM_VERSION_MAJOR GREATER 21)
find_package(LLVMOrcRuntime QUIET MODULE)
endif()

if(LLVM_BUILT_WITH_OOP_JIT)
if((CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND CMAKE_SYSTEM_PROCESSOR MATCHES "arm64") OR
(CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64"))
add_definitions(-DLLVM_BUILT_WITH_OOP_JIT)
else()
message(FATAL_ERROR "LLVM_BUILT_WITH_OOP_JIT is only supported on MacOS arm64 or Linux x86_64. Build aborted.")
endif()
if(LLVMOrcRuntime_FOUND)
message(STATUS "CppInterOp OOP-JIT runtime:")
message(STATUS " orc_rt: ${LLVMOrcRuntime_LIBRARY}")
message(STATUS " executor: ${LLVMOrcRuntime_EXECUTOR}")

file(MAKE_DIRECTORY "${CPPINTEROP_RUNTIME_BUILDTREE_DIR}")
configure_file("${LLVMOrcRuntime_LIBRARY}"
"${CPPINTEROP_RUNTIME_BUILDTREE_DIR}/liborc_rt.a"
COPYONLY)
configure_file("${LLVMOrcRuntime_EXECUTOR}"
"${CPPINTEROP_RUNTIME_BUILDTREE_DIR}/llvm-jitlink-executor"
COPYONLY)
if(CPPINTEROP_INSTALL)
install(FILES "${LLVMOrcRuntime_LIBRARY}"
DESTINATION "${CMAKE_INSTALL_LIBDIR}/${CPPINTEROP_RUNTIME_SUBDIR}"
RENAME liborc_rt.a)
install(PROGRAMS "${LLVMOrcRuntime_EXECUTOR}"
DESTINATION "${CMAKE_INSTALL_LIBDIR}/${CPPINTEROP_RUNTIME_SUBDIR}"
RENAME llvm-jitlink-executor)
endif()

# Bake build-tree and install-tree runtime locations into the library
# so it can locate the bundled parts at runtime without dladdr or any
# platform-specific self-DSO discovery.
add_definitions(
"-DCPPINTEROP_RUNTIME_BUILD_DIR=\"${CPPINTEROP_RUNTIME_BUILDTREE_DIR}\""
"-DCPPINTEROP_RUNTIME_INSTALL_DIR=\"${CMAKE_INSTALL_FULL_LIBDIR}/${CPPINTEROP_RUNTIME_SUBDIR}\"")
elseif(LLVM_VERSION_MAJOR GREATER 21)
message(STATUS
"CppInterOp: OOP-JIT runtime (liborc_rt + llvm-jitlink-executor) "
"not found in ${LLVM_LIBRARY_DIR}. Out-of-process JIT support will "
"be unavailable. To enable it, build LLVM with compiler-rt and "
"ninja the llvm-jitlink-executor + orc_rt* targets, or install a "
"compiler-rt package that ships them.")
endif()

# If the llvm sources are present add them with higher priority.
Expand Down Expand Up @@ -432,6 +495,35 @@ configure_file(
${CMAKE_CURRENT_BINARY_DIR}/lib/cmake/CppInterOp/CppInterOpConfigVersion.cmake
@ONLY)

if(CPPINTEROP_INSTALL)
install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/lib/cmake/CppInterOp/
DESTINATION lib/cmake/CppInterOp
FILES_MATCHING
PATTERN "*.cmake"
)

install(DIRECTORY include/
DESTINATION include
FILES_MATCHING
PATTERN "*.def"
PATTERN "*.h"
PATTERN "*.inc"
PATTERN ".svn" EXCLUDE
)

install(DIRECTORY tools/
DESTINATION include/CppInterOp/tools
FILES_MATCHING
PATTERN "*.h"
)

install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/include/
DESTINATION include
FILES_MATCHING
PATTERN "CMakeFiles" EXCLUDE
PATTERN "*.inc"
)
endif()
add_definitions( -D_GNU_SOURCE )

# Add deps if we build together with clang.
Expand Down Expand Up @@ -521,6 +613,9 @@ if (CPPINTEROP_INCLUDE_DOCS)
add_subdirectory(docs)
endif()

if(NOT EMSCRIPTEN AND NOT CPPINTEROP_TABLEGEN_EXE)
add_subdirectory(utils/TableGen)
endif()
add_subdirectory(lib)
if (CPPINTEROP_ENABLE_TESTING)
add_subdirectory(unittests)
Expand Down
Loading
Loading