~ruther/guix-local

3f2ee72dbdb6118ea8daea77f2f40b28210c4279 — Danny Milosavljevic 5 months ago 8c12fa9
gnu: Add swift@6.2.

* gnu/packages/swift.scm (%swift-6.2-source): New variable.
(%swift-libdispatch-6.2-source): New variable.
(%swift-syntax-6.2-source): New variable.
(swift-6.2): New variable.
* gnu/packages/patches/swift-6.2-cplus-include-path.patch: New file.
* gnu/packages/patches/swift-6.2-exclude-scan-test.patch: New file.
* gnu/local.mk (dist_patch_DATA): Add them.

Change-Id: I795a87ec7c8203f26ce380c805a28d53b2c4fe65
M gnu/local.mk => gnu/local.mk +2 -0
@@ 2318,6 2318,8 @@ dist_patch_DATA =						\
  %D%/packages/patches/supertux-unbundle-squirrel.patch		\
  %D%/packages/patches/swift-5.7.3-sdk-path.patch			\
  %D%/packages/patches/swift-5.7.3-sourcekit-rpath.patch		\
  %D%/packages/patches/swift-6.2-cplus-include-path.patch		\
  %D%/packages/patches/swift-6.2-exclude-scan-test.patch		\
  %D%/packages/patches/swift-corelibs-libdispatch-5.6.3-lock-cpp.patch	\
  %D%/packages/patches/swift-corelibs-libdispatch-5.7.3-modulemap.patch	\
  %D%/packages/patches/swift-llvm-5.7.3-linux.patch	\

A gnu/packages/patches/swift-6.2-cplus-include-path.patch => gnu/packages/patches/swift-6.2-cplus-include-path.patch +116 -0
@@ 0,0 1,116 @@
Author: Danny Milosavljevic <dannym@friendly-machines.com>
Date: 2025-10-20
Subject: Make clang importer heed CPLUS_INCLUDE_PATH

--- a/include/swift/ClangImporter/ClangImporter.h	1970-01-01 00:00:01.000000000 +0000
+++ b/include/swift/ClangImporter/ClangImporter.h	2025-10-21 14:31:53.328441417 +0000
@@ -787,6 +787,9 @@
   SmallVector<std::pair<std::string, std::string>, 1> overridenFiles;
 
   bool requiresBuiltinHeadersInSystemModules;
+
+  /// Extra arguments to pass to the Clang invocation (e.g., -isystem paths).
+  std::vector<std::string> extraArgs;
 };
 
 /// On Linux, some platform libraries (glibc, libstdc++) are not modularized.
--- a/lib/ClangImporter/ClangImporter.cpp	1970-01-01 00:00:01.000000000 +0000
+++ b/lib/ClangImporter/ClangImporter.cpp	2025-10-21 14:34:20.744234737 +0000
@@ -1326,6 +1326,12 @@
   importer->requiresBuiltinHeadersInSystemModules =
       fileMapping.requiresBuiltinHeadersInSystemModules;
 
