~ruther/guix-local

5f818705b4527f8aaae411d25b6f0cd55021614d — Maxim Cournoyer 5 years ago 35b91ad
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.
3 files changed, 523 insertions(+), 1 deletions(-)

M gnu/local.mk
M gnu/packages/cpp.scm
A gnu/packages/patches/cling-use-shared-library.patch
M gnu/local.mk => gnu/local.mk +1 -0
@@ 967,6 967,7 @@ dist_patch_DATA =						\
  %D%/packages/patches/clang-runtime-3.8-libsanitizer-mode-field.patch	\
  %D%/packages/patches/classpath-aarch64-support.patch		\
  %D%/packages/patches/classpath-miscompilation.patch		\
  %D%/packages/patches/cling-use-shared-library.patch		\
  %D%/packages/patches/clucene-pkgconfig.patch			\
  %D%/packages/patches/cmake-curl-certificates.patch		\
  %D%/packages/patches/coda-use-system-libs.patch		\

M gnu/packages/cpp.scm => gnu/packages/cpp.scm +193 -1
@@ 21,6 21,8 @@
;;; Copyright © 2021 Felix Gruber <felgru@posteo.net>
;;; Copyright © 2021 Nicolò Balzarotti <nicolo@nixo.xyz>
;;; Copyright © 2021 Guillaume Le Vaillant <glv@posteo.net>
;;; Copyright © 2021 Maxim Cournoyer <maxim.cournoyer@gmail.com>

;;;
;;; 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 <vector>.*" all)
              (string-append all "#include <limits>\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 <stdio.h>' 'printf(\"Hello World!\\n\");'
@end example")
      (license license:lgpl2.1+))))     ;for the combined work

(define-public jsonnet
  (package
    (name "jsonnet")

A gnu/packages/patches/cling-use-shared-library.patch => gnu/packages/patches/cling-use-shared-library.patch +329 -0
@@ 0,0 1,329 @@
From 811f0a575231496318b5e9c9a0ff0ed195b16dc0 Mon Sep 17 00:00:00 2001
From: Maxim Cournoyer <maxim.cournoyer@gmail.com>
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] <target_link_libraries>: 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()
     $<TARGET_OBJECTS:obj.clingMetaProcessor>
     $<TARGET_OBJECTS:obj.clingUtils>
   )
-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