~ruther/guix-local

3aa493477c9d271aeb8a6c75647a9dd00cbfb508 — Danny Milosavljevic 5 months ago c3cacc0
gnu: Add swift-llvm.

* gnu/packages/llvm.scm (swift-llvm): New variable.
* gnu/local.mk (dist_patch_DATA): Add swift-llvm-5.7.3-linux.patch.
* gnu/packages/patches/swift-llvm-5.7.3-linux.patch: New file.

Change-Id: Ifc456c68c8e1fc551b8a75ecfcda91813b8cacdc
3 files changed, 167 insertions(+), 0 deletions(-)

M gnu/local.mk
M gnu/packages/llvm.scm
A gnu/packages/patches/swift-llvm-5.7.3-linux.patch
M gnu/local.mk => gnu/local.mk +1 -0
@@ 2316,6 2316,7 @@ dist_patch_DATA =						\
  %D%/packages/patches/superlu-dist-awpm-grid.patch		\
  %D%/packages/patches/superlu-dist-scotchmetis.patch		\
  %D%/packages/patches/supertux-unbundle-squirrel.patch		\
  %D%/packages/patches/swift-llvm-5.7.3-linux.patch	\
  %D%/packages/patches/swig-support-gcc-12.patch		\
  %D%/packages/patches/swish-e-search.patch			\
  %D%/packages/patches/swish-e-format-security.patch		\

M gnu/packages/llvm.scm => gnu/packages/llvm.scm +127 -0
@@ 2137,3 2137,130 @@ Here's how to print @samp{\"Hello World!\"} using @command{cling}:
cling '#include <stdio.h>' 'printf(\"Hello World!\\n\");'
@end example")
    (license license:lgpl2.1+)))     ;for the combined work

(define %swift-llvm-clang-version "5.7.3")