+  // Add extra arguments from file mapping (e.g., C++ stdlib include paths).
+  ctx.ClangImporterOpts.ExtraArgs.insert(
+      ctx.ClangImporterOpts.ExtraArgs.end(),
+      fileMapping.extraArgs.begin(),
+      fileMapping.extraArgs.end());
+
   // Create a new Clang compiler invocation.
   {
     if (auto ClangArgs = importer->getClangCC1Arguments(ctx, VFS))
--- a/lib/ClangImporter/ClangIncludePaths.cpp	1970-01-01 00:00:01.000000000 +0000
+++ b/lib/ClangImporter/ClangIncludePaths.cpp	2025-10-21 14:32:26.864394627 +0000
@@ -21,6 +21,7 @@
 #include "clang/Driver/ToolChain.h"
 #include "clang/Frontend/CompilerInstance.h"
 #include "llvm/WindowsDriver/MSVCPaths.h"
+#include <cstdlib>
 
 using namespace swift;
 
@@ -306,9 +307,71 @@
                                      {"cstdlib", "string", "vector"}, vfs)) {
     cxxStdlibDir = dir.value();
   } else {
-    if (!suppressDiagnostic)
-      ctx.Diags.diagnose(SourceLoc(), diag::libstdcxx_not_found, triple.str());
-    return;
+    // FALLBACK: Try reading CPLUS_INCLUDE_PATH from environment.
+    // This is needed because Swift doesn't go through the full clang driver
+    // command construction that processes environment variables into -cxx-isystem
+    // arguments. When AddClangCXXStdlibIncludeArgs fails to find GCC (e.g., due
+    // to --gcc-toolchain pointing to wrong location or GCC detection failing),
+    // parsedStdlibArgs will be empty and findFirstIncludeDir returns nullopt.
+    // In Guix, CPLUS_INCLUDE_PATH is set by the build environment.
+    const char *cplusIncludePath = std::getenv("CPLUS_INCLUDE_PATH");
+    if (cplusIncludePath) {
+      llvm::SmallVector<llvm::StringRef, 8> envPaths;
+      llvm::StringRef(cplusIncludePath).split(envPaths, ':', -1, false);
+
+      for (const auto &envPath : envPaths) {
+        Path dir(envPath.str());
+        // Check if this directory contains C++ stdlib headers
+        Path testFile(dir);
+        llvm::sys::path::append(testFile, "cstdlib");
+        if (vfs->exists(testFile)) {
+          llvm::sys::path::remove_dots(dir, /*remove_dot_dot=*/true);
+          cxxStdlibDir = dir;
+          break;
+        }
+      }
+    }
+
+    if (cxxStdlibDir.empty()) {
+      if (!suppressDiagnostic)
+        ctx.Diags.diagnose(SourceLoc(), diag::libstdcxx_not_found, triple.str());
+      return;
+    }
+  }
+
+  // ADD INCLUDE PATHS FOR ARCH-SPECIFIC HEADERS:
+  // GCC's libstdc++ has architecture-specific headers in subdirectories.
+  // Standard clang driver adds THREE separate -internal-isystem include paths:
+  //   1. /path/to/gcc/include/c++            (base: cstdlib, string, vector, etc.)
+  //   2. /path/to/gcc/include/c++/TRIPLE     (arch: bits/c++config.h, ext/*, etc.)
+  //   3. /path/to/gcc/include/c++/backward   (backward compatibility headers)
+  // This allows clang to find both generic headers (cstddef) and arch-specific
+  // headers (bits/c++config.h) in their respective directories.
+  //
+  // We add these three paths as -isystem arguments via fileMapping.extraArgs.
+  // This is equivalent to what clang's AddClangCXXStdlibIncludeArgs does when
+  // it calls addSystemInclude three times in Gnu.cpp:addLibStdCXXIncludePaths.
+  // Using -isystem instead of VFS redirects ensures error messages reference
+  // real filesystem paths that users can verify exist.
+
+  // 1. Base directory (already found above in cxxStdlibDir)
+  fileMapping.extraArgs.push_back("-isystem");
+  fileMapping.extraArgs.push_back(std::string(cxxStdlibDir));
+
+  // 2. Architecture-specific subdirectory (e.g., x86_64-unknown-linux-gnu)
+  Path archSpecificDir(cxxStdlibDir);
+  llvm::sys::path::append(archSpecificDir, triple.str());
+  if (vfs->exists(archSpecificDir)) {
+    fileMapping.extraArgs.push_back("-isystem");
+    fileMapping.extraArgs.push_back(std::string(archSpecificDir));
+  }
+
+  // 3. Backward compatibility directory
+  Path backwardDir(cxxStdlibDir);
+  llvm::sys::path::append(backwardDir, "backward");
+  if (vfs->exists(backwardDir)) {
+    fileMapping.extraArgs.push_back("-isystem");
+    fileMapping.extraArgs.push_back(std::string(backwardDir));
   }
 
   Path actualModuleMapPath;

A gnu/packages/patches/swift-6.2-exclude-scan-test.patch => gnu/packages/patches/swift-6.2-exclude-scan-test.patch +17 -0
@@ 0,0 1,17 @@
Author: Danny Milosavljevic <dannym@friendly-machines.com>
Date: 2025-10-20
Subject: Move test to tests.

