Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for Musl libc #4779

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CoreFoundation/Base.subproj/CFUtilities.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) && defined(__GLIBC__)
#define environ __environ
#endif
char **envp = environ;
Expand Down
4 changes: 2 additions & 2 deletions CoreFoundation/Base.subproj/CoreFoundation_Prefix.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 defined(__GLIBC__) || TARGET_OS_WIN32
CF_INLINE size_t
strlcpy(char * dst, const char * src, size_t maxlen) {
const size_t srclen = strlen(src);
Expand Down Expand Up @@ -300,7 +300,7 @@ typedef unsigned long fd_mask;
#endif


#if !TARGET_OS_CYGWIN && !TARGET_OS_BSD
#if defined(__GLIBC__) || TARGET_OS_WIN32
#define issetugid() 0
#endif

Expand Down
4 changes: 3 additions & 1 deletion CoreFoundation/Base.subproj/ForSwiftFoundationOnly.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@
#include <features.h>
#include <termios.h>

#if defined(__GLIBC_PREREQ)
#if __GLIBC_PREREQ(2, 28) == 0
// required for statx() system call, glibc >=2.28 wraps the kernel function
#include <sys/syscall.h>
Expand All @@ -78,6 +79,7 @@
#include <linux/fs.h>
#define AT_STATX_SYNC_AS_STAT 0x0000 /* - Do whatever stat() does */
#endif //__GLIBC_PREREQ(2. 28)
#endif // defined(__GLIBC_PREREQ)

#ifndef __NR_statx
#include <sys/stat.h>
Expand Down Expand Up @@ -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__)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Won't this activate this line for the BSDs and all other libcs? No way to just enable this for Musl alone?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Musl provides no macro we could reliably check for.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it make sense to add one in this repo then, something like TARGET_LIBC_MUSL using this SO answer? Because this is technically wrong: glibc uses the _D_EXACT_NAMLEN branch above and has nothing to do with this condition.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Couldn't we just write __linux__ instead? Android and Musl are both Linux, after all.

We could even do

#elif defined(__linux__) && !defined(_DIRENT_HAVE_D_NAMLEN)

which would then mean if Musl or Android added d_namlen in the future, things would Just Work.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't particularly like the attempts at detecting Musl in that Stack Overflow answer; Musl should probably define some macros of its own — it should ideally be possible to test not just for Musl but to check the Musl version as well.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Couldn't we just write __linux__ instead?

That would work and be fine here, but I was trying to come up with a more general solution.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the general solution is to get musl to add __MUSL__ (and ideally __MUSL_MINOR__ and __MUSL_PREREQ() to go with it) in <features.h>. I have a patch for that locally — I'll see if we can upstream it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return strlen(entry->d_name);
#else
return entry->d_namlen;
Expand Down
7 changes: 7 additions & 0 deletions Sources/Foundation/Data.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
5 changes: 5 additions & 0 deletions Sources/Foundation/FileHandle.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion Sources/Foundation/Host.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
4 changes: 3 additions & 1 deletion Sources/Foundation/NSData.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
4 changes: 3 additions & 1 deletion Sources/Foundation/NSSwiftRuntime.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
2 changes: 2 additions & 0 deletions Sources/Foundation/NSURL.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion Sources/Foundation/Process.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
6 changes: 4 additions & 2 deletions Sources/Foundation/Thread.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import WinSDK

#if canImport(Glibc)
import Glibc
#elseif canImport(Musl)
import Musl
#endif

// WORKAROUND_SR9811
Expand Down Expand Up @@ -362,7 +364,7 @@ open class Thread : NSObject {
let maxSupportedStackDepth = 128;
let addrs = UnsafeMutablePointer<UnsafeMutableRawPointer?>.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),
Expand All @@ -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()
Expand Down
3 changes: 3 additions & 0 deletions Sources/Tools/plutil/main.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down