(define-public swift-llvm
  (package
    (name "swift-llvm")
    (version %swift-llvm-clang-version)
    (source (origin
              (method git-fetch)
              (uri (git-reference
                    (url "https://github.com/apple/llvm-project.git")
                    (commit (string-append "swift-" %swift-llvm-clang-version
                                           "-RELEASE"))))
              (file-name (git-file-name "swift-llvm" %swift-llvm-clang-version))
              (sha256
               (base32
                "0ai460v5kqq3mhp0vz1f5rr2fcwqmx91bnwbkaksjp9cxlylnfr0"))
              (patches (search-patches "swift-llvm-5.7.3-linux.patch"))))
    (build-system cmake-build-system)
    (arguments
     (list
      ;; Upstream build script doesn't test LLVM.
      ;; LLVM_INCLUDE_TESTS=ON (default) builds test tools like FileCheck,
      ;; but LLVM_BUILD_TESTS=OFF (default) means no tests run via ctest.
      #:tests? #f
      #:build-type "Release"
      #:configure-flags
      #~(list "-DCMAKE_C_FLAGS=-fno-stack-protector"
              "-DCMAKE_CXX_FLAGS=-fno-stack-protector"
              "-DCMAKE_C_FLAGS_RELWITHDEBINFO=-O2 -DNDEBUG"
              "-DCMAKE_CXX_FLAGS_RELWITHDEBINFO=-O2 -DNDEBUG"
              "-DLLVM_TOOL_SWIFT_BUILD:BOOL=NO"
              "-DINTERNAL_INSTALL_PREFIX=local"
              "-DLLVM_INCLUDE_DOCS=YES"
              "-DLLVM_ENABLE_LTO="
              "-DLLVM_ENABLE_DUMP=ON"
              "-DLLVM_ENABLE_PROJECTS=clang"
              "-DLLVM_TARGETS_TO_BUILD=X86;ARM;AArch64;PowerPC;SystemZ;Mips"
              ;; Python llvm.py adds this (not build-script-impl).
              ;; This would also enable dump() by undefining NDEBUG.
              ; FIXME: "-DLLVM_ENABLE_ASSERTIONS=TRUE"
              "-DLLVM_LIT_ARGS=-sv -j 16"
              (string-append "-DGCC_INSTALL_PREFIX="
                             (assoc-ref %build-inputs "gcc-lib"))
              (string-append "-DC_INCLUDE_DIRS="
                             (assoc-ref %build-inputs "libc")
                             "/include")
              (string-append "-DCMAKE_INSTALL_PREFIX=" #$output))
      #:phases
      #~(modify-phases %standard-phases
          (add-after 'unpack 'enter-llvm-directory
            (lambda _
              (chdir "llvm")))
          (add-after 'enter-llvm-directory 'allow-config-h-install
            (lambda _
              ;; Swift needs llvm/Config/config.h, so remove the EXCLUDE.
              (substitute* "CMakeLists.txt"
                (("PATTERN \"config\\.h\" EXCLUDE")
                 ""))))
          (add-after 'allow-config-h-install 'fix-demangle-includes
            (lambda _
              (substitute* "include/llvm/Demangle/MicrosoftDemangleNodes.h"
                (("#include <array>")
                 "#include <array>\n#include <cstdint>\n#include <string>"))
              (substitute* "utils/benchmark/src/benchmark_register.h"
                (("#include <vector>")
                 "#include <vector>\n#include <limits>"))
              (substitute* "include/llvm/Support/Signals.h"
                (("#include <string>")
                 "#include <string>
#include <cstdint>"))
              ;; Work around Guix bug: libstdc++ was built without fenv.h support,
              ;; so _GLIBCXX_HAVE_FENV_H is undefined, causing <fenv.h> wrapper to
              ;; not include the actual header. Define it to bypass the wrapper.
              ;; See <https://issues.guix.gnu.org/43579>
              (substitute* "lib/Analysis/ConstantFolding.cpp"
                (("#include \"llvm/Config/config.h\"")
                 "#include \"llvm/Config/config.h\"\n#define _GLIBCXX_HAVE_FENV_H 1\n#include <fenv.h>"))))
          (add-after 'fix-demangle-includes 'set-glibc-file-names
            (lambda* (#:key inputs #:allow-other-keys)
              (let ((libc (assoc-ref inputs "libc"))
                    (gcc (assoc-ref inputs "gcc")))
                (substitute* "../clang/lib/Driver/ToolChains/Linux.cpp"
                  ;; Make "LibDir" refer to <glibc>/lib so that it
                  ;; uses the right dynamic linker file name.
                  (("(^[[:blank:]]+LibDir = ).*" _ declaration)
                   (string-append declaration "\"" libc "/lib\";\n"))
                  ;; Make clang look for libstdc++ in the right location.
                  (("LibStdCXXIncludePathCandidates\\[\\] = \\{")
                   (string-append
                    "LibStdCXXIncludePathCandidates[] = { \"" gcc
                    "/include/c++\","))
                  ;; Make sure libc's libdir is on the search path, to
                  ;; allow crt1.o & co. to be found.
                  (("@GLIBC_LIBDIR@")
                   (string-append libc "/lib"))))))
          (add-after 'install 'install-filecheck
            (lambda _
              ;; FileCheck is built but not installed by default.
              ;; Swift needs it--so install it manually.
              (install-file "bin/FileCheck"
               (string-append #$output "/bin")))))))
    (native-inputs
     (list python-3))
    (inputs
     `(("libxml2" ,libxml2)
       ("gcc-lib" ,gcc "lib")
       ("gcc" ,gcc)
       ("libc" ,glibc)
       ("libffi" ,libffi)))
    (propagated-inputs
     (list zlib))
    (home-page "https://swift.org/")
    (synopsis "LLVM for Swift (Apple's fork)")
    (description
     "This is Apple's fork of LLVM with Swift-specific modifications,
required to build Swift.")
    (license license:ncsa)))

;(define-public swift-clang-runtime
;  (package
;    (inherit (clang-runtime-from-llvm swift-llvm))
;    (arguments
;     (substitute-keyword-arguments (package-arguments (clang-runtime-from-llvm swift-llvm))
;       ((#:configure-flags flags)
;        #~(cons "-DCOMPILER_RT_INTERCEPT_LIBDISPATCH=ON"
;                #$flags))))))

A gnu/packages/patches/swift-llvm-5.7.3-linux.patch => gnu/packages/patches/swift-llvm-5.7.3-linux.patch +39 -0
@@ 0,0 1,39 @@
Author: Danny Milosavljevic <dannym@friendly-machines.com>
Date: 2025-10-20
Subject: Fix libc search path

Swift LLVM 5.7.3 (based on LLVM 14.0) - libc search path fix

This patch makes it easy to insert libc's $libdir so that Clang passes the
correct absolute file name of crt1.o etc. to 'ld'.  It removes the hard-coded
FHS directory names to make sure Clang also works on foreign distros.

--- a/clang/lib/Driver/ToolChains/Linux.cpp
+++ b/clang/lib/Driver/ToolChains/Linux.cpp
@@ -297,21 +297,12 @@

   Generic_GCC::AddMultiarchPaths(D, SysRoot, OSLibDir, Paths);

-  // Similar to the logic for GCC above, if we are currently running Clang
-  // inside of the requested system root, add its parent library path to those
-  // searched.
-  // FIXME: It's not clear whether we should use the driver's installed
-  // directory ('Dir' below) or the ResourceDir.
-  if (StringRef(D.Dir).startswith(SysRoot)) {
-    // Even if OSLibDir != "lib", this is needed for Clang in the build
-    // directory (not installed) to find libc++.
-    addPathIfExists(D, D.Dir + "/../lib", Paths);
-    if (OSLibDir != "lib")
-      addPathIfExists(D, D.Dir + "/../" + OSLibDir, Paths);
-  }
+  // Add libc's lib/ directory to the search path, so that crt1.o, crti.o,
+  // and friends can be found.
+  addPathIfExists(D, "@GLIBC_LIBDIR@", Paths);

-  addPathIfExists(D, SysRoot + "/lib", Paths);
-  addPathIfExists(D, SysRoot + "/usr/lib", Paths);
+  // Add GCC's lib/ directory so libstdc++.so can be found.
+  addPathIfExists(D, GCCInstallation.getParentLibPath(), Paths);
 }

 ToolChain::RuntimeLibType Linux::GetDefaultRuntimeLibType() const {