From 5f818705b4527f8aaae411d25b6f0cd55021614d Mon Sep 17 00:00:00 2001 From: Maxim Cournoyer Date: Fri, 3 Sep 2021 09:08:22 -0400 Subject: gnu: Add cling. * gnu/packages/cpp.scm (cling): New variable. (llvm-cling): New private variable. (clang-cling): Likewise. * gnu/packages/patches/cling-use-shared-library.patch: New patch. * gnu/local.mk (dist_patch_DATA): Register it. --- gnu/packages/cpp.scm | 194 +++++++++++- .../patches/cling-use-shared-library.patch | 329 +++++++++++++++++++++ 2 files changed, 522 insertions(+), 1 deletion(-) create mode 100644 gnu/packages/patches/cling-use-shared-library.patch (limited to 'gnu/packages') diff --git a/gnu/packages/cpp.scm b/gnu/packages/cpp.scm index 37dd5ceec4..042658695c 100644 --- a/gnu/packages/cpp.scm +++ b/gnu/packages/cpp.scm @@ -21,6 +21,8 @@ ;;; Copyright © 2021 Felix Gruber ;;; Copyright © 2021 Nicolò Balzarotti ;;; Copyright © 2021 Guillaume Le Vaillant +;;; Copyright © 2021 Maxim Cournoyer + ;;; ;;; This file is part of GNU Guix. ;;; @@ -43,6 +45,7 @@ #:use-module (guix download) #:use-module (guix utils) #:use-module (guix git-download) + #:use-module ((guix build utils) #:hide (delete)) #:use-module (guix build-system cmake) #:use-module (guix build-system gnu) #:use-module (guix build-system python) @@ -61,6 +64,7 @@ #:use-module (gnu packages documentation) #:use-module (gnu packages gcc) #:use-module (gnu packages libevent) + #:use-module (gnu packages libffi) #:use-module (gnu packages libunwind) #:use-module (gnu packages linux) #:use-module (gnu packages llvm) @@ -72,9 +76,11 @@ #:use-module (gnu packages pkg-config) #:use-module (gnu packages popt) #:use-module (gnu packages pretty-print) + #:use-module (gnu packages python) #:use-module (gnu packages tls) #:use-module (gnu packages web) - #:use-module (gnu packages xml)) + #:use-module (gnu packages xml) + #:use-module (srfi srfi-1)) (define-public range-v3 (package @@ -1357,6 +1363,192 @@ of reading and writing XML.") ;; details. (license license:gpl2+))) +(define %cling-version "0.9") + +(define llvm-cling ;LLVM 9 with approximately 10 patches for cling + (let ((base llvm-9)) + (package/inherit base + (name "llvm-cling") + (source + (origin + (inherit (package-source base)) + (method git-fetch) + (uri (git-reference + (url "http://root.cern/git/llvm.git") + (commit (string-append "cling-v" %cling-version)))) + (file-name (git-file-name "llvm-cling" %cling-version)) + (sha256 + (base32 + "0y3iwv3c9152kybmdrwvadggjs163r25h7rmlxzr3hfpr463pnwf")) + (modules '((guix build utils))) + (snippet + ;; The source is missing an include directive (see: + ;; https://github.com/vgvassilev/cling/issues/219). + '(substitute* "utils/benchmark/src/benchmark_register.h" + (("^#include .*" all) + (string-append all "#include \n")))))) + (outputs '("out")) + (arguments + (substitute-keyword-arguments (package-arguments base) + ((#:configure-flags _ ''()) + '(list "-DLLVM_PARALLEL_LINK_JOBS=1" ;cater to smaller build machines + ;; Only enable compiler support for the host architecture to + ;; save on build time. + "-DLLVM_TARGETS_TO_BUILD=host;NVPTX" + "-DLLVM_INSTALL_UTILS=ON" + "-DLLVM_ENABLE_RTTI=ON" + "-DLLVM_ENABLE_FFI=ON" + "-DLLVM_BUILD_LLVM_DYLIB=ON" + "-DLLVM_LINK_LLVM_DYLIB=ON")) + ((#:phases phases '%standard-phases) + `(modify-phases ,phases + (delete 'shared-lib-workaround) + (delete 'install-opt-viewer)))))))) + +(define clang-cling-runtime + (let ((base clang-runtime-9)) + (package/inherit base + (name "clang-cling-runtime") + (arguments + (substitute-keyword-arguments (package-arguments base) + ((#:phases phases '%standard-phases) + `(modify-phases ,phases + (add-after 'install 'delete-static-libraries + ;; This reduces the size from 22 MiB to 4 MiB. + (lambda* (#:key outputs #:allow-other-keys) + (let ((out (assoc-ref outputs "out"))) + (for-each delete-file (find-files out "\\.a$"))))))))) + (inputs (alist-replace "llvm" `(,llvm-cling) + (package-inputs base)))))) + +(define clang-cling ;modified clang 9 with ~ 60 patches for cling + (let ((base clang-9)) + (package/inherit base + (name "clang-cling") + (source + (origin + (inherit (package-source base)) + (method git-fetch) + (uri (git-reference + (url "http://root.cern/git/clang.git") + (commit (string-append "cling-v" %cling-version)))) + (file-name (git-file-name "clang-cling" %cling-version)) + (sha256 + (base32 + "128mxkwghss6589wvm6amzv183aq88rdrnfxjiyjcji5hx84vpby")))) + (arguments + (substitute-keyword-arguments (package-arguments base) + ((#:phases phases '%standard-phases) + `(modify-phases ,phases + (add-after 'install 'delete-static-libraries + ;; This reduces the size by half, from 220 MiB to 112 MiB. + (lambda* (#:key outputs #:allow-other-keys) + (let ((out (assoc-ref outputs "out"))) + (for-each delete-file (find-files out "\\.a$"))))))))) + (propagated-inputs (fold alist-replace + (package-propagated-inputs base) + '("llvm" "clang-runtime") + `((,llvm-cling) (,clang-cling-runtime))))))) + +(define-public cling + ;; The tagged v0.9 release doesn't build, so use the latest commit. + (let ((commit "d78d1a03fedfd2bf6d2b6ff295aca576d98940df") + (revision "1") + (version* "0.9")) + (package + (name "cling") + (version (git-version version* revision commit)) + (source (origin + (method git-fetch) + (uri (git-reference + (url "http://root.cern/git/cling.git") + (commit commit))) + (file-name (git-file-name name version)) + (sha256 + (base32 + "0lsbxv21b4qw11xkw9iipdpca64jjwwqxm0qf5v2cgdlibf8m8n9")) + ;; Patch submitted upstream here: + ;; https://github.com/root-project/cling/pull/433. + (patches (search-patches "cling-use-shared-library.patch")))) + (build-system cmake-build-system) + (arguments + `(#:build-type "Release" ;keep the build as lean as possible + #:tests? #f ;FIXME: 78 tests fail (out of ~200) + #:test-target "check-cling" + #:configure-flags + (list (string-append "-DCLING_CXX_PATH=" + (assoc-ref %build-inputs "gcc") "/bin/g++") + ;; XXX: The AddLLVM.cmake module expects LLVM_EXTERNAL_LIT to + ;; be a Python script, not a shell executable. + (string-append "-DLLVM_EXTERNAL_LIT=" + (assoc-ref %build-inputs "python-lit") + "/bin/.lit-real")) + #:phases + (modify-phases %standard-phases + (add-after 'unpack 'set-version + (lambda _ + (make-file-writable "VERSION") + (call-with-output-file "VERSION" + (lambda (port) + (format port "~a~%" ,version))))) + (add-after 'unpack 'patch-paths + (lambda* (#:key inputs #:allow-other-keys) + (substitute* "lib/Interpreter/CIFactory.cpp" + (("\bsed\b") + (which "sed")) + ;; This ensures that the default C++ library used by Cling is + ;; that of the compiler that was used to build it, rather + ;; than that of whatever g++ happens to be on PATH. + (("ReadCompilerIncludePaths\\(CLING_CXX_RLTV") + (string-append "ReadCompilerIncludePaths(\"" + (assoc-ref inputs "gcc") "/bin/g++\"")) + ;; Cling uses libclang's CompilerInvocation::GetResourcesPath + ;; to resolve Clang's library prefix, but this fails on Guix + ;; because it is relative to the output of cling rather than + ;; clang (see: + ;; https://github.com/root-project/cling/issues/434). Fully + ;; shortcut the logic in this method to return the correct + ;; static location. + (("static std::string getResourceDir.*" all) + (string-append all + " return std::string(\"" + (assoc-ref inputs "clang-cling") + "/lib/clang/" ,(package-version clang-cling) + "\");"))) + ;; Check for the 'lit' command for the tests, not 'lit.py' + ;; (see: https://github.com/root-project/cling/issues/432). + (substitute* "CMakeLists.txt" + (("lit.py") + "lit")))) + (add-after 'unpack 'adjust-lit.cfg + ;; See: https://github.com/root-project/cling/issues/435. + (lambda _ + (substitute* "test/lit.cfg" + (("config.llvm_tools_dir \\+ '") + "config.cling_obj_root + '/bin")))) + (add-after 'install 'delete-static-libraries + ;; This reduces the size from 17 MiB to 5.4 MiB. + (lambda* (#:key outputs #:allow-other-keys) + (let ((out (assoc-ref outputs "out"))) + (for-each delete-file (find-files out "\\.a$")))))))) + (native-inputs + `(("python" ,python) + ("python-lit" ,python-lit))) + (inputs + `(("clang-cling" ,clang-cling) + ("llvm-cling" ,llvm-cling))) + (home-page "https://root.cern/cling/") + (synopsis "Interactive C++ interpreter") + (description "Cling is an interactive C++17 standard compliant +interpreter, built on top of LLVM and Clang. Cling can be used as a +read-eval-print loop (REPL) to assist with rapid application development. +Here's how to print @samp{\"Hello World!\"} using @command{cling}: + +@example +cling '#include ' 'printf(\"Hello World!\\n\");' +@end example") + (license license:lgpl2.1+)))) ;for the combined work + (define-public jsonnet (package (name "jsonnet") diff --git a/gnu/packages/patches/cling-use-shared-library.patch b/gnu/packages/patches/cling-use-shared-library.patch new file mode 100644 index 0000000000..6385b307b3 --- /dev/null +++ b/gnu/packages/patches/cling-use-shared-library.patch @@ -0,0 +1,329 @@ +From 811f0a575231496318b5e9c9a0ff0ed195b16dc0 Mon Sep 17 00:00:00 2001 +From: Maxim Cournoyer +Date: Tue, 7 Sep 2021 16:35:07 -0400 +Subject: [PATCH] build: Allow building Cling using the Clang shared library. + +The officially supported way to build LLVM/Clang as a shared library +is via the LLVM_BUILD_LLVM_DYLIB and LLVM_LINK_LLVM_DYLIB CMake +options (see: https://llvm.org/docs/BuildingADistribution.html). When +built this way, the whole of Clang API is exposed as a shared +library (libclang-cpp.so). + +* CMakeLists.txt: Query if we're in shared mode via llvm-config, and +register the result as LLVM_LIB_IS_SHARED. +[LLVM_LIB_IS_SHARED] : Use the PUBLIC interface of the +LLVM shared library. +* lib/Interpreter/CMakeLists.txt [LLVM_LIB_IS_SHARED]: When defined, replace the +individual Clang components by clang-cpp. +* lib/MetaProcessor/CMakeLists.txt: Likewise. +* lib/Utils/CMakeLists.txt: Likewise. +* tools/Jupyter/CMakeLists.txt: Likewise. +* tools/driver/CMakeLists.txt: Likewise. +* tools/libcling/CMakeLists.txt: Likewise. +--- + CMakeLists.txt | 10 ++++++-- + lib/Interpreter/CMakeLists.txt | 40 ++++++++++++++++++-------------- + lib/MetaProcessor/CMakeLists.txt | 16 +++++++++---- + lib/Utils/CMakeLists.txt | 34 +++++++++++++++------------ + tools/Jupyter/CMakeLists.txt | 11 ++++++++- + tools/driver/CMakeLists.txt | 16 +++---------- + tools/libcling/CMakeLists.txt | 38 +++++++++++++++--------------- + 7 files changed, 93 insertions(+), 72 deletions(-) + +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 65b14b27..888f7ee9 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -23,6 +23,7 @@ if( CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR ) + "--libdir" + "--includedir" + "--prefix" ++ "--shared-mode" + "--src-root") + execute_process( + COMMAND ${CONFIG_COMMAND} +@@ -47,7 +48,8 @@ if( CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR ) + list(GET CONFIG_OUTPUT 2 LIBRARY_DIR) + list(GET CONFIG_OUTPUT 3 INCLUDE_DIR) + list(GET CONFIG_OUTPUT 4 LLVM_OBJ_ROOT) +- list(GET CONFIG_OUTPUT 5 MAIN_SRC_DIR) ++ list(GET CONFIG_OUTPUT 5 LLVM_LIB_IS_SHARED) ++ list(GET CONFIG_OUTPUT 6 MAIN_SRC_DIR) + + if(NOT MSVC_IDE) + set(LLVM_ENABLE_ASSERTIONS ${ENABLE_ASSERTIONS} +@@ -427,7 +429,11 @@ macro(add_cling_library name) + endif() + + if(TARGET ${name}) +- target_link_libraries(${name} INTERFACE ${LLVM_COMMON_LIBS}) ++ if(LLVM_LIB_IS_SHARED) ++ target_link_libraries(${name} PUBLIC LLVM) ++ else() ++ target_link_libraries(${name} INTERFACE ${LLVM_COMMON_LIBS}) ++ endif() + + if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY OR ${name} STREQUAL "libcling") + install(TARGETS ${name} +diff --git a/lib/Interpreter/CMakeLists.txt b/lib/Interpreter/CMakeLists.txt +index 921c773c..af65c020 100644 +--- a/lib/Interpreter/CMakeLists.txt ++++ b/lib/Interpreter/CMakeLists.txt +@@ -6,22 +6,28 @@ + # LICENSE.TXT for details. + #------------------------------------------------------------------------------ + +-set(LIBS +- clingUtils +- clangCodeGen +- clangDriver +- clangFrontend +- clangParse +- clangSema +- clangAnalysis +- clangEdit +- clangRewrite +- clangRewriteFrontend +- clangSerialization +- clangAST +- clangBasic +- clangLex +-) ++if (LLVM_LIB_IS_SHARED) ++ set(LIBS ++ clang-cpp ++ clingUtils) ++else() ++ set(LIBS ++ clingUtils ++ clangCodeGen ++ clangDriver ++ clangFrontend ++ clangParse ++ clangSema ++ clangAnalysis ++ clangEdit ++ clangRewrite ++ clangRewriteFrontend ++ clangSerialization ++ clangAST ++ clangBasic ++ clangLex ++ ) ++endif() + + set(LLVM_LINK_COMPONENTS + analysis +@@ -369,4 +375,4 @@ if ((NOT builtin_llvm) AND builtin_clang) + get_property(P SOURCE TransactionUnloader.cpp PROPERTY INCLUDE_DIRECTORIES) + list(INSERT P 0 ${FixInclude}) + set_property(SOURCE TransactionUnloader.cpp PROPERTY INCLUDE_DIRECTORIES "${P}") +-endif() +\ No newline at end of file ++endif() +diff --git a/lib/MetaProcessor/CMakeLists.txt b/lib/MetaProcessor/CMakeLists.txt +index e753dca3..5f4641bb 100644 +--- a/lib/MetaProcessor/CMakeLists.txt ++++ b/lib/MetaProcessor/CMakeLists.txt +@@ -10,7 +10,16 @@ set( LLVM_LINK_COMPONENTS + core + support + binaryformat +-) ++ ) ++ ++if (LLVM_LIB_IS_SHARED) ++ set(LIBS clang-cpp) ++else() ++ set(LIBS ++ clangLex ++ clangAST ++ clangBasic) ++endif() + + add_cling_library(clingMetaProcessor OBJECT + Display.cpp +@@ -21,10 +30,7 @@ add_cling_library(clingMetaProcessor OBJECT + MetaSema.cpp + + LINK_LIBS +- clangLex +- clangAST +- clangBasic +- ++ ${LIBS} + clingInterpreter + clingUtils + ) +diff --git a/lib/Utils/CMakeLists.txt b/lib/Utils/CMakeLists.txt +index 327c9fff..fbe4bd87 100644 +--- a/lib/Utils/CMakeLists.txt ++++ b/lib/Utils/CMakeLists.txt +@@ -26,21 +26,25 @@ set(LLVM_LINK_COMPONENTS + ${LLVM_TARGETS_TO_BUILD} + ) + +-set(LIBS +- clangCodeGen +- clangDriver +- clangFrontend +- clangParse +- clangSema +- clangAnalysis +- clangEdit +- clangRewrite +- clangRewriteFrontend +- clangSerialization +- clangAST +- clangBasic +- clangLex +-) ++if (LLVM_LIB_IS_SHARED) ++ set(LIBS clang-cpp) ++else() ++ set(LIBS ++ clangCodeGen ++ clangDriver ++ clangFrontend ++ clangParse ++ clangSema ++ clangAnalysis ++ clangEdit ++ clangRewrite ++ clangRewriteFrontend ++ clangSerialization ++ clangAST ++ clangBasic ++ clangLex ++ ) ++endif() + + find_library(DL_LIBRARY_PATH dl) + if (DL_LIBRARY_PATH) +diff --git a/tools/Jupyter/CMakeLists.txt b/tools/Jupyter/CMakeLists.txt +index aad5f3f7..8b4ac36f 100644 +--- a/tools/Jupyter/CMakeLists.txt ++++ b/tools/Jupyter/CMakeLists.txt +@@ -39,6 +39,14 @@ else() + endif() + endif() + ++if (LLVM_LIB_IS_SHARED) ++ set(LIBS ++ clang-cpp ++ clingUserInterface ++ clingMetaProcessor ++ ${INTERPRETER} ++ clingUtils) ++else() + set(LIBS + clangAST + clangBasic +@@ -54,7 +62,8 @@ set(LIBS + clingMetaProcessor + ${INTERPRETER} + clingUtils +- ) ++ ) ++endif() + + if( LLVM_ENABLE_PIC ) + set(ENABLE_SHARED SHARED) +diff --git a/tools/driver/CMakeLists.txt b/tools/driver/CMakeLists.txt +index 1968b97f..5ed53fb7 100644 +--- a/tools/driver/CMakeLists.txt ++++ b/tools/driver/CMakeLists.txt +@@ -9,23 +9,13 @@ + # Keep symbols for JIT resolution + set(LLVM_NO_DEAD_STRIP 1) + +-if(BUILD_SHARED_LIBS) +- set(LIBS +- LLVMSupport +- +- clangFrontendTool +- +- clingInterpreter +- clingMetaProcessor +- clingUserInterface +- clingUtils +- ) ++if(LLVM_LIB_IS_SHARED) ++ set(LIBS clang-cpp clingUserInterface) + add_cling_executable(cling + cling.cpp + ) + else() + set(LIBS +- LLVMSupport + + clangASTMatchers + clangFrontendTool +@@ -38,7 +28,7 @@ else() + $ + $ + ) +-endif(BUILD_SHARED_LIBS) ++endif(LLVM_LIB_IS_SHARED) + + set_target_properties(cling + PROPERTIES ENABLE_EXPORTS 1) +diff --git a/tools/libcling/CMakeLists.txt b/tools/libcling/CMakeLists.txt +index 143d3bdb..ba000d44 100644 +--- a/tools/libcling/CMakeLists.txt ++++ b/tools/libcling/CMakeLists.txt +@@ -10,21 +10,25 @@ set(SOURCES + ADDITIONAL_HEADERS + ) + +-set(LIBS +- clangAnalysis +- clangDriver +- clangFrontend +- clangParse +- clangSema +- clangAST +- clangLex +- clangSerialization +- clangCodeGen +- clangBasic +- clangEdit +- +- clingUtils +-) ++if (LLVM_LIB_IS_SHARED) ++ set(LIBS clang-cpp) ++else() ++ set(LIBS ++ clangAnalysis ++ clangDriver ++ clangFrontend ++ clangParse ++ clangSema ++ clangAST ++ clangLex ++ clangSerialization ++ clangCodeGen ++ clangBasic ++ clangEdit ++ ++ clingUtils ++ ) ++endif() + + set( LLVM_LINK_COMPONENTS + analysis +@@ -63,10 +67,6 @@ option(LIBCLING_BUILD_STATIC + # set(LLVM_EXPORTED_SYMBOL_FILE) + #endif() + +-if( LLVM_ENABLE_PIC ) +- set(ENABLE_SHARED SHARED) +-endif() +- + if((NOT LLVM_ENABLE_PIC OR LIBCLING_BUILD_STATIC) AND NOT WIN32) + set(ENABLE_STATIC STATIC) + endif() +-- +2.33.0 + -- cgit v1.2.3