From 37cad5dfd5c1a33f5e4e0b383fd1825cdac47b7c Mon Sep 17 00:00:00 2001 From: Emily Date: Mon, 11 Aug 2025 15:36:06 +0100 Subject: [PATCH] =?UTF-8?q?swiftPackages.swift{,-unwrapped}:=20get=20libc+?= =?UTF-8?q?+=20headers=20from=20Swift=E2=80=99s=20LLVM?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit libc++ only supports a limited range of Clang versions, so this was relying on the LLVM version corresponding to the one used in Swift’s fork. Since Swift builds its own LLVM 15 anyway, we can simply install the required libc++ headers along with it. --- .../compilers/swift/compiler/default.nix | 24 ++++++- .../patches/swift-darwin-libcxx-flags.patch | 63 ------------------- .../compilers/swift/wrapper/default.nix | 5 ++ 3 files changed, 26 insertions(+), 66 deletions(-) delete mode 100644 pkgs/development/compilers/swift/compiler/patches/swift-darwin-libcxx-flags.patch diff --git a/pkgs/development/compilers/swift/compiler/default.nix b/pkgs/development/compilers/swift/compiler/default.nix index 891e209dca4d..27bcd8b7ac6b 100644 --- a/pkgs/development/compilers/swift/compiler/default.nix +++ b/pkgs/development/compilers/swift/compiler/default.nix @@ -146,7 +146,10 @@ let -e 's|^\s*exec|exec -a "$0"|g' \ -e 's|^\[\[ "${clang.cc}/bin/clang" = \*++ ]]|[[ "$0" = *++ ]]|' \ -e "s|${clang.cc}/bin/clang|$unwrappedClang|g" \ - -e "s|^\(\s*\)\($unwrappedClang\) \"@\\\$responseFile\"|\1argv0=\$0\n\1${bash}/bin/bash -c \"exec -a '\$argv0' \2 '@\$responseFile'\"|" + -e "s|^\(\s*\)\($unwrappedClang\) \"@\\\$responseFile\"|\1argv0=\$0\n\1${bash}/bin/bash -c \"exec -a '\$argv0' \2 '@\$responseFile'\"|" \ + ${lib.optionalString (clang.libcxx != null) '' + -e 's|$NIX_CXXSTDLIB_COMPILE_${clang.suffixSalt}|-isystem '$SWIFT_BUILD_ROOT'/libcxx/include/c++/v1|g' + ''} chmod a+x "$targetFile" ''; @@ -180,7 +183,10 @@ let sed < '${swiftWrapper}' > "$targetFile" \ -e "s|@prog@|'$unwrappedSwift'|g" \ -e 's|@cc_wrapper@|${clangForWrappers}|g' \ - -e 's|exec "$prog"|exec -a "$0" "$prog"|g' + -e 's|exec "$prog"|exec -a "$0" "$prog"|g' \ + ${lib.optionalString (clang.libcxx != null) '' + -e 's|$NIX_CXXSTDLIB_COMPILE_${clang.suffixSalt}|-isystem '$SWIFT_BUILD_ROOT'/libcxx/include/c++/v1|g' + ''} chmod a+x "$targetFile" ''; @@ -326,7 +332,6 @@ stdenv.mkDerivation { inherit clang; } } - patch -p1 -d swift -i ${./patches/swift-darwin-libcxx-flags.patch} patch -p1 -d swift -i ${ replaceVars ./patches/swift-darwin-plistbuddy-workaround.patch { inherit swiftArch; @@ -505,6 +510,19 @@ stdenv.mkDerivation { cmakeFlags="-GNinja" buildProject swift-cmark + ${lib.optionalString (clang.libcxx != null) '' + # Install the libc++ headers corresponding to the LLVM version of + # Swift’s Clang. + cmakeFlags=" + -GNinja + -DLLVM_ENABLE_RUNTIMES=libcxx;libcxxabi + -DLIBCXXABI_INSTALL_INCLUDE_DIR=$dev/include/c++/v1 + " + ninjaFlags="install-cxx-headers install-cxxabi-headers" + buildProject libcxx llvm-project/runtimes + unset ninjaFlags + ''} + # Some notes: # - The Swift build just needs Clang. # - We can further reduce targets to just our targetPlatform. diff --git a/pkgs/development/compilers/swift/compiler/patches/swift-darwin-libcxx-flags.patch b/pkgs/development/compilers/swift/compiler/patches/swift-darwin-libcxx-flags.patch deleted file mode 100644 index c2b5adafa592..000000000000 --- a/pkgs/development/compilers/swift/compiler/patches/swift-darwin-libcxx-flags.patch +++ /dev/null @@ -1,63 +0,0 @@ -On Darwin, the SDK is a directory of stubs, and libc++ lives separately. We -need to patch the CMake files in several places to make the build for C++ -interop succeed. The required flags can be read from cc-wrapper support files. - ---- a/SwiftCompilerSources/CMakeLists.txt -+++ b/SwiftCompilerSources/CMakeLists.txt -@@ -105,18 +105,11 @@ function(add_swift_compiler_modules_library name) - get_filename_component(swift_exec_bin_dir ${ALS_SWIFT_EXEC} DIRECTORY) - set(sdk_option ${sdk_option} "-resource-dir" "${swift_exec_bin_dir}/../bootstrapping0/lib/swift") - endif() -- if(NOT EXISTS "${sdk_path}/usr/include/c++") -- # Darwin SDKs in Xcode 12 or older do not include libc++, which prevents clang from finding libc++ when invoked -- # from ClangImporter. This results in build errors. To workaround this, let's explicitly pass the path to libc++ -- # to clang. -- message(WARNING "Building with an outdated Darwin SDK: libc++ missing from the ${SWIFT_HOST_VARIANT_SDK} SDK. Will use libc++ from the toolchain.") -- get_filename_component(absolute_libcxx_path "${CMAKE_C_COMPILER}/../../include/c++/v1" REALPATH) -- if (EXISTS "${absolute_libcxx_path}") -- set(sdk_option ${sdk_option} "-Xcc" "-isystem" "-Xcc" "${absolute_libcxx_path}") -- else() -- message(ERROR "libc++ not found in the toolchain.") -- endif() -- endif() -+ file(READ "$ENV{NIX_CC}/nix-support/libcxx-cxxflags" nix_libcxx_cxxflags) -+ separate_arguments(nix_libcxx_cxxflags) -+ foreach(nix_libcxx_cxxflag ${nix_libcxx_cxxflags}) -+ set(sdk_option ${sdk_option} "-Xcc" "${nix_libcxx_cxxflag}") -+ endforeach() - elseif(BOOTSTRAPPING_MODE STREQUAL "CROSSCOMPILE") - set(sdk_option "-sdk" "${SWIFT_SDK_${SWIFT_HOST_VARIANT_SDK}_ARCH_${SWIFT_HOST_VARIANT_ARCH}_PATH}") - get_filename_component(swift_exec_bin_dir ${ALS_SWIFT_EXEC} DIRECTORY) ---- a/cmake/modules/SwiftConfigureSDK.cmake -+++ b/cmake/modules/SwiftConfigureSDK.cmake -@@ -270,6 +270,18 @@ macro(configure_sdk_darwin - # Add this to the list of known SDKs. - list(APPEND SWIFT_CONFIGURED_SDKS "${prefix}") - -+ set(cxx_overlay_opt "") -+ if("${prefix}" STREQUAL "OSX") -+ file(READ "$ENV{NIX_CC}/nix-support/libcxx-cxxflags" nix_libcxx_cxxflags) -+ separate_arguments(nix_libcxx_cxxflags) -+ foreach(nix_libcxx_cxxflag ${nix_libcxx_cxxflags}) -+ set(cxx_overlay_opt ${cxx_overlay_opt} "-Xcc" "${nix_libcxx_cxxflag}") -+ endforeach() -+ endif() -+ set(SWIFT_SDK_${prefix}_CXX_OVERLAY_SWIFT_COMPILE_FLAGS -+ ${cxx_overlay_opt} -+ CACHE STRING "Extra flags for compiling the C++ overlay") -+ - _report_sdk("${prefix}") - endmacro() - ---- a/stdlib/public/Cxx/std/CMakeLists.txt -+++ b/stdlib/public/Cxx/std/CMakeLists.txt -@@ -145,6 +145,9 @@ add_swift_target_library(swiftstd STATIC NO_LINK_NAME IS_STDLIB - SWIFT_COMPILE_FLAGS_LINUX - ${SWIFT_SDK_LINUX_CXX_OVERLAY_SWIFT_COMPILE_FLAGS} - -+ SWIFT_COMPILE_FLAGS_OSX -+ ${SWIFT_SDK_OSX_CXX_OVERLAY_SWIFT_COMPILE_FLAGS} -+ - LINK_FLAGS "${SWIFT_RUNTIME_SWIFT_LINK_FLAGS}" - TARGET_SDKS ALL_APPLE_PLATFORMS LINUX - INSTALL_IN_COMPONENT compiler diff --git a/pkgs/development/compilers/swift/wrapper/default.nix b/pkgs/development/compilers/swift/wrapper/default.nix index 88bb9a3c2139..e446bec66868 100644 --- a/pkgs/development/compilers/swift/wrapper/default.nix +++ b/pkgs/development/compilers/swift/wrapper/default.nix @@ -41,6 +41,11 @@ stdenv.mkDerivation ( --replace-fail \ "-resource-dir=$out/resource-root" \ "-resource-dir=${lib.getLib swift}/lib/swift/clang" + '' + # We need the libc++ headers corresponding to the LLVM version of + # Swift’s Clang. + + lib.optionalString (clang.libcxx != null) '' + include -isystem "${lib.getDev swift}/include/c++/v1" > $out/nix-support/libcxx-cxxflags ''; });