Skip to content

Fix swift-corelibs-foundation for Musl compatibility #4876

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

Merged
merged 9 commits into from
Feb 27, 2024
19 changes: 17 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,14 @@ project(Foundation
LANGUAGES C Swift)
enable_testing()

if(NOT SWIFT_SYSTEM_NAME)
if(CMAKE_SYSTEM_NAME STREQUAL Darwin)
set(SWIFT_SYSTEM_NAME macosx)
else()
set(SWIFT_SYSTEM_NAME "$<LOWER_CASE:${CMAKE_SYSTEM_NAME}>")
endif()
endif()

# NOTE(compnerd) default to /MD or /MDd by default based on the configuration.
# Cache the variable to allow the user to alter the configuration.
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>DLL" CACHE
Expand All @@ -38,6 +46,7 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set(CMAKE_Swift_MODULE_DIRECTORY ${CMAKE_BINARY_DIR}/swift)

option(BUILD_SHARED_LIBS "build shared libraries" ON)
option(BUILD_FULLY_STATIC "build fully static" NO)
option(HAS_LIBDISPATCH_API "has libdispatch API" ON)
option(BUILD_NETWORKING "build FoundationNetworking module" ON)
option(BUILD_TOOLS "build tools" ON)
Expand All @@ -49,6 +58,12 @@ endif()

find_package(ICU COMPONENTS uc i18n REQUIRED OPTIONAL_COMPONENTS data)

# This is needed if we're statically linking, otherwise we can't pull in Dispatch
# because we won't have RT::rt as a CMake target.
if(NOT CMAKE_SYSTEM_NAME STREQUAL Android)
find_package(LibRT)
endif()

include(SwiftSupport)
include(GNUInstallDirs)
include(XCTest)
Expand Down Expand Up @@ -99,13 +114,13 @@ if(NOT BUILD_SHARED_LIBS)
endif()

install(TARGETS CoreFoundation CFXMLInterface
DESTINATION lib/swift_static/$<LOWER_CASE:${CMAKE_SYSTEM_NAME}>)
DESTINATION lib/swift_static/${SWIFT_SYSTEM_NAME})

if(BUILD_NETWORKING)
set_property(GLOBAL APPEND PROPERTY Foundation_EXPORTS
CFURLSessionInterface)
install(TARGETS CFURLSessionInterface
DESTINATION lib/swift_static/$<LOWER_CASE:${CMAKE_SYSTEM_NAME}>)
DESTINATION lib/swift_static/${SWIFT_SYSTEM_NAME})
endif()
endif()

Expand Down
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) && !TARGET_OS_ANDROID && !defined(__musl__)
#define environ __environ
#endif
char **envp = environ;
Expand Down
8 changes: 6 additions & 2 deletions CoreFoundation/Base.subproj/CoreFoundation_Prefix.h
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,8 @@ 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_MAC
#if !HAVE_STRLCPY
CF_INLINE size_t
strlcpy(char * dst, const char * src, size_t maxlen) {
const size_t srclen = strlen(src);
Expand All @@ -201,7 +202,9 @@ strlcpy(char * dst, const char * src, size_t maxlen) {
}
return srclen;
}
#endif

