diff --git a/schemes/release-6.0/manifest.json b/schemes/release-6.0/manifest.json index 5926ed5f..c53c8a5c 100644 --- a/schemes/release-6.0/manifest.json +++ b/schemes/release-6.0/manifest.json @@ -1,9 +1,9 @@ { "update-checkout-scheme": "release/6.0", - "base-tag": "swift-6.0-DEVELOPMENT-SNAPSHOT-2024-10-12-a", + "base-tag": "swift-6.0.2-RELEASE", "build-compiler": false, "icu4c": ["https://github.com/swiftwasm/icu4c-wasi/releases/download/0.8.0/icu4c-wasi.tar.xz"], "libxml2": ["https://github.com/swiftwasm/libxml2-wasm/releases/download/2.0.0/libxml2-wasm32-unknown-wasi.tar.gz"], "wasi-sysroot": "https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-21/wasi-sysroot-21.0.tar.gz", - "swift-org-download-channel": "swift-6.0-branch" + "swift-org-download-channel": "swift-6.0.2-release" } diff --git a/schemes/release-6.0/swift-corelibs-foundation/0001-build-Repair-the-build-on-WASI-platform.patch b/schemes/release-6.0/swift-corelibs-foundation/0001-build-Repair-the-build-on-WASI-platform.patch new file mode 100644 index 00000000..66d521d2 --- /dev/null +++ b/schemes/release-6.0/swift-corelibs-foundation/0001-build-Repair-the-build-on-WASI-platform.patch @@ -0,0 +1,96 @@ +From acdc7e138ff67f02c261bb6372f755c2fdb6bc7b Mon Sep 17 00:00:00 2001 +From: Yuta Saito +Date: Sat, 30 Mar 2024 10:28:40 +0000 +Subject: [PATCH] build: Repair the build on WASI platform + +Cherry picked from https://github.com/apple/swift-corelibs-foundation/pull/4934 + +(cherry picked from commit 51ee6906be0556eb63cd35a16ad4167f69f16a63) +--- + Package.swift | 20 ++++++++++++++++++-- + Sources/CoreFoundation/CFBundle.c | 8 +++++++- + Sources/CoreFoundation/CFString.c | 2 +- + 3 files changed, 26 insertions(+), 4 deletions(-) + +diff --git a/Package.swift b/Package.swift +index 4ead01c3..8aa40e79 100644 +--- a/Package.swift ++++ b/Package.swift +@@ -3,6 +3,16 @@ + + import PackageDescription + ++let platformsWithThreads: [Platform] = [ ++ .iOS, ++ .macOS, ++ .tvOS, ++ .watchOS, ++ .macCatalyst, ++ .driverKit, ++ .android, ++ .linux, ++] + var dispatchIncludeFlags: [CSetting] + if let environmentPath = Context.environment["DISPATCH_INCLUDE_PATH"] { + dispatchIncludeFlags = [.unsafeFlags([ +@@ -31,8 +41,11 @@ let coreFoundationBuildSettings: [CSetting] = [ + .define("DEPLOYMENT_ENABLE_LIBDISPATCH"), + .define("DEPLOYMENT_RUNTIME_SWIFT"), + .define("HAVE_STRUCT_TIMESPEC"), +- .define("SWIFT_CORELIBS_FOUNDATION_HAS_THREADS"), ++ .define("SWIFT_CORELIBS_FOUNDATION_HAS_THREADS", .when(platforms: platformsWithThreads)), + .define("_GNU_SOURCE", .when(platforms: [.linux, .android])), ++ .define("_WASI_EMULATED_SIGNAL", .when(platforms: [.wasi])), ++ .define("HAVE_STRLCPY", .when(platforms: [.wasi])), ++ .define("HAVE_STRLCAT", .when(platforms: [.wasi])), + .unsafeFlags([ + "-Wno-shorten-64-to-32", + "-Wno-deprecated-declarations", +@@ -61,8 +74,11 @@ let interfaceBuildSettings: [CSetting] = [ + .define("CF_BUILDING_CF"), + .define("DEPLOYMENT_ENABLE_LIBDISPATCH"), + .define("HAVE_STRUCT_TIMESPEC"), +- .define("SWIFT_CORELIBS_FOUNDATION_HAS_THREADS"), ++ .define("SWIFT_CORELIBS_FOUNDATION_HAS_THREADS", .when(platforms: platformsWithThreads)), + .define("_GNU_SOURCE", .when(platforms: [.linux, .android])), ++ .define("_WASI_EMULATED_SIGNAL", .when(platforms: [.wasi])), ++ .define("HAVE_STRLCPY", .when(platforms: [.wasi])), ++ .define("HAVE_STRLCAT", .when(platforms: [.wasi])), + .unsafeFlags([ + "-Wno-shorten-64-to-32", + "-Wno-deprecated-declarations", +diff --git a/Sources/CoreFoundation/CFBundle.c b/Sources/CoreFoundation/CFBundle.c +index 8026a262..05afe988 100644 +--- a/Sources/CoreFoundation/CFBundle.c ++++ b/Sources/CoreFoundation/CFBundle.c +@@ -596,7 +596,13 @@ static CFBundleRef _CFBundleGetBundleWithIdentifier(CFStringRef bundleID, void * + + CFBundleRef CFBundleGetBundleWithIdentifier(CFStringRef bundleID) { + // Use the frame that called this as a hint +- return _CFBundleGetBundleWithIdentifier(bundleID, __builtin_return_address(0)); ++ void *hint; ++#if TARGET_OS_WASI ++ hint = NULL; ++#else ++ hint = __builtin_frame_address(0); ++#endif ++ return _CFBundleGetBundleWithIdentifier(bundleID, hint); + } + + CFBundleRef _CFBundleGetBundleWithIdentifierWithHint(CFStringRef bundleID, void *pointer) { +diff --git a/Sources/CoreFoundation/CFString.c b/Sources/CoreFoundation/CFString.c +index 1de46dac..94a6c86d 100644 +--- a/Sources/CoreFoundation/CFString.c ++++ b/Sources/CoreFoundation/CFString.c +@@ -28,7 +28,7 @@ + #include "CFRuntime_Internal.h" + #include + #include <_foundation_unicode/uchar.h> +-#if TARGET_OS_MAC || TARGET_OS_WIN32 || TARGET_OS_LINUX || TARGET_OS_BSD ++#if TARGET_OS_MAC || TARGET_OS_WIN32 || TARGET_OS_LINUX || TARGET_OS_BSD || TARGET_OS_WASI + #include "CFConstantKeys.h" + #include "CFStringLocalizedFormattingInternal.h" + #endif +-- +2.46.0 + diff --git a/schemes/release-6.0/swift-corelibs-foundation/0002-Reflect-Package.swift-WASI-changes-in-CMakeLists.txt.patch b/schemes/release-6.0/swift-corelibs-foundation/0002-Reflect-Package.swift-WASI-changes-in-CMakeLists.txt.patch new file mode 100644 index 00000000..e710ad45 --- /dev/null +++ b/schemes/release-6.0/swift-corelibs-foundation/0002-Reflect-Package.swift-WASI-changes-in-CMakeLists.txt.patch @@ -0,0 +1,66 @@ +From 8873088ed6903231235bf8f338358a68157794a8 Mon Sep 17 00:00:00 2001 +From: Max Desiatov +Date: Mon, 5 Aug 2024 20:28:46 +0100 +Subject: [PATCH] Reflect `Package.swift` WASI changes in `CMakeLists.txt` + +--- + CMakeLists.txt | 26 ++++++++++++++++++++++++-- + 1 file changed, 24 insertions(+), 2 deletions(-) + +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 30d960cb..edb6cf06 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -115,7 +115,6 @@ list(APPEND _Foundation_common_build_flags + "-DCF_BUILDING_CF" + "-DDEPLOYMENT_ENABLE_LIBDISPATCH" + "-DHAVE_STRUCT_TIMESPEC" +- "-DSWIFT_CORELIBS_FOUNDATION_HAS_THREADS" + "-Wno-shorten-64-to-32" + "-Wno-deprecated-declarations" + "-Wno-unreachable-code" +@@ -127,6 +126,18 @@ list(APPEND _Foundation_common_build_flags + "-Wno-switch" + "-fblocks") + ++if(CMAKE_SYSTEM_NAME STREQUAL "WASI") ++ list(APPEND _Foundation_common_build_flags ++ "-D_WASI_EMULATED_SIGNAL" ++ "-DHAVE_STRLCPY" ++ "-DHAVE_STRLCAT" ++ ) ++else() ++ list(APPEND _Foundation_common_build_flags ++ "-DSWIFT_CORELIBS_FOUNDATION_HAS_THREADS" ++ ) ++endif() ++ + if(NOT "${CMAKE_C_SIMULATE_ID}" STREQUAL "MSVC") + list(APPEND _Foundation_common_build_flags + "-fconstant-cfstrings" +@@ -154,10 +165,21 @@ set(_Foundation_swift_build_flags) + list(APPEND _Foundation_swift_build_flags + "-swift-version 6" + "-DDEPLOYMENT_RUNTIME_SWIFT" +- "-DSWIFT_CORELIBS_FOUNDATION_HAS_THREADS" + "-Xfrontend" + "-require-explicit-sendable") + ++if(CMAKE_SYSTEM_NAME STREQUAL "WASI") ++ list(APPEND _Foundation_swift_build_flags ++ "-D_WASI_EMULATED_SIGNAL" ++ "-DHAVE_STRLCPY" ++ "-DHAVE_STRLCAT" ++ ) ++else() ++ list(APPEND _Foundation_swift_build_flags ++ "-DSWIFT_CORELIBS_FOUNDATION_HAS_THREADS" ++ ) ++endif() ++ + if(CMAKE_SYSTEM_NAME STREQUAL "Linux" OR CMAKE_SYSTEM_NAME STREQUAL "Android") + list(APPEND _Foundation_common_build_flags + "-D_GNU_SOURCE") +-- +2.46.0 + diff --git a/schemes/release-6.0/swift-foundation/0001-6.0-Fix-WASI-support-825.patch b/schemes/release-6.0/swift-foundation/0001-6.0-Fix-WASI-support-825.patch new file mode 100644 index 00000000..582e68f3 --- /dev/null +++ b/schemes/release-6.0/swift-foundation/0001-6.0-Fix-WASI-support-825.patch @@ -0,0 +1,1014 @@ +From b0abbb45992f33c23c40f88915456734d41b1dee Mon Sep 17 00:00:00 2001 +From: Max Desiatov +Date: Thu, 29 Aug 2024 18:27:06 +0100 +Subject: [PATCH] 6.0: Fix WASI support (#825) + +* Add explicit include of `wasi/libc-environ.h` (#786) + +This is necessary to get the `__wasilibc_get_environ` function +declaration. + +(cherry picked from commit 243066f12d0b6f1ab8ad9fefd8526b2383641892) + +* Add explicit void type parameter to C functions without parameters (#775) + +C functions with `()` as parameter list can take any number of +parameters. But WebAssembly requires static signature information for +every function call, so we need to explicitly specify `(void)` to +indicate that the function takes no parameters. + +(cherry picked from commit 8f34f38f30858f7b9dfa9a40b07c18fd7a7b93ae) + +* Exclude EREMOTE definition for WASI platform (#778) + +WASI does not define the EREMOTE error code. + +(cherry picked from commit 6bb5ff7b29ed65a722119057d406ffd4bdcdf1b9) + +* Throw `.featureUnsupported` when attempting to create temp files on WASI (#779) + +WASI does not have temp directory concept, and does not provide mktemp +family of functions, so attempting to create a temporary file should be +considered a feature unsupported. + +(cherry picked from commit fb11420dc6f546e67fce249c15bb17e208c40aff) + +* Fix `operatingSystemVersion` on WASI (#782) + +The `operatingSystemVersion` property type is a tuple but the it was +returning an `OperatingSystemVersion` instance on unknown platforms. + +(cherry picked from commit a8f12255dbf98e0899af84d0e674ab71be30bd85) + +* Guard out extended or fs attributes related code on WASI (#784) + +This commit guards out the extended attributes and file system +attributes related code on WASI as WASI does not support these +features. Just return nothing or ignore the set request. + +(cherry picked from commit fab7195ea2503d296ce80ff6bc5cdb6da8c71b9c) + +* Guard out user/group related code on WASI (#783) + +* Guard out user/group related code on WASI + +This change guards out the user/group related code on WASI, as WASI does +not have the concept of users or groups. + +* Throw explicit unsupported error if trying to set user or group on WASI + +Instead of implicitly ignoring user-given values, we should throw +exception to make it clear that those values cannot be set on WASI. + +(cherry picked from commit 0b3974d35103fd1e3e5213f2cdcefc1fd7fa84f4) + +* Skip sticky-bit check in `isDeletableFile` on WASI (#785) + +WASI does not surface the sticky bit and getuid, so we cannot check +whether the file is actually deletable before attempting to delete it. + +(cherry picked from commit e90b6c3f90e52f840fc087b05468f430eae1d05a) + +* Implement `_copyRegularFile` for WASI without `sendfile` (#787) + +WASI doesn't have `sendfile`, so we need to implement the copy in user +space with `read` and `write`. It's not as efficient as `sendfile`, but +it's the best we can do. + +(cherry picked from commit 2a6afeb50aecc5fdfaa7b739399afff1eca024d1) + +* Port `LockedState` and `_ThreadLocal` to WASI without any locking (#780) + +(cherry picked from commit aa68eebebcb8dd16b9636c54e580e0ad32bb57e3) + +* Add WASI platform conditions for libc imports and word size (#776) + +* Add `import WASILibc` statements to libc import chains + +* Declare wasm32 arch as 32-bit environment + +* Switch to _pointerBitWidth for architecture checks + +This change switches the architecture checks in Data.swift to use the +_pointerBitWidth instead of the arch() checks for consistency with newer +platforms. + +(cherry picked from commit c82d1673eb112ac62e4f770947c8a238a7659163) + +* Enable wasi-libc emulation features (#777) + +* Enable wasi-libc emulation features + +Those features require explicit macro definitions to be enabled, so add +them to the package definition. Only affects WASI builds. + +* Prefer `TARGET_OS_WASI` over `__wasi__` + +And explain why we need definition checks for `signal.h` and `sys/mman.h` + +(cherry picked from commit c86692f7e7b6d7cb1625d66ee6ff2618011f22f1) + +--------- + +Co-authored-by: Yuta Saito +--- + CMakeLists.txt | 8 +++++ + Package.swift | 35 ++++++++++++++----- + Sources/FoundationEssentials/CMakeLists.txt | 1 + + .../Calendar/Calendar.swift | 2 ++ + .../Calendar/Calendar_Gregorian.swift | 2 ++ + .../Data/Data+Reading.swift | 2 ++ + .../Data/Data+Writing.swift | 9 +++++ + Sources/FoundationEssentials/Data/Data.swift | 14 ++++---- + Sources/FoundationEssentials/Date.swift | 2 ++ + .../Decimal/Decimal+Math.swift | 2 ++ + .../Error/CocoaError+FilePath.swift | 2 ++ + .../Error/ErrorCodes+POSIX.swift | 4 +++ + .../FileManager/FileManager+Basics.swift | 2 ++ + .../FileManager/FileManager+Directories.swift | 2 ++ + .../FileManager/FileManager+Files.swift | 23 ++++++++++-- + .../FileManager+SymbolicLinks.swift | 2 ++ + .../FileManager/FileManager+Utilities.swift | 6 ++-- + .../FileManager/FileOperations.swift | 23 ++++++++++++ + ...yInteger+NumericStringRepresentation.swift | 2 ++ + .../FoundationEssentials/LockedState.swift | 9 +++++ + Sources/FoundationEssentials/Platform.swift | 4 +-- + .../ProcessInfo/ProcessInfo.swift | 4 ++- + .../PropertyList/OpenStepPlist.swift | 2 ++ + .../String/String+Path.swift | 4 +++ + .../FoundationEssentials/_ThreadLocal.swift | 8 +++++ + .../CMakeLists.txt | 1 + + .../Calendar/Calendar_ICU.swift | 2 ++ + .../Formatting/Duration+Formatting.swift | 2 ++ + Sources/_FoundationCShims/include/_CStdlib.h | 16 ++++++++- + .../include/platform_shims.h | 12 +++---- + Sources/_FoundationCShims/platform_shims.c | 20 ++++++----- + 31 files changed, 189 insertions(+), 38 deletions(-) + +diff --git a/CMakeLists.txt b/CMakeLists.txt +index a8dc410..3243e53 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -116,6 +116,14 @@ foreach(version ${_SwiftFoundation_versions}) + endforeach() + endforeach() + ++# wasi-libc emulation feature flags ++set(_SwiftFoundation_wasi_libc_flags) ++if(CMAKE_SYSTEM_NAME STREQUAL "WASI") ++ list(APPEND _SwiftFoundation_wasi_libc_flags ++ "SHELL:$<$:-Xcc -D_WASI_EMULATED_SIGNAL>" ++ "SHELL:$<$:-Xcc -D_WASI_EMULATED_MMAN>") ++endif() ++ + include(GNUInstallDirs) + include(SwiftFoundationSwiftSupport) + +diff --git a/Package.swift b/Package.swift +index daaf638..67bce50 100644 +--- a/Package.swift ++++ b/Package.swift +@@ -70,6 +70,11 @@ var dependencies: [Package.Dependency] { + } + } + ++let wasiLibcCSettings: [CSetting] = [ ++ .define("_WASI_EMULATED_SIGNAL", .when(platforms: [.wasi])), ++ .define("_WASI_EMULATED_MMAN", .when(platforms: [.wasi])), ++] ++ + let package = Package( + name: "FoundationPreview", + platforms: [.macOS("13.3"), .iOS("16.4"), .tvOS("16.4"), .watchOS("9.4")], +@@ -91,15 +96,23 @@ let package = Package( + path: "Sources/Foundation"), + + // _FoundationCShims (Internal) +- .target(name: "_FoundationCShims", +- cSettings: [.define("_CRT_SECURE_NO_WARNINGS", +- .when(platforms: [.windows]))]), ++ .target( ++ name: "_FoundationCShims", ++ cSettings: [ ++ .define("_CRT_SECURE_NO_WARNINGS", .when(platforms: [.windows])) ++ ] + wasiLibcCSettings ++ ), + + // TestSupport (Internal) +- .target(name: "TestSupport", dependencies: [ +- "FoundationEssentials", +- "FoundationInternationalization", +- ], swiftSettings: availabilityMacros + concurrencyChecking), ++ .target( ++ name: "TestSupport", ++ dependencies: [ ++ "FoundationEssentials", ++ "FoundationInternationalization", ++ ], ++ cSettings: wasiLibcCSettings, ++ swiftSettings: availabilityMacros + concurrencyChecking ++ ), + + // FoundationEssentials + .target( +@@ -130,11 +143,14 @@ let package = Package( + ], + cSettings: [ + .define("_GNU_SOURCE", .when(platforms: [.linux])) +- ], ++ ] + wasiLibcCSettings, + swiftSettings: [ + .enableExperimentalFeature("VariadicGenerics"), + .enableExperimentalFeature("AccessLevelOnImport") +- ] + availabilityMacros + concurrencyChecking ++ ] + availabilityMacros + concurrencyChecking, ++ linkerSettings: [ ++ .linkedLibrary("wasi-emulated-getpid", .when(platforms: [.wasi])), ++ ] + ), + .testTarget( + name: "FoundationEssentialsTests", +@@ -166,6 +182,7 @@ let package = Package( + "CMakeLists.txt", + "Predicate/CMakeLists.txt" + ], ++ cSettings: wasiLibcCSettings, + swiftSettings: [ + .enableExperimentalFeature("AccessLevelOnImport") + ] + availabilityMacros + concurrencyChecking +diff --git a/Sources/FoundationEssentials/CMakeLists.txt b/Sources/FoundationEssentials/CMakeLists.txt +index 6dc5929..5525efe 100644 +--- a/Sources/FoundationEssentials/CMakeLists.txt ++++ b/Sources/FoundationEssentials/CMakeLists.txt +@@ -65,6 +65,7 @@ target_compile_options(FoundationEssentials PRIVATE + "SHELL:$<$:-Xfrontend -enable-experimental-feature -Xfrontend StrictConcurrency>" + "SHELL:$<$:-Xfrontend -enable-upcoming-feature -Xfrontend InferSendableFromCaptures>") + target_compile_options(FoundationEssentials PRIVATE ${_SwiftFoundation_availability_macros}) ++target_compile_options(FoundationEssentials PRIVATE ${_SwiftFoundation_wasi_libc_flags}) + target_compile_options(FoundationEssentials PRIVATE -package-name "SwiftFoundation") + + target_link_libraries(FoundationEssentials PUBLIC +diff --git a/Sources/FoundationEssentials/Calendar/Calendar.swift b/Sources/FoundationEssentials/Calendar/Calendar.swift +index 9de55b3..257b742 100644 +--- a/Sources/FoundationEssentials/Calendar/Calendar.swift ++++ b/Sources/FoundationEssentials/Calendar/Calendar.swift +@@ -20,6 +20,8 @@ import Glibc + import Musl + #elseif canImport(CRT) + import CRT ++#elseif os(WASI) ++import WASILibc + #endif + + #if FOUNDATION_FRAMEWORK +diff --git a/Sources/FoundationEssentials/Calendar/Calendar_Gregorian.swift b/Sources/FoundationEssentials/Calendar/Calendar_Gregorian.swift +index 797a8e8..8c25c77 100644 +--- a/Sources/FoundationEssentials/Calendar/Calendar_Gregorian.swift ++++ b/Sources/FoundationEssentials/Calendar/Calendar_Gregorian.swift +@@ -20,6 +20,8 @@ import Glibc + import Musl + #elseif canImport(CRT) + import CRT ++#elseif os(WASI) ++import WASILibc + #endif + + +diff --git a/Sources/FoundationEssentials/Data/Data+Reading.swift b/Sources/FoundationEssentials/Data/Data+Reading.swift +index 2540b14..48b9521 100644 +--- a/Sources/FoundationEssentials/Data/Data+Reading.swift ++++ b/Sources/FoundationEssentials/Data/Data+Reading.swift +@@ -27,6 +27,8 @@ import Musl + #elseif os(Windows) + import CRT + import WinSDK ++#elseif os(WASI) ++import WASILibc + #endif + + func _fgetxattr(_ fd: Int32, _ name: UnsafePointer!, _ value: UnsafeMutableRawPointer!, _ size: Int, _ position: UInt32, _ options: Int32) -> Int { +diff --git a/Sources/FoundationEssentials/Data/Data+Writing.swift b/Sources/FoundationEssentials/Data/Data+Writing.swift +index 1e75b43..0256e51 100644 +--- a/Sources/FoundationEssentials/Data/Data+Writing.swift ++++ b/Sources/FoundationEssentials/Data/Data+Writing.swift +@@ -29,6 +29,8 @@ import Musl + #elseif os(Windows) + import CRT + import WinSDK ++#elseif os(WASI) ++import WASILibc + #endif + + #if !NO_FILESYSTEM +@@ -129,6 +131,10 @@ private func cleanupTemporaryDirectory(at inPath: String?) { + + /// Caller is responsible for calling `close` on the `Int32` file descriptor. + private func createTemporaryFile(at destinationPath: String, inPath: PathOrURL, prefix: String, options: Data.WritingOptions) throws -> (Int32, String) { ++#if os(WASI) ++ // WASI does not have temp directories ++ throw CocoaError(.featureUnsupported) ++#else + var directoryPath = destinationPath + if !directoryPath.isEmpty && directoryPath.last! != "/" { + directoryPath.append("/") +@@ -183,6 +189,7 @@ private func createTemporaryFile(at destinationPath: String, inPath: PathOrURL, + } + } + } while true ++#endif // os(WASI) + } + + /// Returns `(file descriptor, temporary file path, temporary directory path)` +@@ -516,6 +523,7 @@ private func writeToFileAux(path inPath: PathOrURL, buffer: UnsafeRawBufferPoint + + cleanupTemporaryDirectory(at: temporaryDirectoryPath) + ++#if !os(WASI) // WASI does not support fchmod for now + if let mode { + // Try to change the mode if the path has not changed. Do our best, but don't report an error. + #if FOUNDATION_FRAMEWORK +@@ -539,6 +547,7 @@ private func writeToFileAux(path inPath: PathOrURL, buffer: UnsafeRawBufferPoint + fchmod(fd, mode) + #endif + } ++#endif // os(WASI) + } + } + } +diff --git a/Sources/FoundationEssentials/Data/Data.swift b/Sources/FoundationEssentials/Data/Data.swift +index 8bded85..ad3ac42 100644 +--- a/Sources/FoundationEssentials/Data/Data.swift ++++ b/Sources/FoundationEssentials/Data/Data.swift +@@ -76,6 +76,8 @@ import Glibc + import Musl + #elseif canImport(ucrt) + import ucrt ++#elseif canImport(WASILibc) ++import WASILibc + #endif + + #if os(Windows) +@@ -580,11 +582,11 @@ public struct Data : Equatable, Hashable, RandomAccessCollection, MutableCollect + @usableFromInline + @frozen + internal struct InlineData : Sendable { +-#if arch(x86_64) || arch(arm64) || arch(s390x) || arch(powerpc64) || arch(powerpc64le) ++#if _pointerBitWidth(_64) + @usableFromInline typealias Buffer = (UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, + UInt8, UInt8, UInt8, UInt8, UInt8, UInt8) //len //enum + @usableFromInline var bytes: Buffer +-#elseif arch(i386) || arch(arm) || arch(arm64_32) ++#elseif _pointerBitWidth(_32) + @usableFromInline typealias Buffer = (UInt8, UInt8, UInt8, UInt8, + UInt8, UInt8) //len //enum + @usableFromInline var bytes: Buffer +@@ -615,9 +617,9 @@ public struct Data : Equatable, Hashable, RandomAccessCollection, MutableCollect + @inlinable // This is @inlinable as a trivial initializer. + init(count: Int = 0) { + assert(count <= MemoryLayout.size) +-#if arch(x86_64) || arch(arm64) || arch(s390x) || arch(powerpc64) || arch(powerpc64le) ++#if _pointerBitWidth(_64) + bytes = (UInt8(0), UInt8(0), UInt8(0), UInt8(0), UInt8(0), UInt8(0), UInt8(0), UInt8(0), UInt8(0), UInt8(0), UInt8(0), UInt8(0), UInt8(0), UInt8(0)) +-#elseif arch(i386) || arch(arm) || arch(arm64_32) ++#elseif _pointerBitWidth(_32) + bytes = (UInt8(0), UInt8(0), UInt8(0), UInt8(0), UInt8(0), UInt8(0)) + #else + #error ("Unsupported architecture: initialization for Buffer is required for this architecture") +@@ -802,9 +804,9 @@ public struct Data : Equatable, Hashable, RandomAccessCollection, MutableCollect + } + } + +-#if arch(x86_64) || arch(arm64) || arch(s390x) || arch(powerpc64) || arch(powerpc64le) ++#if _pointerBitWidth(_64) + @usableFromInline internal typealias HalfInt = Int32 +-#elseif arch(i386) || arch(arm) || arch(arm64_32) ++#elseif _pointerBitWidth(_32) + @usableFromInline internal typealias HalfInt = Int16 + #else + #error ("Unsupported architecture: a definition of half of the pointer sized Int needs to be defined for this architecture") +diff --git a/Sources/FoundationEssentials/Date.swift b/Sources/FoundationEssentials/Date.swift +index b65066f..37548e4 100644 +--- a/Sources/FoundationEssentials/Date.swift ++++ b/Sources/FoundationEssentials/Date.swift +@@ -20,6 +20,8 @@ import Glibc + import Musl + #elseif canImport(WinSDK) + import WinSDK ++#elseif os(WASI) ++import WASILibc + #endif + + #if !FOUNDATION_FRAMEWORK +diff --git a/Sources/FoundationEssentials/Decimal/Decimal+Math.swift b/Sources/FoundationEssentials/Decimal/Decimal+Math.swift +index 7b35f11..eb344b2 100644 +--- a/Sources/FoundationEssentials/Decimal/Decimal+Math.swift ++++ b/Sources/FoundationEssentials/Decimal/Decimal+Math.swift +@@ -20,6 +20,8 @@ import Glibc + import Musl + #elseif canImport(CRT) + import CRT ++#elseif os(WASI) ++import WASILibc + #endif + + private let powerOfTen: [Decimal.VariableLengthInteger] = [ +diff --git a/Sources/FoundationEssentials/Error/CocoaError+FilePath.swift b/Sources/FoundationEssentials/Error/CocoaError+FilePath.swift +index d9b2497..586c781 100644 +--- a/Sources/FoundationEssentials/Error/CocoaError+FilePath.swift ++++ b/Sources/FoundationEssentials/Error/CocoaError+FilePath.swift +@@ -24,6 +24,8 @@ import Musl + #elseif os(Windows) + import CRT + import WinSDK ++#elseif os(WASI) ++import WASILibc + #endif + + extension CocoaError.Code { +diff --git a/Sources/FoundationEssentials/Error/ErrorCodes+POSIX.swift b/Sources/FoundationEssentials/Error/ErrorCodes+POSIX.swift +index 048cd29..e1bfffa 100644 +--- a/Sources/FoundationEssentials/Error/ErrorCodes+POSIX.swift ++++ b/Sources/FoundationEssentials/Error/ErrorCodes+POSIX.swift +@@ -21,6 +21,8 @@ + #elseif os(Windows) + import CRT + import WinSDK ++#elseif os(WASI) ++import WASILibc + #endif + + #if FOUNDATION_FRAMEWORK +@@ -467,11 +469,13 @@ extension POSIXError { + return .ESTALE + } + ++ #if !os(WASI) + /// Too many levels of remote in path. + public static var EREMOTE: POSIXErrorCode { + return .EREMOTE + } + #endif ++ #endif + + #if canImport(Darwin) + /// RPC struct is bad. +diff --git a/Sources/FoundationEssentials/FileManager/FileManager+Basics.swift b/Sources/FoundationEssentials/FileManager/FileManager+Basics.swift +index 991c5e8..9896b35 100644 +--- a/Sources/FoundationEssentials/FileManager/FileManager+Basics.swift ++++ b/Sources/FoundationEssentials/FileManager/FileManager+Basics.swift +@@ -21,6 +21,8 @@ import Musl + #elseif os(Windows) + import CRT + import WinSDK ++#elseif os(WASI) ++import WASILibc + #endif + + #if os(Windows) +diff --git a/Sources/FoundationEssentials/FileManager/FileManager+Directories.swift b/Sources/FoundationEssentials/FileManager/FileManager+Directories.swift +index 0941e51..f8375b3 100644 +--- a/Sources/FoundationEssentials/FileManager/FileManager+Directories.swift ++++ b/Sources/FoundationEssentials/FileManager/FileManager+Directories.swift +@@ -28,6 +28,8 @@ import Musl + #elseif os(Windows) + import CRT + import WinSDK ++#elseif os(WASI) ++import WASILibc + #endif + + internal import _FoundationCShims +diff --git a/Sources/FoundationEssentials/FileManager/FileManager+Files.swift b/Sources/FoundationEssentials/FileManager/FileManager+Files.swift +index b8cd50a..9cd9752 100644 +--- a/Sources/FoundationEssentials/FileManager/FileManager+Files.swift ++++ b/Sources/FoundationEssentials/FileManager/FileManager+Files.swift +@@ -29,6 +29,9 @@ internal import _FoundationCShims + #elseif os(Windows) + import CRT + import WinSDK ++#elseif os(WASI) ++internal import _FoundationCShims ++import WASILibc + #endif + + extension Date { +@@ -471,7 +474,7 @@ extension _FileManagerImpl { + parent = fileManager.currentDirectoryPath + } + +-#if os(Windows) ++#if os(Windows) || os(WASI) + return fileManager.isWritableFile(atPath: parent) && fileManager.isWritableFile(atPath: path) + #else + guard fileManager.isWritableFile(atPath: parent), +@@ -494,7 +497,7 @@ extension _FileManagerImpl { + #endif + } + +-#if !os(Windows) ++#if !os(Windows) && !os(WASI) + private func _extendedAttribute(_ key: UnsafePointer, at path: UnsafePointer, followSymlinks: Bool) throws -> Data? { + #if canImport(Darwin) + var size = getxattr(path, key, nil, 0, 0, followSymlinks ? 0 : XATTR_NOFOLLOW) +@@ -648,10 +651,11 @@ extension _FileManagerImpl { + + var attributes = statAtPath.fileAttributes + try? Self._catInfo(for: URL(filePath: path, directoryHint: .isDirectory), statInfo: statAtPath, into: &attributes) +- ++ #if !os(WASI) // WASI does not support extended attributes + if let extendedAttrs = try? _extendedAttributes(at: fsRep, followSymlinks: false) { + attributes[._extendedAttributes] = extendedAttrs + } ++ #endif + + #if !targetEnvironment(simulator) && FOUNDATION_FRAMEWORK + if statAtPath.isRegular || statAtPath.isDirectory { +@@ -713,6 +717,9 @@ extension _FileManagerImpl { + ] + } + } ++#elseif os(WASI) ++ // WASI does not support file system attributes ++ return [:] + #else + try fileManager.withFileSystemRepresentation(for: path) { rep in + guard let rep else { +@@ -928,6 +935,10 @@ extension _FileManagerImpl { + let groupID = _readFileAttributePrimitive(attributes[.groupOwnerAccountID], as: UInt.self) + + if user != nil || userID != nil || group != nil || groupID != nil { ++ #if os(WASI) ++ // WASI does not have the concept of users or groups ++ throw CocoaError.errorWithFilePath(.featureUnsupported, path) ++ #else + // Bias toward userID & groupID - try to prevent round trips to getpwnam if possible. + var leaveUnchanged: UInt32 { UInt32(bitPattern: -1) } + let rawUserID = userID.flatMap(uid_t.init) ?? user.flatMap(Self._userAccountNameToNumber) ?? leaveUnchanged +@@ -935,12 +946,18 @@ extension _FileManagerImpl { + if chown(fileSystemRepresentation, rawUserID, rawGroupID) != 0 { + throw CocoaError.errorWithFilePath(path, errno: errno, reading: false) + } ++ #endif + } + + try Self._setCatInfoAttributes(attributes, path: path) + + if let extendedAttrs = attributes[.init("NSFileExtendedAttributes")] as? [String : Data] { ++ #if os(WASI) ++ // WASI does not support extended attributes ++ throw CocoaError.errorWithFilePath(.featureUnsupported, path) ++ #else + try Self._setAttributes(extendedAttrs, at: fileSystemRepresentation, followSymLinks: false) ++ #endif + } + + if let date = attributes[.modificationDate] as? Date { +diff --git a/Sources/FoundationEssentials/FileManager/FileManager+SymbolicLinks.swift b/Sources/FoundationEssentials/FileManager/FileManager+SymbolicLinks.swift +index a1355e7..12d32e5 100644 +--- a/Sources/FoundationEssentials/FileManager/FileManager+SymbolicLinks.swift ++++ b/Sources/FoundationEssentials/FileManager/FileManager+SymbolicLinks.swift +@@ -23,6 +23,8 @@ import Musl + import CRT + import WinSDK + internal import _FoundationCShims ++#elseif os(WASI) ++import WASILibc + #endif + + extension _FileManagerImpl { +diff --git a/Sources/FoundationEssentials/FileManager/FileManager+Utilities.swift b/Sources/FoundationEssentials/FileManager/FileManager+Utilities.swift +index 9bac967..036f50c 100644 +--- a/Sources/FoundationEssentials/FileManager/FileManager+Utilities.swift ++++ b/Sources/FoundationEssentials/FileManager/FileManager+Utilities.swift +@@ -34,6 +34,8 @@ internal import _FoundationCShims + #elseif os(Windows) + import CRT + import WinSDK ++#elseif os(WASI) ++import WASILibc + #endif + + #if os(Windows) +@@ -176,7 +178,7 @@ extension _FileManagerImpl { + #endif + } + +-#if !os(Windows) ++#if !os(Windows) && !os(WASI) + static func _setAttribute(_ key: UnsafePointer, value: Data, at path: UnsafePointer, followSymLinks: Bool) throws { + try value.withUnsafeBytes { buffer in + #if canImport(Darwin) +@@ -274,7 +276,7 @@ extension _FileManagerImpl { + } + #endif + +-#if !os(Windows) ++#if !os(Windows) && !os(WASI) + static func _userAccountNameToNumber(_ name: String) -> uid_t? { + name.withCString { ptr in + getpwnam(ptr)?.pointee.pw_uid +diff --git a/Sources/FoundationEssentials/FileManager/FileOperations.swift b/Sources/FoundationEssentials/FileManager/FileOperations.swift +index 03adcc6..14c6fd8 100644 +--- a/Sources/FoundationEssentials/FileManager/FileOperations.swift ++++ b/Sources/FoundationEssentials/FileManager/FileOperations.swift +@@ -21,6 +21,8 @@ import Musl + #elseif os(Windows) + import CRT + import WinSDK ++#elseif os(WASI) ++import WASILibc + #endif + + #if FOUNDATION_FRAMEWORK +@@ -866,12 +868,14 @@ enum _FileOperations { + } + defer { close(dstfd) } + ++ #if !os(WASI) // WASI doesn't have fchmod for now + // Set the file permissions using fchmod() instead of when open()ing to avoid umask() issues + let permissions = fileInfo.st_mode & ~S_IFMT + guard fchmod(dstfd, permissions) == 0 else { + try delegate.throwIfNecessary(errno, String(cString: srcPtr), String(cString: dstPtr)) + return + } ++ #endif + + if fileInfo.st_size == 0 { + // no copying required +@@ -882,12 +886,31 @@ enum _FileOperations { + let chunkSize: Int = Int(fileInfo.st_blksize) + var current: off_t = 0 + ++ #if os(WASI) ++ // WASI doesn't have sendfile, so we need to do it in user space with read/write ++ try withUnsafeTemporaryAllocation(of: UInt8.self, capacity: chunkSize) { buffer in ++ while current < total { ++ let readSize = Swift.min(total - Int(current), chunkSize) ++ let bytesRead = read(srcfd, buffer.baseAddress, readSize) ++ guard bytesRead >= 0 else { ++ try delegate.throwIfNecessary(errno, String(cString: srcPtr), String(cString: dstPtr)) ++ return ++ } ++ guard write(dstfd, buffer.baseAddress, bytesRead) == bytesRead else { ++ try delegate.throwIfNecessary(errno, String(cString: srcPtr), String(cString: dstPtr)) ++ return ++ } ++ current += off_t(bytesRead) ++ } ++ } ++ #else + while current < total { + guard sendfile(dstfd, srcfd, ¤t, Swift.min(total - Int(current), chunkSize)) != -1 else { + try delegate.throwIfNecessary(errno, String(cString: srcPtr), String(cString: dstPtr)) + return + } + } ++ #endif + } + #endif + +diff --git a/Sources/FoundationEssentials/Formatting/BinaryInteger+NumericStringRepresentation.swift b/Sources/FoundationEssentials/Formatting/BinaryInteger+NumericStringRepresentation.swift +index 43e9fcd..663509d 100644 +--- a/Sources/FoundationEssentials/Formatting/BinaryInteger+NumericStringRepresentation.swift ++++ b/Sources/FoundationEssentials/Formatting/BinaryInteger+NumericStringRepresentation.swift +@@ -20,6 +20,8 @@ import Glibc + import Musl + #elseif os(Windows) + import CRT ++#elseif os(WASI) ++import WASILibc + #endif + + // MARK: - BinaryInteger + Numeric string representation +diff --git a/Sources/FoundationEssentials/LockedState.swift b/Sources/FoundationEssentials/LockedState.swift +index 6eb9ad8..4e6aefa 100644 +--- a/Sources/FoundationEssentials/LockedState.swift ++++ b/Sources/FoundationEssentials/LockedState.swift +@@ -35,6 +35,9 @@ package struct LockedState { + typealias Primitive = pthread_mutex_t + #elseif canImport(WinSDK) + typealias Primitive = SRWLOCK ++#elseif os(WASI) ++ // WASI is single-threaded, so we don't need a lock. ++ typealias Primitive = Void + #endif + + typealias PlatformLock = UnsafeMutablePointer +@@ -47,6 +50,8 @@ package struct LockedState { + pthread_mutex_init(platformLock, nil) + #elseif canImport(WinSDK) + InitializeSRWLock(platformLock) ++#elseif os(WASI) ++ // no-op + #endif + } + +@@ -64,6 +69,8 @@ package struct LockedState { + pthread_mutex_lock(platformLock) + #elseif canImport(WinSDK) + AcquireSRWLockExclusive(platformLock) ++#elseif os(WASI) ++ // no-op + #endif + } + +@@ -74,6 +81,8 @@ package struct LockedState { + pthread_mutex_unlock(platformLock) + #elseif canImport(WinSDK) + ReleaseSRWLockExclusive(platformLock) ++#elseif os(WASI) ++ // no-op + #endif + } + } +diff --git a/Sources/FoundationEssentials/Platform.swift b/Sources/FoundationEssentials/Platform.swift +index 9c3f2d7..4549a45 100644 +--- a/Sources/FoundationEssentials/Platform.swift ++++ b/Sources/FoundationEssentials/Platform.swift +@@ -114,7 +114,7 @@ private let _cachedUGIDs: (uid_t, gid_t) = { + }() + #endif + +-#if !os(Windows) ++#if !os(Windows) && !os(WASI) + extension Platform { + private static var ROOT_USER: UInt32 { 0 } + static func getUGIDs(allowEffectiveRootUID: Bool = true) -> (uid: UInt32, gid: UInt32) { +@@ -175,7 +175,7 @@ extension Platform { + // FIXME: bionic implements this as `return 0;` and does not expose the + // function via headers. We should be able to shim this and use the call + // if it is available. +-#if !os(Android) ++#if !os(Android) && !os(WASI) + guard issetugid() == 0 else { return nil } + #endif + if let value = getenv(name) { +diff --git a/Sources/FoundationEssentials/ProcessInfo/ProcessInfo.swift b/Sources/FoundationEssentials/ProcessInfo/ProcessInfo.swift +index 2e809fa..eb55c27 100644 +--- a/Sources/FoundationEssentials/ProcessInfo/ProcessInfo.swift ++++ b/Sources/FoundationEssentials/ProcessInfo/ProcessInfo.swift +@@ -23,6 +23,8 @@ import Glibc + import Musl + #elseif os(Windows) + import WinSDK ++#elseif os(WASI) ++import WASILibc + #endif + + #if !NO_PROCESS +@@ -391,7 +393,7 @@ extension _ProcessInfo { + patch: Int(osVersionInfo.dwBuildNumber) + ) + #else +- return OperatingSystemVersion(majorVersion: -1, minorVersion: 0, patchVersion: 0) ++ return (major: -1, minor: 0, patch: 0) + #endif + } + +diff --git a/Sources/FoundationEssentials/PropertyList/OpenStepPlist.swift b/Sources/FoundationEssentials/PropertyList/OpenStepPlist.swift +index c042820..a484557 100644 +--- a/Sources/FoundationEssentials/PropertyList/OpenStepPlist.swift ++++ b/Sources/FoundationEssentials/PropertyList/OpenStepPlist.swift +@@ -16,6 +16,8 @@ import Darwin + import Bionic + #elseif canImport(Glibc) + import Glibc ++#elseif os(WASI) ++import WASILibc + #elseif canImport(Musl) + import Musl + #endif +diff --git a/Sources/FoundationEssentials/String/String+Path.swift b/Sources/FoundationEssentials/String/String+Path.swift +index 477d5d3..7047b9b 100644 +--- a/Sources/FoundationEssentials/String/String+Path.swift ++++ b/Sources/FoundationEssentials/String/String+Path.swift +@@ -20,6 +20,8 @@ import Glibc + import Musl + #elseif os(Windows) + import WinSDK ++#elseif os(WASI) ++import WASILibc + #endif + + internal import _FoundationCShims +@@ -452,6 +454,7 @@ extension String { + return envVar.standardizingPath + } + ++ #if !os(WASI) // WASI does not have user concept + // Next, attempt to find the home directory via getpwnam/getpwuid + var pass: UnsafeMutablePointer? + if let user { +@@ -465,6 +468,7 @@ extension String { + if let dir = pass?.pointee.pw_dir { + return String(cString: dir).standardizingPath + } ++ #endif + + // Fallback to HOME for the current user if possible + if user == nil, let home = getenv("HOME") { +diff --git a/Sources/FoundationEssentials/_ThreadLocal.swift b/Sources/FoundationEssentials/_ThreadLocal.swift +index aea9c41..ffe010c 100644 +--- a/Sources/FoundationEssentials/_ThreadLocal.swift ++++ b/Sources/FoundationEssentials/_ThreadLocal.swift +@@ -32,6 +32,8 @@ struct _ThreadLocal { + fileprivate typealias PlatformKey = tss_t + #elseif canImport(WinSDK) + fileprivate typealias PlatformKey = DWORD ++#elseif os(WASI) ++ fileprivate typealias PlatformKey = UnsafeMutablePointer + #endif + + struct Key { +@@ -48,6 +50,8 @@ struct _ThreadLocal { + self.key = key + #elseif canImport(WinSDK) + key = FlsAlloc(nil) ++#elseif os(WASI) ++ key = UnsafeMutablePointer.allocate(capacity: 1) + #endif + } + } +@@ -60,6 +64,8 @@ struct _ThreadLocal { + tss_get(key) + #elseif canImport(WinSDK) + FlsGetValue(key) ++#elseif os(WASI) ++ key.pointee + #endif + } + +@@ -70,6 +76,8 @@ struct _ThreadLocal { + tss_set(key, newValue) + #elseif canImport(WinSDK) + FlsSetValue(key, newValue) ++#elseif os(WASI) ++ key.pointee = newValue + #endif + } + } +diff --git a/Sources/FoundationInternationalization/CMakeLists.txt b/Sources/FoundationInternationalization/CMakeLists.txt +index 5a89ceb..857db9c 100644 +--- a/Sources/FoundationInternationalization/CMakeLists.txt ++++ b/Sources/FoundationInternationalization/CMakeLists.txt +@@ -33,6 +33,7 @@ target_compile_options(FoundationInternationalization PRIVATE + "SHELL:$<$:-Xfrontend -enable-experimental-feature -Xfrontend StrictConcurrency>" + "SHELL:$<$:-Xfrontend -enable-upcoming-feature -Xfrontend InferSendableFromCaptures>") + target_compile_options(FoundationInternationalization PRIVATE ${_SwiftFoundation_availability_macros}) ++target_compile_options(FoundationInternationalization PRIVATE ${_SwiftFoundation_wasi_libc_flags}) + target_compile_options(FoundationInternationalization PRIVATE -package-name "SwiftFoundation") + + target_link_libraries(FoundationInternationalization PUBLIC +diff --git a/Sources/FoundationInternationalization/Calendar/Calendar_ICU.swift b/Sources/FoundationInternationalization/Calendar/Calendar_ICU.swift +index 0d3c371..01895b8 100644 +--- a/Sources/FoundationInternationalization/Calendar/Calendar_ICU.swift ++++ b/Sources/FoundationInternationalization/Calendar/Calendar_ICU.swift +@@ -24,6 +24,8 @@ import Musl + import CRT + #elseif canImport(Darwin) + import Darwin ++#elseif os(WASI) ++import WASILibc + #endif + + internal import _FoundationICU +diff --git a/Sources/FoundationInternationalization/Formatting/Duration+Formatting.swift b/Sources/FoundationInternationalization/Formatting/Duration+Formatting.swift +index a94f571..dfe2fad 100644 +--- a/Sources/FoundationInternationalization/Formatting/Duration+Formatting.swift ++++ b/Sources/FoundationInternationalization/Formatting/Duration+Formatting.swift +@@ -24,6 +24,8 @@ import Glibc + import Musl + #elseif os(Windows) + import CRT ++#elseif os(WASI) ++import WASILibc + #endif + + @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) +diff --git a/Sources/_FoundationCShims/include/_CStdlib.h b/Sources/_FoundationCShims/include/_CStdlib.h +index 8967eb7..0337393 100644 +--- a/Sources/_FoundationCShims/include/_CStdlib.h ++++ b/Sources/_FoundationCShims/include/_CStdlib.h +@@ -60,7 +60,21 @@ + #endif + + #if __has_include() +-#include ++/// Guard against including `signal.h` on WASI. The `signal.h` header file ++/// itself is available in wasi-libc, but it's just a stub that doesn't actually ++/// do anything. And also including it requires a special macro definition ++/// (`_WASI_EMULATED_SIGNAL`) and it causes compilation errors without the macro. ++# if !TARGET_OS_WASI || defined(_WASI_EMULATED_SIGNAL) ++# include ++# endif ++#endif ++ ++#if __has_include() ++/// Similar to `signal.h`, guard against including `sys/mman.h` on WASI unless ++/// `_WASI_EMULATED_MMAN` is enabled. ++# if !TARGET_OS_WASI || defined(_WASI_EMULATED_MMAN) ++# include ++# endif + #endif + + #if __has_include() +diff --git a/Sources/_FoundationCShims/include/platform_shims.h b/Sources/_FoundationCShims/include/platform_shims.h +index 911fc9e..f8048e6 100644 +--- a/Sources/_FoundationCShims/include/platform_shims.h ++++ b/Sources/_FoundationCShims/include/platform_shims.h +@@ -31,19 +31,19 @@ + #include + #endif + +-INTERNAL char * _Nullable * _Nullable _platform_shims_get_environ(); ++INTERNAL char * _Nullable * _Nullable _platform_shims_get_environ(void); + +-INTERNAL void _platform_shims_lock_environ(); +-INTERNAL void _platform_shims_unlock_environ(); ++INTERNAL void _platform_shims_lock_environ(void); ++INTERNAL void _platform_shims_unlock_environ(void); + + #if __has_include() + #include +-INTERNAL vm_size_t _platform_shims_vm_size(); ++INTERNAL vm_size_t _platform_shims_vm_size(void); + #endif + + #if __has_include() + #include +-INTERNAL mach_port_t _platform_mach_task_self(); ++INTERNAL mach_port_t _platform_mach_task_self(void); + #endif + + #if __has_include() +@@ -65,7 +65,7 @@ typedef enum { + } _platform_shims_OSThermalPressureLevel; + + +-INTERNAL const char * _Nonnull _platform_shims_kOSThermalNotificationPressureLevelName(); ++INTERNAL const char * _Nonnull _platform_shims_kOSThermalNotificationPressureLevelName(void); + #endif + + #endif /* CSHIMS_PLATFORM_SHIMS */ +diff --git a/Sources/_FoundationCShims/platform_shims.c b/Sources/_FoundationCShims/platform_shims.c +index 5a400a4..556bc94 100644 +--- a/Sources/_FoundationCShims/platform_shims.c ++++ b/Sources/_FoundationCShims/platform_shims.c +@@ -21,21 +21,25 @@ + extern char **environ; + #endif + ++#if __wasi__ ++#include // for __wasilibc_get_environ ++#endif ++ + #if __has_include() + #import +-void _platform_shims_lock_environ() { ++void _platform_shims_lock_environ(void) { + environ_lock_np(); + } + +-void _platform_shims_unlock_environ() { ++void _platform_shims_unlock_environ(void) { + environ_unlock_np(); + } + #else +-void _platform_shims_lock_environ() { /* noop */ } +-void _platform_shims_unlock_environ() { /* noop */ } ++void _platform_shims_lock_environ(void) { /* noop */ } ++void _platform_shims_unlock_environ(void) { /* noop */ } + #endif + +-char ** _platform_shims_get_environ() { ++char ** _platform_shims_get_environ(void) { + #if __has_include() + return *_NSGetEnviron(); + #elif defined(_WIN32) +@@ -48,20 +52,20 @@ char ** _platform_shims_get_environ() { + } + + #if __has_include() +-const char * _platform_shims_kOSThermalNotificationPressureLevelName() { ++const char * _platform_shims_kOSThermalNotificationPressureLevelName(void) { + return kOSThermalNotificationPressureLevelName; + } + #endif + + #if __has_include() +-vm_size_t _platform_shims_vm_size() { ++vm_size_t _platform_shims_vm_size(void) { + // This shim exists because vm_page_size is not marked const, and therefore looks like global mutable state to Swift. + return vm_page_size; + } + #endif + + #if __has_include() +-mach_port_t _platform_mach_task_self() { ++mach_port_t _platform_mach_task_self(void) { + // This shim exists because mach_task_self_ is not marked const, and therefore looks like global mutable state to Swift. + return mach_task_self(); + } +-- +2.46.0 + diff --git a/schemes/release-6.0/swift-foundation/0001-Use-platform-shims-for-clock-ids-to-support-wasi-lib.patch b/schemes/release-6.0/swift-foundation/0002-Use-platform-shims-for-clock-ids-to-support-wasi-lib.patch similarity index 100% rename from schemes/release-6.0/swift-foundation/0001-Use-platform-shims-for-clock-ids-to-support-wasi-lib.patch rename to schemes/release-6.0/swift-foundation/0002-Use-platform-shims-for-clock-ids-to-support-wasi-lib.patch diff --git a/schemes/release-6.0/swift-foundation/0003-Fix-TimeZone.current-lookup-on-Windows-975-978.patch b/schemes/release-6.0/swift-foundation/0003-Fix-TimeZone.current-lookup-on-Windows-975-978.patch new file mode 100644 index 00000000..fdb2fcd0 --- /dev/null +++ b/schemes/release-6.0/swift-foundation/0003-Fix-TimeZone.current-lookup-on-Windows-975-978.patch @@ -0,0 +1,134 @@ +From d3d8499bcfea5e1d16060d8a1c1e772b23a606d9 Mon Sep 17 00:00:00 2001 +From: Jeremy Schonfeld +Date: Fri, 11 Oct 2024 11:18:11 -0700 +Subject: [PATCH] Fix TimeZone.current lookup on Windows (#975) (#978) + +--- + .../TimeZone/TimeZone.swift | 2 +- + .../TimeZone/TimeZone_Cache.swift | 26 ++++++++++--------- + .../TimeZone/TimeZone_ICU.swift | 24 +++++++++++++++++ + Sources/_FoundationCShims/include/_CStdlib.h | 2 ++ + 4 files changed, 41 insertions(+), 13 deletions(-) + +diff --git a/Sources/FoundationEssentials/TimeZone/TimeZone.swift b/Sources/FoundationEssentials/TimeZone/TimeZone.swift +index d924312..09cd1ff 100644 +--- a/Sources/FoundationEssentials/TimeZone/TimeZone.swift ++++ b/Sources/FoundationEssentials/TimeZone/TimeZone.swift +@@ -390,7 +390,7 @@ extension TimeZone { + + extension TimeZone { + internal static func dataFromTZFile(_ name: String) -> Data { +-#if NO_TZFILE ++#if NO_TZFILE || os(Windows) + return Data() + #else + let path = TZDIR + "/" + name +diff --git a/Sources/FoundationEssentials/TimeZone/TimeZone_Cache.swift b/Sources/FoundationEssentials/TimeZone/TimeZone_Cache.swift +index efb8d67..ac61ee3 100644 +--- a/Sources/FoundationEssentials/TimeZone/TimeZone_Cache.swift ++++ b/Sources/FoundationEssentials/TimeZone/TimeZone_Cache.swift +@@ -50,6 +50,12 @@ dynamic package func _timeZoneGMTClass() -> _TimeZoneProtocol.Type { + } + #endif + ++#if os(Windows) ++dynamic package func _timeZoneIdentifier(forWindowsIdentifier windowsIdentifier: String) -> String? { ++ nil ++} ++#endif ++ + /// Singleton which listens for notifications about preference changes for TimeZone and holds cached values for current, fixed time zones, etc. + struct TimeZoneCache : Sendable { + // MARK: - State +@@ -129,18 +135,14 @@ struct TimeZoneCache : Sendable { + } + + #if os(Windows) +- let hFile = TZDEFAULT.withCString(encodedAs: UTF16.self) { +- CreateFileW($0, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, nil, OPEN_EXISTING, 0, nil) +- } +- defer { CloseHandle(hFile) } +- let dwSize = GetFinalPathNameByHandleW(hFile, nil, 0, VOLUME_NAME_DOS) +- let path = withUnsafeTemporaryAllocation(of: WCHAR.self, capacity: Int(dwSize)) { +- _ = GetFinalPathNameByHandleW(hFile, $0.baseAddress, dwSize, VOLUME_NAME_DOS) +- return String(decodingCString: $0.baseAddress!, as: UTF16.self) +- } +- if let rangeOfZoneInfo = path._range(of: "\(TZDIR)\\", anchored: false, backwards: false) { +- let name = path[rangeOfZoneInfo.upperBound...] +- if let result = fixed(String(name)) { ++ var timeZoneInfo = TIME_ZONE_INFORMATION() ++ if GetTimeZoneInformation(&timeZoneInfo) != TIME_ZONE_ID_INVALID { ++ let windowsName = withUnsafePointer(to: &(timeZoneInfo.StandardName)) { ++ $0.withMemoryRebound(to: WCHAR.self, capacity: 32) { ++ String(decoding: UnsafeBufferPointer(start: $0, count: wcslen($0)), as: UTF16.self) ++ } ++ } ++ if let identifier = _timeZoneIdentifier(forWindowsIdentifier: windowsName), let result = fixed(identifier) { + return TimeZone(inner: result) + } + } +diff --git a/Sources/FoundationInternationalization/TimeZone/TimeZone_ICU.swift b/Sources/FoundationInternationalization/TimeZone/TimeZone_ICU.swift +index 8b63f09..bff665f 100644 +--- a/Sources/FoundationInternationalization/TimeZone/TimeZone_ICU.swift ++++ b/Sources/FoundationInternationalization/TimeZone/TimeZone_ICU.swift +@@ -32,6 +32,13 @@ private func _timeZoneICUClass_localized() -> _TimeZoneProtocol.Type? { + } + #endif + ++#if os(Windows) ++@_dynamicReplacement(for: _timeZoneIdentifier(forWindowsIdentifier:)) ++private func _timeZoneIdentifier_ICU(forWindowsIdentifier windowsIdentifier: String) -> String? { ++ _TimeZoneICU.getSystemTimeZoneID(forWindowsIdentifier: windowsIdentifier) ++} ++#endif ++ + internal final class _TimeZoneICU: _TimeZoneProtocol, Sendable { + init?(secondsFromGMT: Int) { + fatalError("Unexpected init") +@@ -309,6 +316,23 @@ internal final class _TimeZoneICU: _TimeZoneProtocol, Sendable { + return result + } + ++ #if os(Windows) ++ internal static func getSystemTimeZoneID(forWindowsIdentifier identifier: String) -> String? { ++ let timeZoneIdentifier = Array(identifier.utf16) ++ let result: String? = timeZoneIdentifier.withUnsafeBufferPointer { identifier in ++ return _withResizingUCharBuffer { buffer, size, status in ++ let len = ucal_getTimeZoneIDForWindowsID(identifier.baseAddress, Int32(identifier.count), nil, buffer, size, &status) ++ if status.isSuccess { ++ return len ++ } else { ++ return nil ++ } ++ } ++ } ++ return result ++ } ++ #endif ++ + internal static func timeZoneNamesFromICU() -> [String] { + let filteredTimeZoneNames = [ + "ACT", +diff --git a/Sources/_FoundationCShims/include/_CStdlib.h b/Sources/_FoundationCShims/include/_CStdlib.h +index 0337393..5232967 100644 +--- a/Sources/_FoundationCShims/include/_CStdlib.h ++++ b/Sources/_FoundationCShims/include/_CStdlib.h +@@ -156,6 +156,7 @@ + #include + #else + ++#if TARGET_OS_MAC || TARGET_OS_LINUX + #ifndef TZDIR + #define TZDIR "/usr/share/zoneinfo/" /* Time zone object file directory */ + #endif /* !defined TZDIR */ +@@ -163,6 +164,7 @@ + #ifndef TZDEFAULT + #define TZDEFAULT "/etc/localtime" + #endif /* !defined TZDEFAULT */ ++#endif /* TARGET_OS_MAC || TARGET_OS_LINUX */ + + #endif + +-- +2.46.0 +