swiftPackages.swift{,-unwrapped}: get libc++ headers from Swift’s LLVM

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.
This commit is contained in:
Emily
2025-09-02 04:14:28 +01:00
parent 809f7d037c
commit 37cad5dfd5
3 changed files with 26 additions and 66 deletions
@@ -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
# Swifts 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.
@@ -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
@@ -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
# Swifts Clang.
+ lib.optionalString (clang.libcxx != null) ''
include -isystem "${lib.getDev swift}/include/c++/v1" > $out/nix-support/libcxx-cxxflags
'';
});