-
Notifications
You must be signed in to change notification settings - Fork 31
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add swift-foundation patches to fix android build
- Loading branch information
1 parent
090f9e9
commit 1c73461
Showing
2 changed files
with
249 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
diff --git a/Sources/FoundationEssentials/Platform.swift b/Sources/FoundationEssentials/Platform.swift | ||
index 6eb3acc..72dbf88 100644 | ||
--- a/Sources/FoundationEssentials/Platform.swift | ||
+++ b/Sources/FoundationEssentials/Platform.swift | ||
@@ -29,8 +29,7 @@ fileprivate let _pageSize: Int = { | ||
// WebAssembly defines a fixed page size | ||
fileprivate let _pageSize: Int = 65_536 | ||
#elseif os(Android) | ||
-import Bionic | ||
-import unistd | ||
+import Android | ||
fileprivate let _pageSize: Int = Int(getpagesize()) | ||
#elseif canImport(Glibc) | ||
import Glibc | ||
@@ -142,7 +141,7 @@ extension Platform { | ||
typealias Operation<Input, Output> = (Input, UnsafeMutablePointer<Output>, UnsafeMutablePointer<CChar>, Int, UnsafeMutablePointer<UnsafeMutablePointer<Output>?>) -> Int32 | ||
#endif | ||
|
||
- private static func withUserGroupBuffer<Input, Output, R>(_ input: Input, _ output: Output, sizeProperty: Int32, operation: Operation<Input, Output>, block: (Output) throws -> R) rethrows -> R? { | ||
+ private static func withUserGroupBuffer<Input, Output, R>(_ input: Input, _ output: Output, sizeProperty: Int32, operation: Operation<Input, Output>, block: (Output) throws -> R?) rethrows -> R? { | ||
var bufferLen = sysconf(sizeProperty) | ||
if bufferLen == -1 { | ||
bufferLen = 4096 // Generous default size estimate | ||
@@ -172,31 +171,51 @@ extension Platform { | ||
|
||
static func name(forUID uid: uid_t) -> String? { | ||
withUserGroupBuffer(uid, passwd(), sizeProperty: Int32(_SC_GETPW_R_SIZE_MAX), operation: getpwuid_r) { | ||
- String(cString: $0.pw_name) | ||
+ // Android's pw_name `char *`` is nullable when it should be non-null. | ||
+ // FIXME: avoid the coerce cast workaround once https://github.com/android/ndk/issues/2098 is fixed. | ||
+ let pw_name: UnsafeMutablePointer<CChar>? = $0.pw_name | ||
+ return pw_name.flatMap { String(cString: $0) } | ||
} | ||
} | ||
|
||
static func fullName(forUID uid: uid_t) -> String? { | ||
withUserGroupBuffer(uid, passwd(), sizeProperty: Int32(_SC_GETPW_R_SIZE_MAX), operation: getpwuid_r) { | ||
- String(cString: $0.pw_gecos) | ||
+#if os(Android) && _pointerBitWidth(_32) | ||
+ // pw_gecos isn't available on 32-bit Android. | ||
+ let pw_gecos: UnsafeMutablePointer<CChar>? = nil | ||
+#else | ||
+ // Android's pw_gecos `char *`` is nullable, so always coerce to a nullable pointer | ||
+ // in order to be compatible with Android. | ||
+ let pw_gecos: UnsafeMutablePointer<CChar>? = $0.pw_gecos | ||
+#endif | ||
+ return pw_gecos.flatMap { String(cString: $0) } | ||
} | ||
} | ||
|
||
static func name(forGID gid: gid_t) -> String? { | ||
withUserGroupBuffer(gid, group(), sizeProperty: Int32(_SC_GETGR_R_SIZE_MAX), operation: getgrgid_r) { | ||
- String(cString: $0.gr_name) | ||
+ // Android's gr_name `char *`` is nullable when it should be non-null. | ||
+ // FIXME: avoid the coerce cast workaround once https://github.com/android/ndk/issues/2098 is fixed. | ||
+ let gr_name: UnsafeMutablePointer<CChar>? = $0.gr_name | ||
+ return gr_name.flatMap { String(cString: $0) } | ||
} | ||
} | ||
|
||
static func homeDirectory(forUserName userName: String) -> String? { | ||
withUserGroupBuffer(userName, passwd(), sizeProperty: Int32(_SC_GETPW_R_SIZE_MAX), operation: getpwnam_r) { | ||
- String(cString: $0.pw_dir) | ||
+ // Android's pw_dir `char *`` is nullable when it should be non-null. | ||
+ // FIXME: avoid the coerce cast workaround once https://github.com/android/ndk/issues/2098 is fixed. | ||
+ let pw_dir: UnsafeMutablePointer<CChar>? = $0.pw_dir | ||
+ return pw_dir.flatMap { String(cString: $0) } | ||
} | ||
} | ||
|
||
static func homeDirectory(forUID uid: uid_t) -> String? { | ||
withUserGroupBuffer(uid, passwd(), sizeProperty: Int32(_SC_GETPW_R_SIZE_MAX), operation: getpwuid_r) { | ||
- String(cString: $0.pw_dir) | ||
+ // Android's pw_dir `char *`` is nullable when it should be non-null. | ||
+ // FIXME: avoid the coerce cast workaround once https://github.com/android/ndk/issues/2098 is fixed. | ||
+ let pw_dir: UnsafeMutablePointer<CChar>? = $0.pw_dir | ||
+ return pw_dir.flatMap { String(cString: $0) } | ||
} | ||
} | ||
} |
169 changes: 169 additions & 0 deletions
169
patches/swift-foundation/0002-fix-the-LP32-armv7-i686-android-build.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,169 @@ | ||
From 1194ec526d02c76fe7f71bc1c18a784a478e53b1 Mon Sep 17 00:00:00 2001 | ||
From: Alex Lorenz <[email protected]> | ||
Date: Wed, 14 Aug 2024 10:56:25 -0700 | ||
Subject: [PATCH] [android] fix the LP32 armv7/i686 android build | ||
|
||
--- | ||
Sources/FoundationEssentials/Data/Data+Reading.swift | 2 +- | ||
.../FileManager/FileManager+Basics.swift | 4 ++-- | ||
.../FileManager/FileManager+Files.swift | 7 ++++--- | ||
.../FileManager/FileManager+Utilities.swift | 8 ++++---- | ||
.../FileManager/FileOperations+Enumeration.swift | 2 +- | ||
.../FoundationEssentials/FileManager/FileOperations.swift | 2 +- | ||
.../FoundationEssentials/ProcessInfo/ProcessInfo.swift | 5 ++++- | ||
Sources/FoundationEssentials/String/String+Path.swift | 2 +- | ||
8 files changed, 18 insertions(+), 14 deletions(-) | ||
|
||
diff --git a/Sources/FoundationEssentials/Data/Data+Reading.swift b/Sources/FoundationEssentials/Data/Data+Reading.swift | ||
index 612681d..8f611af 100644 | ||
--- a/Sources/FoundationEssentials/Data/Data+Reading.swift | ||
+++ b/Sources/FoundationEssentials/Data/Data+Reading.swift | ||
@@ -327,7 +327,7 @@ internal func readBytesFromFile(path inPath: PathOrURL, reportProgress: Bool, ma | ||
} | ||
|
||
let fileSize = min(Int(clamping: filestat.st_size), maxLength ?? Int.max) | ||
- let fileType = filestat.st_mode & S_IFMT | ||
+ let fileType = mode_t(filestat.st_mode) & S_IFMT | ||
#if !NO_FILESYSTEM | ||
let shouldMap = shouldMapFileDescriptor(fd, path: inPath, options: options) | ||
#else | ||
diff --git a/Sources/FoundationEssentials/FileManager/FileManager+Basics.swift b/Sources/FoundationEssentials/FileManager/FileManager+Basics.swift | ||
index 9896b35..4c05723 100644 | ||
--- a/Sources/FoundationEssentials/FileManager/FileManager+Basics.swift | ||
+++ b/Sources/FoundationEssentials/FileManager/FileManager+Basics.swift | ||
@@ -223,7 +223,7 @@ internal struct _FileManagerImpl { | ||
var statBuf = stat() | ||
let fd = open(path, 0, 0) | ||
guard fd >= 0 else { return nil } | ||
- if fstat(fd, &statBuf) < 0 || statBuf.st_mode & S_IFMT == S_IFDIR { | ||
+ if fstat(fd, &statBuf) < 0 || mode_t(statBuf.st_mode) & S_IFMT == S_IFDIR { | ||
close(fd) | ||
return nil | ||
} | ||
@@ -242,7 +242,7 @@ internal struct _FileManagerImpl { | ||
} | ||
|
||
/* check for being same type */ | ||
- if myInfo.st_mode & S_IFMT != otherInfo.st_mode & S_IFMT { | ||
+ if mode_t(myInfo.st_mode) & S_IFMT != mode_t(otherInfo.st_mode) & S_IFMT { | ||
return false | ||
} | ||
|
||
diff --git a/Sources/FoundationEssentials/FileManager/FileManager+Files.swift b/Sources/FoundationEssentials/FileManager/FileManager+Files.swift | ||
index 4b628c8..346f4ae 100644 | ||
--- a/Sources/FoundationEssentials/FileManager/FileManager+Files.swift | ||
+++ b/Sources/FoundationEssentials/FileManager/FileManager+Files.swift | ||
@@ -162,7 +162,8 @@ extension stat { | ||
} | ||
|
||
fileprivate var fileAttributes: [FileAttributeKey : Any] { | ||
- let fileType = st_mode.fileType | ||
+ // On 32 bit Android, st_mode is UInt32. | ||
+ let fileType = mode_t(st_mode).fileType | ||
var result: [FileAttributeKey : Any] = [ | ||
.size : _writeFileAttributePrimitive(st_size, as: UInt.self), | ||
.modificationDate : modificationDate, | ||
@@ -387,7 +388,7 @@ extension _FileManagerImpl { | ||
guard stat(rep, &fileInfo) == 0 else { | ||
return (false, false) | ||
} | ||
- let isDir = (fileInfo.st_mode & S_IFMT) == S_IFDIR | ||
+ let isDir = (mode_t(fileInfo.st_mode) & S_IFMT) == S_IFDIR | ||
return (true, isDir) | ||
} | ||
#endif | ||
@@ -466,7 +467,7 @@ extension _FileManagerImpl { | ||
return false | ||
} | ||
|
||
- if ((dirInfo.st_mode & S_ISVTX) != 0) && fileManager.fileExists(atPath: path) { | ||
+ if ((mode_t(dirInfo.st_mode) & S_ISVTX) != 0) && fileManager.fileExists(atPath: path) { | ||
// its sticky so verify that we own the file | ||
// otherwise we answer YES on the principle that if | ||
// we create files we can delete them | ||
diff --git a/Sources/FoundationEssentials/FileManager/FileManager+Utilities.swift b/Sources/FoundationEssentials/FileManager/FileManager+Utilities.swift | ||
index 525bef7..0b80db1 100644 | ||
--- a/Sources/FoundationEssentials/FileManager/FileManager+Utilities.swift | ||
+++ b/Sources/FoundationEssentials/FileManager/FileManager+Utilities.swift | ||
@@ -51,19 +51,19 @@ extension FILETIME { | ||
#if !os(Windows) | ||
extension stat { | ||
var isDirectory: Bool { | ||
- (self.st_mode & S_IFMT) == S_IFDIR | ||
+ (mode_t(self.st_mode) & S_IFMT) == S_IFDIR | ||
} | ||
|
||
var isRegular: Bool { | ||
- (self.st_mode & S_IFMT) == S_IFREG | ||
+ (mode_t(self.st_mode) & S_IFMT) == S_IFREG | ||
} | ||
|
||
var isSymbolicLink: Bool { | ||
- (self.st_mode & S_IFMT) == S_IFLNK | ||
+ (mode_t(self.st_mode) & S_IFMT) == S_IFLNK | ||
} | ||
|
||
var isSpecial: Bool { | ||
- let type = self.st_mode & S_IFMT | ||
+ let type = mode_t(self.st_mode) & S_IFMT | ||
return type == S_IFBLK || type == S_IFCHR | ||
} | ||
} | ||
diff --git a/Sources/FoundationEssentials/FileManager/FileOperations+Enumeration.swift b/Sources/FoundationEssentials/FileManager/FileOperations+Enumeration.swift | ||
index 2c9a02f..500da1d 100644 | ||
--- a/Sources/FoundationEssentials/FileManager/FileOperations+Enumeration.swift | ||
+++ b/Sources/FoundationEssentials/FileManager/FileOperations+Enumeration.swift | ||
@@ -367,7 +367,7 @@ struct _POSIXDirectoryContentsSequence: Sequence { | ||
let statDir = directoryPath + "/" + fileName | ||
if stat(statDir, &statBuf) == 0 { | ||
// #define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) | ||
- if (statBuf.st_mode & S_IFMT) == S_IFDIR { | ||
+ if (mode_t(statBuf.st_mode) & S_IFMT) == S_IFDIR { | ||
isDirectory = true | ||
} | ||
} | ||
diff --git a/Sources/FoundationEssentials/FileManager/FileOperations.swift b/Sources/FoundationEssentials/FileManager/FileOperations.swift | ||
index 14c6fd8..93972b0 100644 | ||
--- a/Sources/FoundationEssentials/FileManager/FileOperations.swift | ||
+++ b/Sources/FoundationEssentials/FileManager/FileOperations.swift | ||
@@ -870,7 +870,7 @@ enum _FileOperations { | ||
|
||
#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 | ||
+ let permissions = mode_t(fileInfo.st_mode) & ~S_IFMT | ||
guard fchmod(dstfd, permissions) == 0 else { | ||
try delegate.throwIfNecessary(errno, String(cString: srcPtr), String(cString: dstPtr)) | ||
return | ||
diff --git a/Sources/FoundationEssentials/ProcessInfo/ProcessInfo.swift b/Sources/FoundationEssentials/ProcessInfo/ProcessInfo.swift | ||
index 485f606..0d8680e 100644 | ||
--- a/Sources/FoundationEssentials/ProcessInfo/ProcessInfo.swift | ||
+++ b/Sources/FoundationEssentials/ProcessInfo/ProcessInfo.swift | ||
@@ -199,7 +199,10 @@ final class _ProcessInfo: Sendable { | ||
} | ||
|
||
var fullUserName: String { | ||
-#if canImport(Darwin) || os(Android) || canImport(Glibc) || canImport(Musl) | ||
+#if os(Android) && (arch(i386) || arch(arm)) | ||
+ // On LP32 Android, pw_gecos doesn't exist and is presumed to be NULL. | ||
+ return "" | ||
+#elseif canImport(Darwin) || os(Android) || canImport(Glibc) || canImport(Musl) | ||
let (euid, _) = Platform.getUGIDs() | ||
if let fullName = Platform.fullName(forUID: euid) { | ||
return fullName | ||
diff --git a/Sources/FoundationEssentials/String/String+Path.swift b/Sources/FoundationEssentials/String/String+Path.swift | ||
index 3185c1f..0c377cf 100644 | ||
--- a/Sources/FoundationEssentials/String/String+Path.swift | ||
+++ b/Sources/FoundationEssentials/String/String+Path.swift | ||
@@ -760,7 +760,7 @@ extension String { | ||
if lstat(buffer.baseAddress!, &statBuf) < 0 { | ||
return nil | ||
} | ||
- if statBuf.st_mode & S_IFMT == S_IFLNK { | ||
+ if mode_t(statBuf.st_mode) & S_IFMT == S_IFLNK { | ||
/* Examples: | ||
* fspath == /foo/bar0baz/quux/froboz | ||
* linkx == /tic/tac/toe | ||
-- | ||
2.46.0 | ||
|