#if !HAVE_STRLCAT
CF_INLINE size_t
strlcat(char * dst, const char * src, size_t maxlen) {
const size_t srclen = strlen(src);
Expand All @@ -216,6 +219,7 @@ strlcat(char * dst, const char * src, size_t maxlen) {
return dstlen + srclen;
}
#endif
#endif // !TARGET_OS_MAC

#if TARGET_OS_WIN32
// Compatibility with boolean.h
Expand Down Expand Up @@ -300,7 +304,7 @@ typedef unsigned long fd_mask;
#endif


#if !TARGET_OS_CYGWIN && !TARGET_OS_BSD
#if !TARGET_OS_MAC && !HAVE_ISSETUGID
#define issetugid() 0
#endif

Expand Down
5 changes: 3 additions & 2 deletions 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>

#ifdef __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,7 +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>
#endif // not __NR_statx
Expand Down Expand Up @@ -562,7 +563,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_LINUX || TARGET_OS_ANDROID
return strlen(entry->d_name);
#else
return entry->d_namlen;
Expand Down
20 changes: 18 additions & 2 deletions CoreFoundation/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ project(CoreFoundation
VERSION 1338
LANGUAGES ASM C)

include(CheckSymbolExists)
include(CheckIncludeFile)

set(CMAKE_C_STANDARD 99)
set(CMAKE_C_STANDARD_REQUIRED YES)

Expand Down Expand Up @@ -70,8 +73,6 @@ if(CMAKE_SYSTEM_NAME STREQUAL Linux OR CMAKE_SYSTEM_NAME STREQUAL Android)
add_compile_definitions($<$<COMPILE_LANGUAGE:C>:_GNU_SOURCE>)

if(CMAKE_SYSTEM_NAME STREQUAL Linux)
include(CheckSymbolExists)
include(CheckIncludeFile)
list(APPEND CMAKE_REQUIRED_DEFINITIONS -D_GNU_SOURCE)
check_include_file("sched.h" HAVE_SCHED_H)
if(HAVE_SCHED_H)
Expand All @@ -90,6 +91,21 @@ elseif(CMAKE_SYSTEM_NAME STREQUAL Windows)
endif()
endif()

# Look for some functions that may not be present on all platforms
check_symbol_exists(strlcpy "string.h" HAVE_STRLCPY)
check_symbol_exists(strlcat "string.h" HAVE_STRLCAT)
check_symbol_exists(issetugid "unistd.h" HAVE_ISSETUGID)

if(HAVE_STRLCPY)
add_compile_definitions($<$<COMPILE_LANGUAGE:C>:HAVE_STRLCPY>)
endif()
if(HAVE_STRLCAT)
add_compile_definitions($<$<COMPILE_LANGUAGE:C>:HAVE_STRLCAT>)
endif()
if(HAVE_ISSETUGID)
add_compile_definitions($<$<COMPILE_LANGUAGE:C>:HAVE_ISSETUGID>)
endif()

add_compile_definitions($<$<COMPILE_LANGUAGE:C>:U_SHOW_DRAFT_API>)
add_compile_definitions($<$<COMPILE_LANGUAGE:C>:CF_BUILDING_CF>)

Expand Down
4 changes: 2 additions & 2 deletions Sources/BlocksRuntime/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,5 @@ set_target_properties(BlocksRuntime PROPERTIES
add_library(BlocksRuntime::BlocksRuntime ALIAS BlocksRuntime)

install(TARGETS BlocksRuntime
ARCHIVE DESTINATION lib/swift$<$<NOT:$<BOOL:${BUILD_SHARED_LIBS}>>:_static>/$<LOWER_CASE:${CMAKE_SYSTEM_NAME}>
LIBRARY DESTINATION lib/swift$<$<NOT:$<BOOL:${BUILD_SHARED_LIBS}>>:_static>/$<LOWER_CASE:${CMAKE_SYSTEM_NAME}>)
ARCHIVE DESTINATION lib/swift$<$<NOT:$<BOOL:${BUILD_SHARED_LIBS}>>:_static>/${SWIFT_SYSTEM_NAME}
LIBRARY DESTINATION lib/swift$<$<NOT:$<BOOL:${BUILD_SHARED_LIBS}>>:_static>/${SWIFT_SYSTEM_NAME})
5 changes: 5 additions & 0 deletions Sources/Foundation/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,11 @@ target_link_libraries(Foundation
uuid
PUBLIC
swiftDispatch)
if("${CMAKE_C_COMPILER_TARGET}" MATCHES ".*-musl[^-*]$")
target_link_libraries(Foundation
PUBLIC
fts)
endif()
set_target_properties(Foundation PROPERTIES
INSTALL_RPATH "$ORIGIN"
BUILD_RPATH "$<TARGET_FILE_DIR:swiftDispatch>"
Expand Down
9 changes: 9 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 All @@ -48,6 +55,8 @@ internal func malloc_good_size(_ size: Int) -> Int {

#if canImport(Glibc)
import Glibc
#elseif canImport(Musl)
import Musl
#elseif canImport(WASILibc)
import WASILibc
#endif
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 @@ -494,8 +494,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
8 changes: 6 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 @@ -356,13 +358,15 @@ open class Thread : NSObject {
_cancelled = true
}

// ###TODO: Switch these over to using the Swift runtime's backtracer
// once we have Windows support there.

private class func backtraceAddresses<T>(_ body: (UnsafeMutablePointer<UnsafeMutableRawPointer?>, Int) -> [T]) -> [T] {
// Same as swift/stdlib/public/runtime/Errors.cpp backtrace
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 +387,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
8 changes: 8 additions & 0 deletions Sources/FoundationNetworking/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,14 @@ if(NOT BUILD_SHARED_LIBS)
PRIVATE
"SHELL:-Xfrontend -public-autolink-library -Xfrontend curl")

if(BUILD_FULLY_STATIC)
target_compile_options(FoundationNetworking
PRIVATE
"SHELL:-Xfrontend -public-autolink-library -Xfrontend crypto"
"SHELL:-Xfrontend -public-autolink-library -Xfrontend ssl"
"SHELL:-Xfrontend -public-autolink-library -Xfrontend z")
endif()

# Merge private dependencies into single static objects archive
set_property(TARGET FoundationNetworking PROPERTY STATIC_LIBRARY_OPTIONS
$<TARGET_OBJECTS:CFURLSessionInterface>)
Expand Down
6 changes: 6 additions & 0 deletions Sources/FoundationXML/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@ if(NOT BUILD_SHARED_LIBS)
PRIVATE
"SHELL:-Xfrontend -public-autolink-library -Xfrontend xml2")

if(BUILD_FULLY_STATIC)
target_compile_options(FoundationXML
PRIVATE
"SHELL:-Xfrontend -public-autolink-library -Xfrontend z")
endif()

# Merge private dependencies into single static objects archive
set_property(TARGET FoundationXML PROPERTY STATIC_LIBRARY_OPTIONS
$<TARGET_OBJECTS:CFXMLInterface>)
Expand Down
2 changes: 1 addition & 1 deletion Sources/Tools/plutil/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ if(NOT CMAKE_SYSTEM_NAME MATCHES "Darwin|Windows")
endif()

set_target_properties(plutil PROPERTIES
INSTALL_RPATH "$ORIGIN/../lib/swift/$<LOWER_CASE:${CMAKE_SYSTEM_NAME}>")
INSTALL_RPATH "$ORIGIN/../lib/swift/${SWIFT_SYSTEM_NAME}")


set_property(GLOBAL APPEND PROPERTY Foundation_EXPORTS plutil)
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
4 changes: 2 additions & 2 deletions Sources/UUID/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ if(NOT BUILD_SHARED_LIBS)
# TODO(drexin): should be installed in architecture specific folder, once
# the layout is fixed for non-Darwin platforms
install(TARGETS uuid
ARCHIVE DESTINATION lib/swift_static/$<LOWER_CASE:${CMAKE_SYSTEM_NAME}>
LIBRARY DESTINATION lib/swift_static/$<LOWER_CASE:${CMAKE_SYSTEM_NAME}>
ARCHIVE DESTINATION lib/swift_static/${SWIFT_SYSTEM_NAME}
LIBRARY DESTINATION lib/swift_static/${SWIFT_SYSTEM_NAME}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
endif()
Loading