From 8558a75a4dfa4d284b0d4a924fc1d6108c777613 Mon Sep 17 00:00:00 2001 From: Max Desiatov Date: Thu, 22 Jun 2023 16:44:40 +0100 Subject: [PATCH 1/4] Add support for Musl libc Since Musl is sufficiently different from Glibc (see https://wiki.musl-libc.org/functional-differences-from-glibc.html), it requires a different import, which now should be applied to files that have `import Glibc` in them. --- CoreFoundation/Base.subproj/CFUtilities.c | 2 +- CoreFoundation/Base.subproj/CoreFoundation_Prefix.h | 4 ++-- CoreFoundation/Base.subproj/ForSwiftFoundationOnly.h | 4 +++- Sources/Foundation/Data.swift | 7 +++++++ Sources/Foundation/FileHandle.swift | 5 +++++ Sources/Foundation/Host.swift | 2 +- Sources/Foundation/NSData.swift | 4 +++- Sources/Foundation/NSSwiftRuntime.swift | 4 +++- Sources/Foundation/NSURL.swift | 2 ++ Sources/Foundation/Process.swift | 2 +- Sources/Foundation/Thread.swift | 6 ++++-- Sources/Tools/plutil/main.swift | 3 +++ 12 files changed, 35 insertions(+), 10 deletions(-) diff --git a/CoreFoundation/Base.subproj/CFUtilities.c b/CoreFoundation/Base.subproj/CFUtilities.c index 7c3fc9f8e7..b765d75efc 100644 --- a/CoreFoundation/Base.subproj/CFUtilities.c +++ b/CoreFoundation/Base.subproj/CFUtilities.c @@ -1675,7 +1675,7 @@ CFDictionaryRef __CFGetEnvironment() { extern char **environ; char **envp = environ; #elif TARGET_OS_LINUX -#if !defined(environ) && !TARGET_OS_ANDROID +#if !defined(environ) && !TARGET_OS_ANDROID && defined(__GLIBC_PREREQ) #define environ __environ #endif char **envp = environ; diff --git a/CoreFoundation/Base.subproj/CoreFoundation_Prefix.h b/CoreFoundation/Base.subproj/CoreFoundation_Prefix.h index bf6f203b5f..27d37caa73 100644 --- a/CoreFoundation/Base.subproj/CoreFoundation_Prefix.h +++ b/CoreFoundation/Base.subproj/CoreFoundation_Prefix.h @@ -189,7 +189,7 @@ static dispatch_queue_t __ ## PREFIX ## Queue(void) { \ #define CF_RETAIN_BALANCED_ELSEWHERE(obj, identified_location) do { } while (0) #endif -#if (TARGET_OS_LINUX && !TARGET_OS_ANDROID && !TARGET_OS_CYGWIN) || TARGET_OS_WIN32 +#if (TARGET_OS_LINUX && !TARGET_OS_ANDROID && !TARGET_OS_CYGWIN && defined(__GLIBC_PREREQ)) || TARGET_OS_WIN32 CF_INLINE size_t strlcpy(char * dst, const char * src, size_t maxlen) { const size_t srclen = strlen(src); @@ -300,7 +300,7 @@ typedef unsigned long fd_mask; #endif -#if !TARGET_OS_CYGWIN && !TARGET_OS_BSD +#if !TARGET_OS_CYGWIN && !TARGET_OS_BSD && defined(__GLIBC_PREREQ) #define issetugid() 0 #endif diff --git a/CoreFoundation/Base.subproj/ForSwiftFoundationOnly.h b/CoreFoundation/Base.subproj/ForSwiftFoundationOnly.h index 642151ab34..f507385396 100644 --- a/CoreFoundation/Base.subproj/ForSwiftFoundationOnly.h +++ b/CoreFoundation/Base.subproj/ForSwiftFoundationOnly.h @@ -69,6 +69,7 @@ #include #include +#if defined(__GLIBC_PREREQ) #if __GLIBC_PREREQ(2, 28) == 0 // required for statx() system call, glibc >=2.28 wraps the kernel function #include @@ -78,6 +79,7 @@ #include #define AT_STATX_SYNC_AS_STAT 0x0000 /* - Do whatever stat() does */ #endif //__GLIBC_PREREQ(2. 28) +#endif // defined(__GLIBC_PREREQ) #ifndef __NR_statx #include @@ -562,7 +564,7 @@ CF_CROSS_PLATFORM_EXPORT int _CFOpenFile(const char *path, int opts); static inline int _direntNameLength(struct dirent *entry) { #ifdef _D_EXACT_NAMLEN // defined on Linux return _D_EXACT_NAMLEN(entry); -#elif TARGET_OS_ANDROID +#elif TARGET_OS_ANDROID || !defined(__GLIBC_PREREQ) return strlen(entry->d_name); #else return entry->d_namlen; diff --git a/Sources/Foundation/Data.swift b/Sources/Foundation/Data.swift index e682da12c0..d8e99fc252 100644 --- a/Sources/Foundation/Data.swift +++ b/Sources/Foundation/Data.swift @@ -28,6 +28,13 @@ @usableFromInline let memset = Glibc.memset @usableFromInline let memcpy = Glibc.memcpy @usableFromInline let memcmp = Glibc.memcmp +#elseif canImport(Musl) +@usableFromInline let calloc = Musl.calloc +@usableFromInline let malloc = Musl.malloc +@usableFromInline let free = Musl.free +@usableFromInline let memset = Musl.memset +@usableFromInline let memcpy = Musl.memcpy +@usableFromInline let memcmp = Musl.memcmp #elseif canImport(WASILibc) @usableFromInline let calloc = WASILibc.calloc @usableFromInline let malloc = WASILibc.malloc diff --git a/Sources/Foundation/FileHandle.swift b/Sources/Foundation/FileHandle.swift index a538a2975e..285bed7059 100644 --- a/Sources/Foundation/FileHandle.swift +++ b/Sources/Foundation/FileHandle.swift @@ -22,6 +22,11 @@ import Glibc fileprivate let _read = Glibc.read(_:_:_:) fileprivate let _write = Glibc.write(_:_:_:) fileprivate let _close = Glibc.close(_:) +#elseif canImport(Musl) +import Musl +fileprivate let _read = Musl.read(_:_:_:) +fileprivate let _write = Musl.write(_:_:_:) +fileprivate let _close = Musl.close(_:) #endif #if canImport(WinSDK) diff --git a/Sources/Foundation/Host.swift b/Sources/Foundation/Host.swift index 5fe7b29c5b..5a72373c6d 100644 --- a/Sources/Foundation/Host.swift +++ b/Sources/Foundation/Host.swift @@ -281,7 +281,7 @@ open class Host: NSObject { } var hints = addrinfo() hints.ai_family = PF_UNSPEC -#if os(macOS) || os(iOS) || os(Android) || os(OpenBSD) +#if os(macOS) || os(iOS) || os(Android) || os(OpenBSD) || canImport(Musl) hints.ai_socktype = SOCK_STREAM #else hints.ai_socktype = Int32(SOCK_STREAM.rawValue) diff --git a/Sources/Foundation/NSData.swift b/Sources/Foundation/NSData.swift index 9892d0968b..945c817afd 100644 --- a/Sources/Foundation/NSData.swift +++ b/Sources/Foundation/NSData.swift @@ -488,8 +488,10 @@ open class NSData : NSObject, NSCopying, NSMutableCopying, NSSecureCoding { let createMode = Int(ucrt.S_IREAD) | Int(ucrt.S_IWRITE) #elseif canImport(Darwin) let createMode = Int(S_IRUSR) | Int(S_IWUSR) | Int(S_IRGRP) | Int(S_IWGRP) | Int(S_IROTH) | Int(S_IWOTH) -#else +#elseif canImport(Glibc) let createMode = Int(Glibc.S_IRUSR) | Int(Glibc.S_IWUSR) | Int(Glibc.S_IRGRP) | Int(Glibc.S_IWGRP) | Int(Glibc.S_IROTH) | Int(Glibc.S_IWOTH) +#elseif canImport(Musl) + let createMode = Int(Musl.S_IRUSR) | Int(Musl.S_IWUSR) | Int(Musl.S_IRGRP) | Int(Musl.S_IWGRP) | Int(Musl.S_IROTH) | Int(Musl.S_IWOTH) #endif guard let fh = FileHandle(path: path, flags: flags, createMode: createMode) else { throw _NSErrorWithErrno(errno, reading: false, path: path) diff --git a/Sources/Foundation/NSSwiftRuntime.swift b/Sources/Foundation/NSSwiftRuntime.swift index 04958446d7..7d90e516b0 100644 --- a/Sources/Foundation/NSSwiftRuntime.swift +++ b/Sources/Foundation/NSSwiftRuntime.swift @@ -14,8 +14,10 @@ // This mimics the behavior of the swift sdk overlay on Darwin #if os(macOS) || os(iOS) || os(tvOS) || os(watchOS) @_exported import Darwin -#elseif os(Linux) || os(Android) || CYGWIN || os(OpenBSD) +#elseif canImport (Glibc) @_exported import Glibc +#elseif canImport(Musl) +@_exported import Musl #elseif os(WASI) @_exported import WASILibc #elseif os(Windows) diff --git a/Sources/Foundation/NSURL.swift b/Sources/Foundation/NSURL.swift index 9b121d6681..4b6a2a5b98 100644 --- a/Sources/Foundation/NSURL.swift +++ b/Sources/Foundation/NSURL.swift @@ -20,6 +20,8 @@ internal let kCFURLWindowsPathStyle = CFURLPathStyle.cfurlWindowsPathStyle import Darwin #elseif canImport(Glibc) import Glibc +#elseif canImport(Musl) +import Musl #endif // NOTE: this represents PLATFORM_PATH_STYLE diff --git a/Sources/Foundation/Process.swift b/Sources/Foundation/Process.swift index 542cc94cf1..8d5ac46563 100644 --- a/Sources/Foundation/Process.swift +++ b/Sources/Foundation/Process.swift @@ -776,7 +776,7 @@ open class Process: NSObject { } var taskSocketPair : [Int32] = [0, 0] -#if os(macOS) || os(iOS) || os(Android) || os(OpenBSD) +#if os(macOS) || os(iOS) || os(Android) || os(OpenBSD) || canImport(Musl) socketpair(AF_UNIX, SOCK_STREAM, 0, &taskSocketPair) #else socketpair(AF_UNIX, Int32(SOCK_STREAM.rawValue), 0, &taskSocketPair) diff --git a/Sources/Foundation/Thread.swift b/Sources/Foundation/Thread.swift index 7734cf738d..d161e25908 100644 --- a/Sources/Foundation/Thread.swift +++ b/Sources/Foundation/Thread.swift @@ -14,6 +14,8 @@ import WinSDK #if canImport(Glibc) import Glibc +#elseif canImport(Musl) +import Musl #endif // WORKAROUND_SR9811 @@ -362,7 +364,7 @@ open class Thread : NSObject { let maxSupportedStackDepth = 128; let addrs = UnsafeMutablePointer.allocate(capacity: maxSupportedStackDepth) defer { addrs.deallocate() } -#if os(Android) || os(OpenBSD) +#if os(Android) || os(OpenBSD) || canImport(Musl) let count = 0 #elseif os(Windows) let count = RtlCaptureStackBackTrace(0, DWORD(maxSupportedStackDepth), @@ -383,7 +385,7 @@ open class Thread : NSObject { } open class var callStackSymbols: [String] { -#if os(Android) || os(OpenBSD) +#if os(Android) || os(OpenBSD) || canImport(Musl) return [] #elseif os(Windows) let hProcess: HANDLE = GetCurrentProcess() diff --git a/Sources/Tools/plutil/main.swift b/Sources/Tools/plutil/main.swift index c9ee783f84..d71d9ba9a2 100644 --- a/Sources/Tools/plutil/main.swift +++ b/Sources/Tools/plutil/main.swift @@ -12,6 +12,9 @@ import SwiftFoundation #elseif canImport(Glibc) import Foundation import Glibc +#elseif canImport(Musl) +import Foundation +import Musl #elseif canImport(CRT) import Foundation import CRT From 1114b494c4fbe22776beba1b193987b5e82bf90b Mon Sep 17 00:00:00 2001 From: Max Desiatov Date: Thu, 22 Jun 2023 17:00:14 +0100 Subject: [PATCH 2/4] Use `__GLIBC__` instead of `__GLIBC_PREREQ` --- CoreFoundation/Base.subproj/CFUtilities.c | 2 +- CoreFoundation/Base.subproj/CoreFoundation_Prefix.h | 4 ++-- CoreFoundation/Base.subproj/ForSwiftFoundationOnly.h | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CoreFoundation/Base.subproj/CFUtilities.c b/CoreFoundation/Base.subproj/CFUtilities.c index b765d75efc..83e8b90227 100644 --- a/CoreFoundation/Base.subproj/CFUtilities.c +++ b/CoreFoundation/Base.subproj/CFUtilities.c @@ -1675,7 +1675,7 @@ CFDictionaryRef __CFGetEnvironment() { extern char **environ; char **envp = environ; #elif TARGET_OS_LINUX -#if !defined(environ) && !TARGET_OS_ANDROID && defined(__GLIBC_PREREQ) +#if !defined(environ) && !TARGET_OS_ANDROID && defined(__GLIBC__) #define environ __environ #endif char **envp = environ; diff --git a/CoreFoundation/Base.subproj/CoreFoundation_Prefix.h b/CoreFoundation/Base.subproj/CoreFoundation_Prefix.h index 27d37caa73..d1adee6c5f 100644 --- a/CoreFoundation/Base.subproj/CoreFoundation_Prefix.h +++ b/CoreFoundation/Base.subproj/CoreFoundation_Prefix.h @@ -189,7 +189,7 @@ static dispatch_queue_t __ ## PREFIX ## Queue(void) { \ #define CF_RETAIN_BALANCED_ELSEWHERE(obj, identified_location) do { } while (0) #endif -#if (TARGET_OS_LINUX && !TARGET_OS_ANDROID && !TARGET_OS_CYGWIN && defined(__GLIBC_PREREQ)) || TARGET_OS_WIN32 +#if (TARGET_OS_LINUX && !TARGET_OS_ANDROID && !TARGET_OS_CYGWIN && defined(__GLIBC__)) || TARGET_OS_WIN32 CF_INLINE size_t strlcpy(char * dst, const char * src, size_t maxlen) { const size_t srclen = strlen(src); @@ -300,7 +300,7 @@ typedef unsigned long fd_mask; #endif -#if !TARGET_OS_CYGWIN && !TARGET_OS_BSD && defined(__GLIBC_PREREQ) +#if !TARGET_OS_CYGWIN && !TARGET_OS_BSD && defined(__GLIBC__) #define issetugid() 0 #endif diff --git a/CoreFoundation/Base.subproj/ForSwiftFoundationOnly.h b/CoreFoundation/Base.subproj/ForSwiftFoundationOnly.h index f507385396..b8241e4591 100644 --- a/CoreFoundation/Base.subproj/ForSwiftFoundationOnly.h +++ b/CoreFoundation/Base.subproj/ForSwiftFoundationOnly.h @@ -564,7 +564,7 @@ CF_CROSS_PLATFORM_EXPORT int _CFOpenFile(const char *path, int opts); static inline int _direntNameLength(struct dirent *entry) { #ifdef _D_EXACT_NAMLEN // defined on Linux return _D_EXACT_NAMLEN(entry); -#elif TARGET_OS_ANDROID || !defined(__GLIBC_PREREQ) +#elif TARGET_OS_ANDROID || !defined(__GLIBC__) return strlen(entry->d_name); #else return entry->d_namlen; From 859178e743779b82ceda796808e6cd281dccfb20 Mon Sep 17 00:00:00 2001 From: Max Desiatov Date: Tue, 4 Jul 2023 18:11:54 +0100 Subject: [PATCH 3/4] Simplify `defined(__GLIBC__)` macro checks --- CoreFoundation/Base.subproj/CoreFoundation_Prefix.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CoreFoundation/Base.subproj/CoreFoundation_Prefix.h b/CoreFoundation/Base.subproj/CoreFoundation_Prefix.h index d1adee6c5f..25dad0857b 100644 --- a/CoreFoundation/Base.subproj/CoreFoundation_Prefix.h +++ b/CoreFoundation/Base.subproj/CoreFoundation_Prefix.h @@ -189,7 +189,7 @@ static dispatch_queue_t __ ## PREFIX ## Queue(void) { \ #define CF_RETAIN_BALANCED_ELSEWHERE(obj, identified_location) do { } while (0) #endif -#if (TARGET_OS_LINUX && !TARGET_OS_ANDROID && !TARGET_OS_CYGWIN && defined(__GLIBC__)) || TARGET_OS_WIN32 +#if defined(__GLIBC__) || TARGET_OS_WIN32 CF_INLINE size_t strlcpy(char * dst, const char * src, size_t maxlen) { const size_t srclen = strlen(src); @@ -300,7 +300,7 @@ typedef unsigned long fd_mask; #endif -#if !TARGET_OS_CYGWIN && !TARGET_OS_BSD && defined(__GLIBC__) +#if defined(__GLIBC__) || TARGET_OS_WIN32 #define issetugid() 0 #endif From e95458c6f7d700bea57c3124a072fd30726c1254 Mon Sep 17 00:00:00 2001 From: Max Desiatov Date: Tue, 4 Jul 2023 18:36:10 +0100 Subject: [PATCH 4/4] Update `defined(__GLIBC__)` check in `CFUtilities.c` --- CoreFoundation/Base.subproj/CFUtilities.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CoreFoundation/Base.subproj/CFUtilities.c b/CoreFoundation/Base.subproj/CFUtilities.c index 83e8b90227..a3fab1f7c5 100644 --- a/CoreFoundation/Base.subproj/CFUtilities.c +++ b/CoreFoundation/Base.subproj/CFUtilities.c @@ -1675,7 +1675,7 @@ CFDictionaryRef __CFGetEnvironment() { extern char **environ; char **envp = environ; #elif TARGET_OS_LINUX -#if !defined(environ) && !TARGET_OS_ANDROID && defined(__GLIBC__) +#if !defined(environ) && defined(__GLIBC__) #define environ __environ #endif char **envp = environ;