From e11703d91539fdb3290d7cf1858f6fdcdddbc14c Mon Sep 17 00:00:00 2001 From: Max Desiatov Date: Tue, 30 Apr 2024 17:11:39 +0100 Subject: [PATCH 1/3] Add support for `WASILibc` module (#159) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Quoting the [wasi.dev landing page](https://wasi.dev): > The WebAssembly System Interface (WASI) is a group of standard API specifications for software compiled to the W3C WebAssembly (Wasm) standard. WASI is designed to provide a secure standard interface for applications that can be compiled to Wasm from any language, and that may run anywhere—from browsers to clouds to embedded devices. Currently support for WASI in Swift is based on [`wasi-libc`](https://github.com/WebAssembly/wasi-libc). Adding support for `wasi-libc` mostly amounted to excluding unsupported errnos, adding TLS dictionary storage shim for single-threaded environment, and adding constants in C headers for macros that Clang importer currently doesn't support. Co-authored-by: Guillaume Lessard # Conflicts: # Sources/System/FileOperations.swift # Sources/System/Internals/Syscalls.swift --- Sources/CSystem/include/CSystemWASI.h | 31 +++++++ Sources/CSystem/include/module.modulemap | 1 + Sources/System/Errno.swift | 23 +++++- Sources/System/Internals/CInterop.swift | 4 +- Sources/System/Internals/Constants.swift | 100 ++++++++++++++++++++--- Sources/System/Internals/Exports.swift | 29 ++++++- 6 files changed, 170 insertions(+), 18 deletions(-) create mode 100644 Sources/CSystem/include/CSystemWASI.h diff --git a/Sources/CSystem/include/CSystemWASI.h b/Sources/CSystem/include/CSystemWASI.h new file mode 100644 index 00000000..9877853e --- /dev/null +++ b/Sources/CSystem/include/CSystemWASI.h @@ -0,0 +1,31 @@ +/* + This source file is part of the Swift System open source project + + Copyright (c) 2024 Apple Inc. and the Swift System project authors + Licensed under Apache License v2.0 with Runtime Library Exception + + See https://swift.org/LICENSE.txt for license information +*/ + +#pragma once + +#if __wasi__ + +#include +#include + +// wasi-libc defines the following constants in a way that Clang Importer can't +// understand, so we need to expose them manually. +static inline int32_t _getConst_O_ACCMODE(void) { return O_ACCMODE; } +static inline int32_t _getConst_O_APPEND(void) { return O_APPEND; } +static inline int32_t _getConst_O_CREAT(void) { return O_CREAT; } +static inline int32_t _getConst_O_DIRECTORY(void) { return O_DIRECTORY; } +static inline int32_t _getConst_O_EXCL(void) { return O_EXCL; } +static inline int32_t _getConst_O_NONBLOCK(void) { return O_NONBLOCK; } +static inline int32_t _getConst_O_TRUNC(void) { return O_TRUNC; } +static inline int32_t _getConst_O_WRONLY(void) { return O_WRONLY; } + +static inline int32_t _getConst_EWOULDBLOCK(void) { return EWOULDBLOCK; } +static inline int32_t _getConst_EOPNOTSUPP(void) { return EOPNOTSUPP; } + +#endif diff --git a/Sources/CSystem/include/module.modulemap b/Sources/CSystem/include/module.modulemap index 776f7766..6e8b89e9 100644 --- a/Sources/CSystem/include/module.modulemap +++ b/Sources/CSystem/include/module.modulemap @@ -1,5 +1,6 @@ module CSystem { header "CSystemLinux.h" + header "CSystemWASI.h" header "CSystemWindows.h" export * } diff --git a/Sources/System/Errno.swift b/Sources/System/Errno.swift index 498ccbcf..093023d0 100644 --- a/Sources/System/Errno.swift +++ b/Sources/System/Errno.swift @@ -1,7 +1,7 @@ /* This source file is part of the Swift System open source project - Copyright (c) 2020 Apple Inc. and the Swift System project authors + Copyright (c) 2021 - 2024 Apple Inc. and the Swift System project authors Licensed under Apache License v2.0 with Runtime Library Exception See https://swift.org/LICENSE.txt for license information @@ -226,7 +226,7 @@ public struct Errno: RawRepresentable, Error, Hashable, Codable { @available(*, unavailable, renamed: "badAddress") public static var EFAULT: Errno { badAddress } -#if !os(Windows) +#if !os(Windows) && !os(WASI) /// Not a block device. /// /// You attempted a block device operation on a nonblock device or file. @@ -618,6 +618,7 @@ public struct Errno: RawRepresentable, Error, Hashable, Codable { @available(*, unavailable, renamed: "protocolNotSupported") public static var EPROTONOSUPPORT: Errno { protocolNotSupported } +#if !os(WASI) /// Socket type not supported. /// /// Support for the socket type hasn't been configured into the system @@ -630,6 +631,7 @@ public struct Errno: RawRepresentable, Error, Hashable, Codable { @_alwaysEmitIntoClient @available(*, unavailable, renamed: "socketTypeNotSupported") public static var ESOCKTNOSUPPORT: Errno { socketTypeNotSupported } +#endif /// Not supported. /// @@ -644,6 +646,7 @@ public struct Errno: RawRepresentable, Error, Hashable, Codable { @available(*, unavailable, renamed: "notSupported") public static var ENOTSUP: Errno { notSupported } +#if !os(WASI) /// Protocol family not supported. /// /// The protocol family hasn't been configured into the system @@ -656,6 +659,7 @@ public struct Errno: RawRepresentable, Error, Hashable, Codable { @_alwaysEmitIntoClient @available(*, unavailable, renamed: "protocolFamilyNotSupported") public static var EPFNOSUPPORT: Errno { protocolFamilyNotSupported } +#endif /// The address family isn't supported by the protocol family. /// @@ -802,6 +806,7 @@ public struct Errno: RawRepresentable, Error, Hashable, Codable { @available(*, unavailable, renamed: "socketNotConnected") public static var ENOTCONN: Errno { socketNotConnected } +#if !os(WASI) /// Can't send after socket shutdown. /// /// A request to send data wasn't permitted @@ -815,6 +820,7 @@ public struct Errno: RawRepresentable, Error, Hashable, Codable { @_alwaysEmitIntoClient @available(*, unavailable, renamed: "socketShutdown") public static var ESHUTDOWN: Errno { socketShutdown } +#endif /// Operation timed out. /// @@ -871,6 +877,7 @@ public struct Errno: RawRepresentable, Error, Hashable, Codable { @available(*, unavailable, renamed: "fileNameTooLong") public static var ENAMETOOLONG: Errno { fileNameTooLong } +#if !os(WASI) /// The host is down. /// /// A socket operation failed because the destination host was down. @@ -882,6 +889,7 @@ public struct Errno: RawRepresentable, Error, Hashable, Codable { @_alwaysEmitIntoClient @available(*, unavailable, renamed: "hostIsDown") public static var EHOSTDOWN: Errno { hostIsDown } +#endif /// No route to host. /// @@ -920,6 +928,7 @@ public struct Errno: RawRepresentable, Error, Hashable, Codable { public static var EPROCLIM: Errno { tooManyProcesses } #endif +#if !os(WASI) /// Too many users. /// /// The quota system ran out of table entries. @@ -931,6 +940,7 @@ public struct Errno: RawRepresentable, Error, Hashable, Codable { @_alwaysEmitIntoClient @available(*, unavailable, renamed: "tooManyUsers") public static var EUSERS: Errno { tooManyUsers } +#endif /// Disk quota exceeded. /// @@ -1284,6 +1294,7 @@ public struct Errno: RawRepresentable, Error, Hashable, Codable { @available(*, unavailable, renamed: "multiHop") public static var EMULTIHOP: Errno { multiHop } +#if !os(WASI) /// No message available. /// /// No message was available to be received by the requested operation. @@ -1295,6 +1306,7 @@ public struct Errno: RawRepresentable, Error, Hashable, Codable { @_alwaysEmitIntoClient @available(*, unavailable, renamed: "noData") public static var ENODATA: Errno { noData } +#endif /// Reserved. /// @@ -1308,6 +1320,7 @@ public struct Errno: RawRepresentable, Error, Hashable, Codable { @available(*, unavailable, renamed: "noLink") public static var ENOLINK: Errno { noLink } +#if !os(WASI) /// Reserved. /// /// This error is reserved for future use. @@ -1331,6 +1344,7 @@ public struct Errno: RawRepresentable, Error, Hashable, Codable { @_alwaysEmitIntoClient @available(*, unavailable, renamed: "notStream") public static var ENOSTR: Errno { notStream } +#endif #endif /// Protocol error. @@ -1347,7 +1361,7 @@ public struct Errno: RawRepresentable, Error, Hashable, Codable { @available(*, unavailable, renamed: "protocolError") public static var EPROTO: Errno { protocolError } -#if !os(OpenBSD) +#if !os(OpenBSD) && !os(WASI) /// Reserved. /// /// This error is reserved for future use. @@ -1379,7 +1393,6 @@ public struct Errno: RawRepresentable, Error, Hashable, Codable { // Constants defined in header but not man page @available(/*System 0.0.1: macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0*/iOS 8, *) extension Errno { - /// Operation would block. /// /// The corresponding C error is `EWOULDBLOCK`. @@ -1390,6 +1403,7 @@ extension Errno { @available(*, unavailable, renamed: "wouldBlock") public static var EWOULDBLOCK: Errno { wouldBlock } +#if !os(WASI) /// Too many references: can't splice. /// /// The corresponding C error is `ETOOMANYREFS`. @@ -1409,6 +1423,7 @@ extension Errno { @_alwaysEmitIntoClient @available(*, unavailable, renamed: "tooManyRemoteLevels") public static var EREMOTE: Errno { tooManyRemoteLevels } +#endif #if SYSTEM_PACKAGE_DARWIN /// No such policy registered. diff --git a/Sources/System/Internals/CInterop.swift b/Sources/System/Internals/CInterop.swift index 3b4792e8..19cf4d56 100644 --- a/Sources/System/Internals/CInterop.swift +++ b/Sources/System/Internals/CInterop.swift @@ -1,7 +1,7 @@ /* This source file is part of the Swift System open source project - Copyright (c) 2020 - 2021 Apple Inc. and the Swift System project authors + Copyright (c) 2020 - 2024 Apple Inc. and the Swift System project authors Licensed under Apache License v2.0 with Runtime Library Exception See https://swift.org/LICENSE.txt for license information @@ -18,6 +18,8 @@ import Glibc #elseif canImport(Musl) @_implementationOnly import CSystem import Musl +#elseif canImport(WASILibc) +import WASILibc #else #error("Unsupported Platform") #endif diff --git a/Sources/System/Internals/Constants.swift b/Sources/System/Internals/Constants.swift index 8d4e4bb1..27a145f7 100644 --- a/Sources/System/Internals/Constants.swift +++ b/Sources/System/Internals/Constants.swift @@ -1,7 +1,7 @@ /* This source file is part of the Swift System open source project - Copyright (c) 2020 - 2021 Apple Inc. and the Swift System project authors + Copyright (c) 2020 - 2024 Apple Inc. and the Swift System project authors Licensed under Apache License v2.0 with Runtime Library Exception See https://swift.org/LICENSE.txt for license information @@ -21,6 +21,9 @@ import Glibc #elseif canImport(Musl) import CSystem import Musl +#elseif canImport(WASILibc) +import CSystem +import WASILibc #else #error("Unsupported Platform") #endif @@ -73,7 +76,7 @@ internal var _EACCES: CInt { EACCES } @_alwaysEmitIntoClient internal var _EFAULT: CInt { EFAULT } -#if !os(Windows) +#if !os(Windows) && !os(WASI) @_alwaysEmitIntoClient internal var _ENOTBLK: CInt { ENOTBLK } #endif @@ -141,7 +144,13 @@ internal var _ERANGE: CInt { ERANGE } internal var _EAGAIN: CInt { EAGAIN } @_alwaysEmitIntoClient -internal var _EWOULDBLOCK: CInt { EWOULDBLOCK } +internal var _EWOULDBLOCK: CInt { +#if os(WASI) + _getConst_EWOULDBLOCK() +#else + EWOULDBLOCK +#endif +} @_alwaysEmitIntoClient internal var _EINPROGRESS: CInt { EINPROGRESS } @@ -167,6 +176,7 @@ internal var _ENOPROTOOPT: CInt { ENOPROTOOPT } @_alwaysEmitIntoClient internal var _EPROTONOSUPPORT: CInt { EPROTONOSUPPORT } +#if !os(WASI) @_alwaysEmitIntoClient internal var _ESOCKTNOSUPPORT: CInt { #if os(Windows) @@ -175,6 +185,7 @@ internal var _ESOCKTNOSUPPORT: CInt { return ESOCKTNOSUPPORT #endif } +#endif @_alwaysEmitIntoClient internal var _ENOTSUP: CInt { @@ -185,6 +196,7 @@ internal var _ENOTSUP: CInt { #endif } +#if !os(WASI) @_alwaysEmitIntoClient internal var _EPFNOSUPPORT: CInt { #if os(Windows) @@ -193,6 +205,7 @@ internal var _EPFNOSUPPORT: CInt { return EPFNOSUPPORT #endif } +#endif @_alwaysEmitIntoClient internal var _EAFNOSUPPORT: CInt { EAFNOSUPPORT } @@ -227,6 +240,7 @@ internal var _EISCONN: CInt { EISCONN } @_alwaysEmitIntoClient internal var _ENOTCONN: CInt { ENOTCONN } +#if !os(WASI) @_alwaysEmitIntoClient internal var _ESHUTDOWN: CInt { #if os(Windows) @@ -244,6 +258,7 @@ internal var _ETOOMANYREFS: CInt { return ETOOMANYREFS #endif } +#endif @_alwaysEmitIntoClient internal var _ETIMEDOUT: CInt { ETIMEDOUT } @@ -257,6 +272,7 @@ internal var _ELOOP: CInt { ELOOP } @_alwaysEmitIntoClient internal var _ENAMETOOLONG: CInt { ENAMETOOLONG } +#if !os(WASI) @_alwaysEmitIntoClient internal var _EHOSTDOWN: CInt { #if os(Windows) @@ -265,6 +281,7 @@ internal var _EHOSTDOWN: CInt { return EHOSTDOWN #endif } +#endif @_alwaysEmitIntoClient internal var _EHOSTUNREACH: CInt { EHOSTUNREACH } @@ -277,6 +294,7 @@ internal var _ENOTEMPTY: CInt { ENOTEMPTY } internal var _EPROCLIM: CInt { EPROCLIM } #endif +#if !os(WASI) @_alwaysEmitIntoClient internal var _EUSERS: CInt { #if os(Windows) @@ -285,6 +303,7 @@ internal var _EUSERS: CInt { return EUSERS #endif } +#endif @_alwaysEmitIntoClient internal var _EDQUOT: CInt { @@ -304,6 +323,7 @@ internal var _ESTALE: CInt { #endif } +#if !os(WASI) @_alwaysEmitIntoClient internal var _EREMOTE: CInt { #if os(Windows) @@ -312,6 +332,7 @@ internal var _EREMOTE: CInt { return EREMOTE #endif } +#endif #if SYSTEM_PACKAGE_DARWIN @_alwaysEmitIntoClient @@ -399,30 +420,41 @@ internal var _EBADMSG: CInt { EBADMSG } @_alwaysEmitIntoClient internal var _EMULTIHOP: CInt { EMULTIHOP } +#if !os(WASI) @_alwaysEmitIntoClient internal var _ENODATA: CInt { ENODATA } +#endif @_alwaysEmitIntoClient internal var _ENOLINK: CInt { ENOLINK } +#if !os(WASI) @_alwaysEmitIntoClient internal var _ENOSR: CInt { ENOSR } @_alwaysEmitIntoClient internal var _ENOSTR: CInt { ENOSTR } #endif +#endif @_alwaysEmitIntoClient internal var _EPROTO: CInt { EPROTO } -#if !os(OpenBSD) +#if !os(OpenBSD) && !os(WASI) @_alwaysEmitIntoClient internal var _ETIME: CInt { ETIME } #endif #endif + @_alwaysEmitIntoClient -internal var _EOPNOTSUPP: CInt { EOPNOTSUPP } +internal var _EOPNOTSUPP: CInt { +#if os(WASI) + _getConst_EOPNOTSUPP() +#else + EOPNOTSUPP +#endif +} #if SYSTEM_PACKAGE_DARWIN @_alwaysEmitIntoClient @@ -462,15 +494,33 @@ internal var _O_ACCMODE: CInt { 0x03|O_SEARCH } #else // TODO: API? @_alwaysEmitIntoClient -internal var _O_ACCMODE: CInt { O_ACCMODE } +internal var _O_ACCMODE: CInt { +#if os(WASI) + _getConst_O_ACCMODE() +#else + O_ACCMODE +#endif +} #endif @_alwaysEmitIntoClient -internal var _O_NONBLOCK: CInt { O_NONBLOCK } +internal var _O_NONBLOCK: CInt { +#if os(WASI) + _getConst_O_NONBLOCK() +#else + O_NONBLOCK +#endif +} #endif @_alwaysEmitIntoClient -internal var _O_APPEND: CInt { O_APPEND } +internal var _O_APPEND: CInt { +#if os(WASI) + _getConst_O_APPEND() +#else + O_APPEND +#endif +} #if SYSTEM_PACKAGE_DARWIN @_alwaysEmitIntoClient @@ -481,22 +531,42 @@ internal var _O_EXLOCK: CInt { O_EXLOCK } #endif #if !os(Windows) +#if !os(WASI) // TODO: API? @_alwaysEmitIntoClient internal var _O_ASYNC: CInt { O_ASYNC } +#endif @_alwaysEmitIntoClient internal var _O_NOFOLLOW: CInt { O_NOFOLLOW } #endif @_alwaysEmitIntoClient -internal var _O_CREAT: CInt { O_CREAT } +internal var _O_CREAT: CInt { +#if os(WASI) + _getConst_O_CREAT() +#else + O_CREAT +#endif +} @_alwaysEmitIntoClient -internal var _O_TRUNC: CInt { O_TRUNC } +internal var _O_TRUNC: CInt { +#if os(WASI) + _getConst_O_TRUNC() +#else + O_TRUNC +#endif +} @_alwaysEmitIntoClient -internal var _O_EXCL: CInt { O_EXCL } +internal var _O_EXCL: CInt { +#if os(WASI) + _getConst_O_EXCL() +#else + O_EXCL +#endif +} #if SYSTEM_PACKAGE_DARWIN @_alwaysEmitIntoClient @@ -509,7 +579,13 @@ internal var _O_EVTONLY: CInt { O_EVTONLY } internal var _O_NOCTTY: CInt { O_NOCTTY } @_alwaysEmitIntoClient -internal var _O_DIRECTORY: CInt { O_DIRECTORY } +internal var _O_DIRECTORY: CInt { +#if os(WASI) + _getConst_O_DIRECTORY() +#else + O_DIRECTORY +#endif +} #endif #if SYSTEM_PACKAGE_DARWIN diff --git a/Sources/System/Internals/Exports.swift b/Sources/System/Internals/Exports.swift index e20454ee..f4358c5b 100644 --- a/Sources/System/Internals/Exports.swift +++ b/Sources/System/Internals/Exports.swift @@ -1,7 +1,7 @@ /* This source file is part of the Swift System open source project - Copyright (c) 2020 - 2021 Apple Inc. and the Swift System project authors + Copyright (c) 2020 - 2024 Apple Inc. and the Swift System project authors Licensed under Apache License v2.0 with Runtime Library Exception See https://swift.org/LICENSE.txt for license information @@ -23,6 +23,8 @@ import Glibc #elseif canImport(Musl) @_implementationOnly import CSystem import Musl +#elseif canImport(WASILibc) +import WASILibc #else #error("Unsupported Platform") #endif @@ -58,6 +60,11 @@ internal var system_errno: CInt { get { Musl.errno } set { Musl.errno = newValue } } +#elseif canImport(WASILibc) +internal var system_errno: CInt { + get { WASILibc.errno } + set { WASILibc.errno = newValue } +} #endif // MARK: C stdlib decls @@ -149,6 +156,24 @@ extension String { // TLS #if os(Windows) internal typealias _PlatformTLSKey = DWORD +#elseif os(WASI) && (swift(<6.1) || !_runtime(_multithreaded)) +// Mock TLS storage for single-threaded WASI +internal final class _PlatformTLSKey { + fileprivate init() {} +} +private final class TLSStorage: @unchecked Sendable { + var storage = [ObjectIdentifier: UnsafeMutableRawPointer]() +} +private let sharedTLSStorage = TLSStorage() + +func pthread_setspecific(_ key: _PlatformTLSKey, _ p: UnsafeMutableRawPointer?) -> Int { + sharedTLSStorage.storage[ObjectIdentifier(key)] = p + return 0 +} + +func pthread_getspecific(_ key: _PlatformTLSKey) -> UnsafeMutableRawPointer? { + sharedTLSStorage.storage[ObjectIdentifier(key)] +} #else internal typealias _PlatformTLSKey = pthread_key_t #endif @@ -160,6 +185,8 @@ internal func makeTLSKey() -> _PlatformTLSKey { fatalError("Unable to create key") } return raw + #elseif os(WASI) && (swift(<6.1) || !_runtime(_multithreaded)) + return _PlatformTLSKey() #else var raw = pthread_key_t() guard 0 == pthread_key_create(&raw, nil) else { From b2b60a6b9495f7e06b3aece461cc1b9ccaf917c5 Mon Sep 17 00:00:00 2001 From: Finagolfin Date: Thu, 9 May 2024 19:29:36 +0530 Subject: [PATCH 2/3] Android: DIR* is an OpaquePointer in Bionic too --- Sources/System/Internals/Syscalls.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/System/Internals/Syscalls.swift b/Sources/System/Internals/Syscalls.swift index 3794d6e0..f40b1685 100644 --- a/Sources/System/Internals/Syscalls.swift +++ b/Sources/System/Internals/Syscalls.swift @@ -189,7 +189,7 @@ internal func system_confstr( internal let SYSTEM_AT_REMOVE_DIR = AT_REMOVEDIR internal let SYSTEM_DT_DIR = DT_DIR internal typealias system_dirent = dirent -#if os(Linux) +#if os(Linux) || os(Android) internal typealias system_DIRPtr = OpaquePointer #else internal typealias system_DIRPtr = UnsafeMutablePointer From 209dfeacb8e052a3425b40c9da83fa1bda8f73ee Mon Sep 17 00:00:00 2001 From: Finagolfin Date: Thu, 4 Jul 2024 23:37:25 +0530 Subject: [PATCH 3/3] Import new Android overlay Use Bionic module instead where possible --- Sources/System/Internals/CInterop.swift | 3 +++ Sources/System/Internals/Constants.swift | 2 ++ Sources/System/Internals/Exports.swift | 8 ++++++++ Sources/System/Internals/Syscalls.swift | 2 ++ 4 files changed, 15 insertions(+) diff --git a/Sources/System/Internals/CInterop.swift b/Sources/System/Internals/CInterop.swift index 19cf4d56..80d37d05 100644 --- a/Sources/System/Internals/CInterop.swift +++ b/Sources/System/Internals/CInterop.swift @@ -20,6 +20,9 @@ import Glibc import Musl #elseif canImport(WASILibc) import WASILibc +#elseif canImport(Bionic) +@_implementationOnly import CSystem +import Bionic #else #error("Unsupported Platform") #endif diff --git a/Sources/System/Internals/Constants.swift b/Sources/System/Internals/Constants.swift index 27a145f7..904e5b22 100644 --- a/Sources/System/Internals/Constants.swift +++ b/Sources/System/Internals/Constants.swift @@ -24,6 +24,8 @@ import Musl #elseif canImport(WASILibc) import CSystem import WASILibc +#elseif canImport(Android) +import Android #else #error("Unsupported Platform") #endif diff --git a/Sources/System/Internals/Exports.swift b/Sources/System/Internals/Exports.swift index f4358c5b..d18102a2 100644 --- a/Sources/System/Internals/Exports.swift +++ b/Sources/System/Internals/Exports.swift @@ -25,6 +25,9 @@ import Glibc import Musl #elseif canImport(WASILibc) import WASILibc +#elseif canImport(Android) +@_implementationOnly import CSystem +import Android #else #error("Unsupported Platform") #endif @@ -65,6 +68,11 @@ internal var system_errno: CInt { get { WASILibc.errno } set { WASILibc.errno = newValue } } +#elseif canImport(Android) +internal var system_errno: CInt { + get { Android.errno } + set { Android.errno = newValue } +} #endif // MARK: C stdlib decls diff --git a/Sources/System/Internals/Syscalls.swift b/Sources/System/Internals/Syscalls.swift index f40b1685..6f885be5 100644 --- a/Sources/System/Internals/Syscalls.swift +++ b/Sources/System/Internals/Syscalls.swift @@ -17,6 +17,8 @@ import Musl import WASILibc #elseif os(Windows) import ucrt +#elseif canImport(Android) +import Android #else #error("Unsupported Platform") #endif