cling
cling copied to clipboard
conan support (dependency and package manager)
Hi.
conan allows to wrap existing cmake build scripts. Conan is a dependency and package manager for C and C++ languages
Proof of concept: https://github.com/blockspacer/cling_conan.git
My use case: I use libtooling and cling to parse and execute C++ code at compile-time. https://github.com/blockspacer/CXXCTP
A lot of people over internet said that cant find how to integrate cling into their applications without ROOT ecosystem related to https://github.com/root-project/cling/issues/298
That approach also allows to distribute & find cling and clang headers in project build dirs (so CXXCTP tool will be able to auto download headers without need to configure paths using command-line arguments)
Proof of concept code below allows to find & use LLVMConfig.cmake using conan package (cling requires to provide LLVMDIR):
# see https://github.com/feelpp/feelpp/tree/v0.103.1/cmake/modules/FindCling.cmake
# see https://github.com/alandefreitas/find_package_online/blob/master/Modules/FindCling.cmake
# see https://github.com/alandefreitas/find_package_online/blob/master/Modules/ExternalProjectCling.cmake
if(NOT TARGET CONAN_PKG::cling_conan)
message(FATAL_ERROR "Use CONAN_PKG::cling_conan from conan")
endif()
message (STATUS "CONAN_CLING_CONAN_ROOT=${CONAN_CLING_CONAN_ROOT}")
message (STATUS "CONAN_LIB_DIRS_CLING_CONAN=${CONAN_LIB_DIRS_CLING_CONAN}")
message (STATUS "CONAN_BUILD_DIRS_CLING_CONAN=${CONAN_BUILD_DIRS_CLING_CONAN}")
message (STATUS "CONAN_INCLUDE_DIRS_CLING_CONAN=${CONAN_INCLUDE_DIRS_CLING_CONAN}")
find_path(CLING_Interpreter_INCLUDE_DIR ClingOptions.h
HINTS
${CONAN_CLING_CONAN_ROOT}
${CONAN_LIB_DIRS_CLING_CONAN}
${CONAN_BUILD_DIRS_CLING_CONAN}
${CONAN_INCLUDE_DIRS_CLING_CONAN}
${CONAN_CLING_CONAN_ROOT}/include/cling/Interpreter
# fallback to system one
${CLING_DIR}/src/tools/cling/include/cling/Interpreter
${CLING_DIR}/llvm_src/tools/cling/include/cling/Interpreter
$ENV{CLING_PREFIX}/include/cling/Interpreter
${CLING_PREFIX}/include/cling/Interpreter
/usr/include/cling/Interpreter
/usr/local/include/cling/Interpreter
/opt/local/include/cling/Interpreter
NO_DEFAULT_PATH)
message(STATUS "[cling] CLING_Interpreter_INCLUDE_DIR: ${CLING_Interpreter_INCLUDE_DIR}")
find_path(LLVMConfig_DIR LLVMConfig.cmake
HINTS
${CONAN_CLING_CONAN_ROOT}
${CONAN_LIB_DIRS_CLING_CONAN}
${CONAN_BUILD_DIRS_CLING_CONAN}
${CONAN_INCLUDE_DIRS_CLING_CONAN}
${CONAN_CLING_CONAN_ROOT}/lib/cmake/llvm
# fallback to system one
${CLING_DIR}/src/tools/cling/include/cling/Interpreter
${CLING_DIR}/llvm_src/tools/cling/include/cling/Interpreter
$ENV{CLING_PREFIX}/include/cling/Interpreter
${CLING_PREFIX}/include/cling/Interpreter
${CLING_Interpreter_INCLUDE_DIR}/../../../../../../build/lib/cmake/llvm
/usr/include/cling/Interpreter
/usr/local/include/cling/Interpreter
/opt/local/include/cling/Interpreter
NO_DEFAULT_PATH)
message(STATUS "[cling] LLVMConfig_DIR: ${LLVMConfig_DIR}")
include(
${LLVMConfig_DIR}/LLVMConfig.cmake
)
if(LLVM_BINARY_DIR)
message(STATUS "[cling] LLVM_BINARY_DIR: ${LLVM_BINARY_DIR}")
else()
message(FATAL_ERROR "[cling] LLVM_BINARY_DIR not found: ${LLVM_BINARY_DIR}")
endif()
list(APPEND CLING_DEFINITIONS LLVMDIR="${LLVM_BINARY_DIR}")
We'll need a PR for this, and we need someone (you?) to maintain it!
UPD:
I found that cling requires clang headers with same version as used during build (got stdlib errors similar to https://root-forum.cern.ch/t/root-6-10-08-on-macos-high-sierra-compiling-macro-example/26651/24 i.e. no member named 'int8_t' in the global namespace ).
i.e. conan package for cling must bundle /include/c++/v1 or depend on other recipe that bundles llvm headers (llvm must use same version as cling)
To avoid conflicts with system headers - package consumers must pass -isystem and -nostdinc++ flags to cling similar to pseudo-code below:
llvm_root = self.deps_cpp_info["llvm_9"].rootpath
# https://root-forum.cern.ch/t/root-6-10-08-on-macos-high-sierra-compiling-macro-example/26651/24
CXXFLAGS.append("-Wno-unused-command-line-argument")
CXXFLAGS.append("-Wno-error=unused-command-line-argument")
CXXFLAGS.append("-nostdinc++")
CXXFLAGS.append("-nodefaultlibs")
CXXFLAGS.appe and `nd("-lc++abi")
CXXFLAGS.append("-lc++")
CXXFLAGS.append("-lm")
CXXFLAGS.append("-lc")
CXXFLAGS.append("-stdlib=libc++")
CXXFLAGS.append("-I\"{}/include/c++/v1\"".format(llvm_root))
CXXFLAGS.append("-isystem\"{}/include\"".format(llvm_root))
CXXFLAGS.append("-isystem\"{}/lib/clang/9.0.1/include\"".format(llvm_root))
CXXFLAGS.append("-L{}/lib".format(llvm_root))
CXXFLAGS.append("-Wl,-rpath,{}/lib".format(llvm_root))
CXXFLAGS.append("-resource-dir {}/lib/clang/9.0.1".format(llvm_root))
That requires separate LLVM recipe.
I managed to package llvm 9 via conan https://github.com/blockspacer/conan_llvm_9 and upgraded cling recipe to version that uses llvm 9.
I.e. any consumers of cling package from conan must not only link with cling, but also pass compiler flags that point to llvm headers from https://github.com/blockspacer/conan_llvm_9 package
@blockspacer Hey thank you for this, it's incredibly useful. And the docs are thorough -- Much appreciated!