--- a/tools/CMakeLists.txt	1970-01-01 00:00:01.000000000 +0000
+++ b/tools/CMakeLists.txt	2025-10-21 15:10:03.861123680 +0000
@@ -27,9 +27,9 @@
 add_swift_tool_subdirectory(libStaticMirror)
 add_swift_tool_subdirectory(libMockPlugin)
 add_swift_tool_subdirectory(swift-plugin-server)
-add_swift_tool_subdirectory(swift-scan-test)
 
 if(SWIFT_INCLUDE_TESTS OR SWIFT_INCLUDE_TEST_BINARIES)
+  add_swift_tool_subdirectory(swift-scan-test)
   add_swift_tool_subdirectory(swift-ide-test)
   add_swift_tool_subdirectory(swift-remoteast-test)
   add_swift_tool_subdirectory(lldb-moduleimport-test)

M gnu/packages/swift.scm => gnu/packages/swift.scm +176 -2
@@ 21,6 21,7 @@
  #:use-module ((guix licenses) #:prefix license:)
  #:use-module (guix git-download)
  #:use-module (guix gexp)
  #:use-module (guix utils)
  #:use-module (guix build-system cmake)
  #:use-module (gnu packages)
  #:use-module (gnu packages base)


@@ 41,8 42,6 @@

(define %swift-bootstrap-version "5.7.3")

(define %swift-6.2-version "6.2")

(define %swift-bootstrap-source
  (origin
    (method git-fetch)


@@ 57,6 56,24 @@
    (patches (search-patches "swift-5.7.3-sdk-path.patch"
                             "swift-5.7.3-sourcekit-rpath.patch"))))

(define %swift-6.2-version "6.2")

(define %swift-6.2-source
  (origin
    (method git-fetch)
    (uri (git-reference
          (url "https://github.com/apple/swift.git")
          (commit (string-append "swift-" %swift-6.2-version
                                 "-RELEASE"))))
    (file-name (git-file-name "swift" %swift-6.2-version))
    (sha256
     (base32
      "1615yxdjlglfq0skrj0kfxzlp6riig8nkn07qddh2r89whj3gv2g"))
    (patches (search-patches "swift-5.7.3-sdk-path.patch"
                             "swift-5.7.3-sourcekit-rpath.patch"
                             "swift-6.2-cplus-include-path.patch"
                             "swift-6.2-exclude-scan-test.patch"))))

(define-public swift-cmark
  (package
    (name "swift-cmark")


@@ 133,6 150,31 @@ Swift-specific modifications, required to build Swift 4.2.4.")
    (patches (search-patches "swift-corelibs-libdispatch-5.6.3-lock-cpp.patch"
                             "swift-corelibs-libdispatch-5.7.3-modulemap.patch"))))

(define %swift-libdispatch-6.2-source
  (origin
    (method git-fetch)
    (uri (git-reference
          (url "https://github.com/apple/swift-corelibs-libdispatch.git")
          (commit (string-append "swift-" %swift-6.2-version
                                 "-RELEASE"))))
    (file-name "swift-corelibs-libdispatch")
    (sha256
     (base32
      "1nrm69zwf7i5rxgc9gzdknl6p9aggfnzcrydh1qsvqhga3s8dvaf"))
    (patches (search-patches "swift-corelibs-libdispatch-5.6.3-lock-cpp.patch"))))

(define %swift-syntax-6.2-source
  (origin
    (method git-fetch)
    (uri (git-reference
          (url "https://github.com/swiftlang/swift-syntax.git")
          (commit (string-append "swift-" %swift-6.2-version
                                 "-RELEASE"))))
    (file-name "swift-syntax")
    (sha256
     (base32
      "17z2c7kign0cjvnsm2m75c4nsjr3wbxzlzybwb5pnpxnbvmmyxf9"))))

(define-public swift-bootstrap
  (package
    (name "swift-bootstrap")


@@ 339,3 381,135 @@ approach to safety, performance, and software design patterns.  This package
provides a bootstrap build of Swift 4.2.4 compiled from C++ without requiring
a previous Swift compiler.")
    (license license:asl2.0)))

(define-public swift-6.2
  (package
    (inherit swift-bootstrap)
    (name "swift")
    (version %swift-6.2-version)
    (source %swift-6.2-source)
    (arguments
     (substitute-keyword-arguments (package-arguments swift-bootstrap)
       ((#:configure-flags flags)
        #~(append (cons (string-append "-DCMAKE_INSTALL_RPATH="
                                       #$output "/lib/swift/linux:"
                                       #$output "/lib/swift/host/compiler:"
                                       #$output "/lib")
                        (filter (lambda (flag)
                                  (not (string-prefix? "-DCMAKE_INSTALL_RPATH=" flag)))
                                #$flags))
                  (list "-DSWIFT_BUILD_SWIFT_SYNTAX=TRUE"
                        (string-append "-DSWIFT_PATH_TO_SWIFT_SYNTAX_SOURCE="
                                       (assoc-ref %build-inputs "swift-syntax"))
                        "-DSWIFT_MODULE_CACHE_PATH=/tmp/module-cache"
                        "-DCMAKE_Swift_FLAGS=-module-cache-path /tmp/module-cache"
                        (string-append "-DCMAKE_Swift_COMPILER="
                                       (assoc-ref %build-inputs "swift-bootstrap")
                                       "/bin/swiftc")
                        "-DBOOTSTRAPPING_MODE=BOOTSTRAPPING"
                        ;; Disable Swift-in-Swift compiler components because Swift 6.2's
                        ;; CMake forces BOOTSTRAPPING_MODE=HOSTTOOLS when
                        ;; SWIFT_ENABLE_SWIFT_IN_SWIFT is enabled on Linux, which requires
                        ;; Swift 5.8+. We only have Swift 5.7.3 for bootstrap.
                        ;;
                        ;; What we lose by disabling SWIFT_ENABLE_SWIFT_IN_SWIFT:
                        ;;
                        ;; 1. 48 Swift-based optimizer passes:
                        ;;    - CopyToBorrowOptimization, AssumeSingleThreaded,
                        ;;      BooleanLiteralFolding, DestroyHoisting,
                        ;;      ComputeEscapeEffects, ComputeSideEffects,
                        ;;      DiagnoseInfiniteRecursion, InitializeStaticGlobals,
                        ;;      MandatoryRedundantLoadElimination,
                        ;;      EarlyRedundantLoadElimination, RedundantLoadElimination,
                        ;;      DeadStoreElimination, LifetimeDependenceDiagnostics,
                        ;;      LifetimeDependenceInsertion, LifetimeDependenceScopeFixup,
                        ;;      MergeCondFails, ObjCBridgingOptimization, ObjectOutliner,
                        ;;      DeinitDevirtualizer, ReleaseDevirtualizer,
                        ;;      LetPropertyLowering, FunctionStackProtection, Simplification,
                        ;;      OnoneSimplification, LateOnoneSimplification,
                        ;;      CleanupDebugSteps, NamedReturnValueOptimization,
                        ;;      StripObjectHeaders, StackPromotion, UpdateBorrowedFrom,
                        ;;      ExperimentalSwiftBasedClosureSpecialization,
                        ;;      AutodiffClosureSpecialization, AsyncDemotion,
                        ;;      MandatoryPerformanceOptimizations, ReadOnlyGlobalVariablesPass,
                        ;;      StackProtection, DiagnoseUnknownConstValues,
                        ;;      and various dumper/test passes
                        ;;
                        ;; 2. 2 C++ optimizer passes that are disabled without Swift-in-Swift
                        ;;    (they cause verification failures in C++-only mode):
                        ;;    - LoopRotate
                        ;;    - SimplifyCFG
                        ;;
                        ;; 3. Swift macro implementations (@OptionSet, @DebugDescription,
                        ;;    @TaskLocal, @Swiftify, @DistributedResolvable)
                        ;;    The stdlib has fallbacks with #if hasFeature(Macros), so it
                        ;;    builds without them.
                        ;;
                        ;; The compiler and stdlib will still build and work for all language
                        ;; features. Core functionality (parsing, type checking, SIL
                        ;; generation, code generation) is unaffected. However, generated code
                        ;; will be less optimized (159 C++ optimizer passes still work).
                        "-DSWIFT_ENABLE_SWIFT_IN_SWIFT=FALSE")))
       ((#:phases phases)
        #~(modify-phases #$phases
            (replace 'setup
              (lambda* (#:key inputs #:allow-other-keys)
                (substitute* "lib/Driver/UnixToolChains.cpp"
                 (("return \"gold\";")
                  "return \"\";"))
                (substitute* "include/swift/SIL/SILLinkage.h"
                  (("#include \"llvm/Support/ErrorHandling.h\"")
                   "#include <cstdint>\n#include \"llvm/Support/ErrorHandling.h\""))
                (substitute* "include/swift/Basic/ExternalUnion.h"
                  (("#include \"llvm/Support/ErrorHandling.h\"")
                   "#include <cstdint>\n#include \"llvm/Support/ErrorHandling.h\""))
                (substitute* "stdlib/CMakeLists.txt"
                  (("set\\(CMAKE_CXX_COMPILER \"\\$\\{SWIFT_NATIVE_LLVM_TOOLS_PATH\\}/clang\\+\\+\"\\)")
                   (string-append "set(CMAKE_CXX_COMPILER \""
                                  (assoc-ref %build-inputs "swift-llvm")
                                  "/bin/clang++\")"))
                  (("set\\(CMAKE_C_COMPILER \"\\$\\{SWIFT_NATIVE_LLVM_TOOLS_PATH\\}/clang\"\\)")
                   (string-append "set(CMAKE_C_COMPILER \""
                                  (assoc-ref %build-inputs "swift-llvm")
                                  "/bin/clang\")")))
                (substitute* "stdlib/public/Platform/CMakeLists.txt"
                  (("set\\(GLIBC_SYSROOT_RELATIVE_INCLUDE_PATH \"/usr/include\"\\)")
                   (string-append "set(GLIBC_SYSROOT_RELATIVE_INCLUDE_PATH \""
                                  (assoc-ref %build-inputs "glibc")
                                  "/include\")")))
                (substitute* "lib/Basic/CMakeLists.txt"
                  (("\\$\\{LLVM_MAIN_SRC_DIR\\}/cmake/modules/GenerateVersionFromVCS.cmake")
                   "${LLVM_CMAKE_DIR}/GenerateVersionFromVCS.cmake"))
                (substitute* "lib/Option/CMakeLists.txt"
                  (("\\$\\{LLVM_MAIN_SRC_DIR\\}/\\.\\./clang/tools/driver/features\\.json")
                   "${LLVM_BUILD_BINARY_DIR}/share/clang/features.json"))
                ;; swiftBasic uses clangBasic symbols in Platform.cpp (DarwinSDKInfo)
                ;; but doesn't declare it as a PUBLIC dependency. Add clangBasic to
                ;; executables that link swiftBasic but not swiftAST (which provides it).
                (substitute* "tools/swift-scan-test/CMakeLists.txt"
                  (("swiftBasic\n" all)
                   (string-append all "                      clangBasic\n")))
                (substitute* "unittests/Remangler/CMakeLists.txt"
                  (("swiftBasic\n" all)
                   (string-append all "  clangBasic\n")))
                ;; Fix cmark-gfm path - use CMake-installed export with correct include paths
                (substitute* "cmake/modules/SwiftSharedCMakeConfig.cmake"
                  (("\\$\\{PATH_TO_CMARK_BUILD\\}/src/cmarkTargets\\.cmake")
                   "${PATH_TO_CMARK_BUILD}/lib/cmake/cmark-gfm/cmark-gfm.cmake"))
                ))))))
    (native-inputs
     (list cmake
           ninja
           perl
           pkg-config
           python-3
           swift-bootstrap
           swift-cmark-6.2
           %swift-libdispatch-6.2-source
           %swift-syntax-6.2-source))
    (inputs
     (list glibc icu4c libedit libxml2 swift-llvm-6.2 `(,util-linux "lib")))
    (synopsis "Swift programming language")
    (description
     "Swift is a general-purpose programming language built using a modern
approach to safety, performance, and software design patterns.")))