finagolfin / swift-android-sdk

Android SDKs for Swift
Apache License 2.0
136 stars 14 forks source link

Swift test failing on macOS with Swift 6.0 toolchain #173

Open marcprux opened 3 days ago

marcprux commented 3 days ago

CI is successfully compiling and running test cases against the Swift 6.0 toolchain and SDK (for example), but when I download the SDK and try to compile a simple test library (created by swift package init) locally on my macOS 15 machine, I get compile errors:

~/Library/Developer/Toolchains/swift-6.0.1-RELEASE.xctoolchain/usr/bin/swift build --destination ~/Downloads/swift-release-android-aarch64-24-sdk.json --build-tests --verbose ``` /Users/marc/Library/Developer/Toolchains/swift-6.0.1-RELEASE.xctoolchain/usr/bin/swift-frontend -frontend -c -primary-file /Users/marc/Desktop/swift-test-demo/.build/aarch64-unknown-linux-android24/debug/swift-test-demoPackageTests.derived/runner.swift -emit-dependencies-path /Users/marc/Desktop/swift-test-demo/.build/aarch64-unknown-linux-android24/debug/swift_test_demoPackageTests.build/runner.d -emit-reference-dependencies-path /Users/marc/Desktop/swift-test-demo/.build/aarch64-unknown-linux-android24/debug/swift_test_demoPackageTests.build/runner.swiftdeps -target aarch64-unknown-linux-android24 -Xllvm -aarch64-use-tbi -disable-objc-interop -sdk /opt/homebrew/share/android-ndk/toolchains/llvm/prebuilt/darwin-x86_64/sysroot -I /Users/marc/Desktop/swift-test-demo/.build/aarch64-unknown-linux-android24/debug/Modules -I /Users/marc/Library/Developer/Toolchains/swift-6.0.1-RELEASE.xctoolchain/usr/lib/swift/clang/include -color-diagnostics -enable-testing -g -debug-info-format=dwarf -dwarf-version=4 -module-cache-path /Users/marc/Desktop/swift-test-demo/.build/aarch64-unknown-linux-android24/debug/ModuleCache -Onone -D SWIFT_PACKAGE -D DEBUG -empty-abi-descriptor -resource-dir /Users/marc/Downloads/swift-release-android-aarch64-24-sdk/usr/lib/swift -enable-anonymous-context-mangled-names -file-compilation-dir /Users/marc/Desktop/swift-test-demo -Xcc --sysroot -Xcc /opt/homebrew/share/android-ndk/toolchains/llvm/prebuilt/darwin-x86_64/sysroot -Xcc -fPIC -Xcc -I/Users/marc/Downloads/swift-release-android-aarch64-24-sdk/usr/include -Xcc -g -Xcc -fno-omit-frame-pointer -module-name swift_test_demoPackageTests -package-name swift_test_demo -plugin-path /Users/marc/Library/Developer/Toolchains/swift-6.0.1-RELEASE.xctoolchain/usr/lib/swift/host/plugins -plugin-path /Users/marc/Library/Developer/Toolchains/swift-6.0.1-RELEASE.xctoolchain/usr/local/lib/swift/host/plugins -parse-as-library -o /Users/marc/Desktop/swift-test-demo/.build/aarch64-unknown-linux-android24/debug/swift_test_demoPackageTests.build/runner.swift.o -index-store-path /Users/marc/Desktop/swift-test-demo/.build/aarch64-unknown-linux-android24/debug/index/store -index-system-modules /Users/marc/Desktop/swift-test-demo/.build/aarch64-unknown-linux-android24/debug/swift-test-demoPackageTests.derived/runner.swift:171:22: error: cannot find 'open' in scope 169 | #else 170 | if fileDescriptor == nil { 171 | let fd = open(lockFile.path, O_WRONLY | O_CREAT | O_CLOEXEC, 0o666) | `- error: cannot find 'open' in scope 172 | if fd == -1 { 173 | fatalError("errno: \(errno), lockFile: \(lockFile)") /Users/marc/Desktop/swift-test-demo/.build/aarch64-unknown-linux-android24/debug/swift-test-demoPackageTests.derived/runner.swift:171:42: error: cannot find 'O_WRONLY' in scope 169 | #else 170 | if fileDescriptor == nil { 171 | let fd = open(lockFile.path, O_WRONLY | O_CREAT | O_CLOEXEC, 0o666) | `- error: cannot find 'O_WRONLY' in scope 172 | if fd == -1 { 173 | fatalError("errno: \(errno), lockFile: \(lockFile)") /Users/marc/Desktop/swift-test-demo/.build/aarch64-unknown-linux-android24/debug/swift-test-demoPackageTests.derived/runner.swift:171:53: error: cannot find 'O_CREAT' in scope 169 | #else 170 | if fileDescriptor == nil { 171 | let fd = open(lockFile.path, O_WRONLY | O_CREAT | O_CLOEXEC, 0o666) | `- error: cannot find 'O_CREAT' in scope 172 | if fd == -1 { 173 | fatalError("errno: \(errno), lockFile: \(lockFile)") /Users/marc/Desktop/swift-test-demo/.build/aarch64-unknown-linux-android24/debug/swift-test-demoPackageTests.derived/runner.swift:171:63: error: cannot find 'O_CLOEXEC' in scope 169 | #else 170 | if fileDescriptor == nil { 171 | let fd = open(lockFile.path, O_WRONLY | O_CREAT | O_CLOEXEC, 0o666) | `- error: cannot find 'O_CLOEXEC' in scope 172 | if fd == -1 { 173 | fatalError("errno: \(errno), lockFile: \(lockFile)") /Users/marc/Desktop/swift-test-demo/.build/aarch64-unknown-linux-android24/debug/swift-test-demoPackageTests.derived/runner.swift:173:38: error: cannot find 'errno' in scope 171 | let fd = open(lockFile.path, O_WRONLY | O_CREAT | O_CLOEXEC, 0o666) 172 | if fd == -1 { 173 | fatalError("errno: \(errno), lockFile: \(lockFile)") | `- error: cannot find 'errno' in scope 174 | } 175 | self.fileDescriptor = fd /opt/homebrew/share/android-ndk/toolchains/llvm/prebuilt/darwin-x86_64/sysroot/usr/include/errno.h:58:9: note: macro 'errno' unavailable: structure not supported 56 | * thread. 57 | */ 58 | #define errno (*__errno()) | `- note: macro 'errno' unavailable: structure not supported 59 | 60 | __END_DECLS /Users/marc/Desktop/swift-test-demo/.build/aarch64-unknown-linux-android24/debug/swift-test-demoPackageTests.derived/runner.swift:178:16: error: cannot find 'flock' in scope 176 | } 177 | while true { 178 | if flock(fileDescriptor!, LOCK_EX) == 0 { | `- error: cannot find 'flock' in scope 179 | break 180 | } /Users/marc/Desktop/swift-test-demo/.build/aarch64-unknown-linux-android24/debug/swift-test-demoPackageTests.derived/runner.swift:178:39: error: cannot find 'LOCK_EX' in scope 176 | } 177 | while true { 178 | if flock(fileDescriptor!, LOCK_EX) == 0 { | `- error: cannot find 'LOCK_EX' in scope 179 | break 180 | } /Users/marc/Desktop/swift-test-demo/.build/aarch64-unknown-linux-android24/debug/swift-test-demoPackageTests.derived/runner.swift:181:16: error: cannot find 'errno' in scope 179 | break 180 | } 181 | if errno == EINTR { continue } | `- error: cannot find 'errno' in scope 182 | fatalError("unable to acquire lock, errno: \(errno)") 183 | } /opt/homebrew/share/android-ndk/toolchains/llvm/prebuilt/darwin-x86_64/sysroot/usr/include/errno.h:58:9: note: macro 'errno' unavailable: structure not supported 56 | * thread. 57 | */ 58 | #define errno (*__errno()) | `- note: macro 'errno' unavailable: structure not supported 59 | 60 | __END_DECLS /Users/marc/Desktop/swift-test-demo/.build/aarch64-unknown-linux-android24/debug/swift-test-demoPackageTests.derived/runner.swift:182:58: error: cannot find 'errno' in scope 180 | } 181 | if errno == EINTR { continue } 182 | fatalError("unable to acquire lock, errno: \(errno)") | `- error: cannot find 'errno' in scope 183 | } 184 | #endif /opt/homebrew/share/android-ndk/toolchains/llvm/prebuilt/darwin-x86_64/sysroot/usr/include/errno.h:58:9: note: macro 'errno' unavailable: structure not supported 56 | * thread. 57 | */ 58 | #define errno (*__errno()) | `- note: macro 'errno' unavailable: structure not supported 59 | 60 | __END_DECLS /Users/marc/Desktop/swift-test-demo/.build/aarch64-unknown-linux-android24/debug/swift-test-demoPackageTests.derived/runner.swift:198:9: error: cannot find 'flock' in scope 196 | #else 197 | guard let fd = fileDescriptor else { return } 198 | flock(fd, LOCK_UN) | `- error: cannot find 'flock' in scope 199 | #endif 200 | } /Users/marc/Desktop/swift-test-demo/.build/aarch64-unknown-linux-android24/debug/swift-test-demoPackageTests.derived/runner.swift:198:19: error: cannot find 'LOCK_UN' in scope 196 | #else 197 | guard let fd = fileDescriptor else { return } 198 | flock(fd, LOCK_UN) | `- error: cannot find 'LOCK_UN' in scope 199 | #endif 200 | } /Users/marc/Desktop/swift-test-demo/.build/aarch64-unknown-linux-android24/debug/swift-test-demoPackageTests.derived/runner.swift:210:9: error: cannot find 'close' in scope 208 | #else 209 | guard let fd = fileDescriptor else { return } 210 | close(fd) | `- error: cannot find 'close' in scope 211 | #endif 212 | } ```

Looking at the generated runner.swift, it does import Bionic:

.build/aarch64-unknown-linux-android24/debug/swift-test-demoPackageTests.derived/runner.swift ```swift #if canImport(Testing) import Testing #endif #if canImport(XCTest) import Foundation import XCTest public final class SwiftPMXCTestObserver: NSObject { public override init() { super.init() XCTestObservationCenter.shared.addTestObserver(self) } } extension SwiftPMXCTestObserver: XCTestObservation { var testOutputPath: String { return "/Users/marc/Desktop/swift-test-demo/.build/aarch64-unknown-linux-android24/debug/testOutput.txt" } private func write(record: Encodable) { let lock = FileLock(at: URL(fileURLWithPath: self.testOutputPath + ".lock")) _ = try? lock.withLock { self._write(record: record) } } private func _write(record: Encodable) { if let data = try? JSONEncoder().encode(record) { if let fileHandle = FileHandle(forWritingAtPath: self.testOutputPath) { defer { fileHandle.closeFile() } fileHandle.seekToEndOfFile() fileHandle.write("\n".data(using: .utf8)!) fileHandle.write(data) } else { _ = try? data.write(to: URL(fileURLWithPath: self.testOutputPath)) } } } public func testBundleWillStart(_ testBundle: Bundle) { let record = TestBundleEventRecord(bundle: .init(testBundle), event: .start) write(record: TestEventRecord(bundleEvent: record)) } public func testSuiteWillStart(_ testSuite: XCTestSuite) { let record = TestSuiteEventRecord(suite: .init(testSuite), event: .start) write(record: TestEventRecord(suiteEvent: record)) } public func testCaseWillStart(_ testCase: XCTestCase) { let record = TestCaseEventRecord(testCase: .init(testCase), event: .start) write(record: TestEventRecord(caseEvent: record)) } #if canImport(Darwin) public func testCase(_ testCase: XCTestCase, didRecord issue: XCTIssue) { let record = TestCaseFailureRecord(testCase: .init(testCase), issue: .init(issue), failureKind: .unexpected) write(record: TestEventRecord(caseFailure: record)) } public func testCase(_ testCase: XCTestCase, didRecord expectedFailure: XCTExpectedFailure) { let record = TestCaseFailureRecord(testCase: .init(testCase), issue: .init(expectedFailure.issue), failureKind: .expected(failureReason: expectedFailure.failureReason)) write(record: TestEventRecord(caseFailure: record)) } #else public func testCase(_ testCase: XCTestCase, didFailWithDescription description: String, inFile filePath: String?, atLine lineNumber: Int) { let issue = TestIssue(description: description, inFile: filePath, atLine: lineNumber) let record = TestCaseFailureRecord(testCase: .init(testCase), issue: issue, failureKind: .unexpected) write(record: TestEventRecord(caseFailure: record)) } #endif public func testCaseDidFinish(_ testCase: XCTestCase) { let record = TestCaseEventRecord(testCase: .init(testCase), event: .finish) write(record: TestEventRecord(caseEvent: record)) } #if canImport(Darwin) public func testSuite(_ testSuite: XCTestSuite, didRecord issue: XCTIssue) { let record = TestSuiteFailureRecord(suite: .init(testSuite), issue: .init(issue), failureKind: .unexpected) write(record: TestEventRecord(suiteFailure: record)) } public func testSuite(_ testSuite: XCTestSuite, didRecord expectedFailure: XCTExpectedFailure) { let record = TestSuiteFailureRecord(suite: .init(testSuite), issue: .init(expectedFailure.issue), failureKind: .expected(failureReason: expectedFailure.failureReason)) write(record: TestEventRecord(suiteFailure: record)) } #else public func testSuite(_ testSuite: XCTestSuite, didFailWithDescription description: String, inFile filePath: String?, atLine lineNumber: Int) { let issue = TestIssue(description: description, inFile: filePath, atLine: lineNumber) let record = TestSuiteFailureRecord(suite: .init(testSuite), issue: issue, failureKind: .unexpected) write(record: TestEventRecord(suiteFailure: record)) } #endif public func testSuiteDidFinish(_ testSuite: XCTestSuite) { let record = TestSuiteEventRecord(suite: .init(testSuite), event: .finish) write(record: TestEventRecord(suiteEvent: record)) } public func testBundleDidFinish(_ testBundle: Bundle) { let record = TestBundleEventRecord(bundle: .init(testBundle), event: .finish) write(record: TestEventRecord(bundleEvent: record)) } } // FIXME: Copied from `Lock.swift` in TSCBasic, would be nice if we had a better way #if canImport(Glibc) @_exported import Glibc #elseif canImport(Musl) @_exported import Musl #elseif os(Windows) @_exported import CRT @_exported import WinSDK #elseif os(WASI) @_exported import WASILibc #elseif canImport(Bionic) @_exported import Bionic #else @_exported import Darwin.C #endif import Foundation public final class FileLock { #if os(Windows) private var handle: HANDLE? #else private var fileDescriptor: CInt? #endif private let lockFile: URL public init(at lockFile: URL) { self.lockFile = lockFile } public func lock() throws { #if os(Windows) if handle == nil { let h: HANDLE = lockFile.path.withCString(encodedAs: UTF16.self, { CreateFileW( $0, UInt32(GENERIC_READ) | UInt32(GENERIC_WRITE), UInt32(FILE_SHARE_READ) | UInt32(FILE_SHARE_WRITE), nil, DWORD(OPEN_ALWAYS), DWORD(FILE_ATTRIBUTE_NORMAL), nil ) }) if h == INVALID_HANDLE_VALUE { throw FileSystemError(errno: Int32(GetLastError()), lockFile) } self.handle = h } var overlapped = OVERLAPPED() overlapped.Offset = 0 overlapped.OffsetHigh = 0 overlapped.hEvent = nil if !LockFileEx(handle, DWORD(LOCKFILE_EXCLUSIVE_LOCK), 0, UInt32.max, UInt32.max, &overlapped) { throw ProcessLockError.unableToAquireLock(errno: Int32(GetLastError())) } #elseif os(WASI) // WASI doesn't support flock #else if fileDescriptor == nil { let fd = open(lockFile.path, O_WRONLY | O_CREAT | O_CLOEXEC, 0o666) if fd == -1 { fatalError("errno: \(errno), lockFile: \(lockFile)") } self.fileDescriptor = fd } while true { if flock(fileDescriptor!, LOCK_EX) == 0 { break } if errno == EINTR { continue } fatalError("unable to acquire lock, errno: \(errno)") } #endif } public func unlock() { #if os(Windows) var overlapped = OVERLAPPED() overlapped.Offset = 0 overlapped.OffsetHigh = 0 overlapped.hEvent = nil UnlockFileEx(handle, 0, UInt32.max, UInt32.max, &overlapped) #elseif os(WASI) // WASI doesn't support flock #else guard let fd = fileDescriptor else { return } flock(fd, LOCK_UN) #endif } deinit { #if os(Windows) guard let handle = handle else { return } CloseHandle(handle) #elseif os(WASI) // WASI doesn't support flock #else guard let fd = fileDescriptor else { return } close(fd) #endif } public func withLock(_ body: () throws -> T) throws -> T { try lock() defer { unlock() } return try body() } public func withLock(_ body: () async throws -> T) async throws -> T { try lock() defer { unlock() } return try await body() } } // FIXME: Copied from `XCTEvents.swift`, would be nice if we had a better way struct TestEventRecord: Codable { let caseFailure: TestCaseFailureRecord? let suiteFailure: TestSuiteFailureRecord? let bundleEvent: TestBundleEventRecord? let suiteEvent: TestSuiteEventRecord? let caseEvent: TestCaseEventRecord? init( caseFailure: TestCaseFailureRecord? = nil, suiteFailure: TestSuiteFailureRecord? = nil, bundleEvent: TestBundleEventRecord? = nil, suiteEvent: TestSuiteEventRecord? = nil, caseEvent: TestCaseEventRecord? = nil ) { self.caseFailure = caseFailure self.suiteFailure = suiteFailure self.bundleEvent = bundleEvent self.suiteEvent = suiteEvent self.caseEvent = caseEvent } } // MARK: - Records struct TestAttachment: Codable { let name: String? // TODO: Handle `userInfo: [AnyHashable : Any]?` let uniformTypeIdentifier: String let payload: Data? } struct TestBundleEventRecord: Codable { let bundle: TestBundle let event: TestEvent } struct TestCaseEventRecord: Codable { let testCase: TestCase let event: TestEvent } struct TestCaseFailureRecord: Codable, CustomStringConvertible { let testCase: TestCase let issue: TestIssue let failureKind: TestFailureKind var description: String { return "\(issue.sourceCodeContext.description)\(testCase) \(issue.compactDescription)" } } struct TestSuiteEventRecord: Codable { let suite: TestSuiteRecord let event: TestEvent } struct TestSuiteFailureRecord: Codable { let suite: TestSuiteRecord let issue: TestIssue let failureKind: TestFailureKind } // MARK: Primitives struct TestBundle: Codable { let bundleIdentifier: String? let bundlePath: String } struct TestCase: Codable { let name: String } struct TestErrorInfo: Codable { let description: String let type: String } enum TestEvent: Codable { case start case finish } enum TestFailureKind: Codable, Equatable { case unexpected case expected(failureReason: String?) var isExpected: Bool { switch self { case .expected: return true case .unexpected: return false } } } struct TestIssue: Codable { let type: TestIssueType let compactDescription: String let detailedDescription: String? let associatedError: TestErrorInfo? let sourceCodeContext: TestSourceCodeContext let attachments: [TestAttachment] } enum TestIssueType: Codable { case assertionFailure case performanceRegression case system case thrownError case uncaughtException case unmatchedExpectedFailure case unknown } struct TestLocation: Codable, CustomStringConvertible { let file: String let line: Int var description: String { return "\(file):\(line) " } } struct TestSourceCodeContext: Codable, CustomStringConvertible { let callStack: [TestSourceCodeFrame] let location: TestLocation? var description: String { return location?.description ?? "" } } struct TestSourceCodeFrame: Codable { let address: UInt64 let symbolInfo: TestSourceCodeSymbolInfo? let symbolicationError: TestErrorInfo? } struct TestSourceCodeSymbolInfo: Codable { let imageName: String let symbolName: String let location: TestLocation? } struct TestSuiteRecord: Codable { let name: String } // MARK: XCTest compatibility extension TestIssue { init(description: String, inFile filePath: String?, atLine lineNumber: Int) { let location: TestLocation? if let filePath = filePath { location = .init(file: filePath, line: lineNumber) } else { location = nil } self.init(type: .assertionFailure, compactDescription: description, detailedDescription: description, associatedError: nil, sourceCodeContext: .init(callStack: [], location: location), attachments: []) } } import XCTest #if canImport(Darwin) // XCTAttachment is unavailable in swift-corelibs-xctest. extension TestAttachment { init(_ attachment: XCTAttachment) { self.init( name: attachment.name, uniformTypeIdentifier: attachment.uniformTypeIdentifier, payload: attachment.value(forKey: "payload") as? Data ) } } #endif extension TestBundle { init(_ testBundle: Bundle) { self.init( bundleIdentifier: testBundle.bundleIdentifier, bundlePath: testBundle.bundlePath ) } } extension TestCase { init(_ testCase: XCTestCase) { self.init(name: testCase.name) } } extension TestErrorInfo { init(_ error: Swift.Error) { self.init(description: "\(error)", type: "\(Swift.type(of: error))") } } #if canImport(Darwin) // XCTIssue is unavailable in swift-corelibs-xctest. extension TestIssue { init(_ issue: XCTIssue) { self.init( type: .init(issue.type), compactDescription: issue.compactDescription, detailedDescription: issue.detailedDescription, associatedError: issue.associatedError.map { .init($0) }, sourceCodeContext: .init(issue.sourceCodeContext), attachments: issue.attachments.map { .init($0) } ) } } extension TestIssueType { init(_ type: XCTIssue.IssueType) { switch type { case .assertionFailure: self = .assertionFailure case .thrownError: self = .thrownError case .uncaughtException: self = .uncaughtException case .performanceRegression: self = .performanceRegression case .system: self = .system case .unmatchedExpectedFailure: self = .unmatchedExpectedFailure @unknown default: self = .unknown } } } #endif #if canImport(Darwin) // XCTSourceCodeLocation/XCTSourceCodeContext/XCTSourceCodeFrame/XCTSourceCodeSymbolInfo is unavailable in swift-corelibs-xctest. extension TestLocation { init(_ location: XCTSourceCodeLocation) { self.init( file: location.fileURL.absoluteString, line: location.lineNumber ) } } extension TestSourceCodeContext { init(_ context: XCTSourceCodeContext) { self.init( callStack: context.callStack.map { .init($0) }, location: context.location.map { .init($0) } ) } } extension TestSourceCodeFrame { init(_ frame: XCTSourceCodeFrame) { self.init( address: frame.address, symbolInfo: (try? frame.symbolInfo()).map { .init($0) }, symbolicationError: frame.symbolicationError.map { .init($0) } ) } } extension TestSourceCodeSymbolInfo { init(_ symbolInfo: XCTSourceCodeSymbolInfo) { self.init( imageName: symbolInfo.imageName, symbolName: symbolInfo.symbolName, location: symbolInfo.location.map { .init($0) } ) } } #endif extension TestSuiteRecord { init(_ testSuite: XCTestSuite) { self.init(name: testSuite.name) } } import XCTest import swift_test_demoPackageDiscoveredTests #endif @main @available(macOS 10.15, iOS 11, watchOS 4, tvOS 11, *) @available(*, deprecated, message: "Not actually deprecated. Marked as deprecated to allow inclusion of deprecated tests (which test deprecated functionality) without warnings") struct Runner { private static func testingLibrary() -> String { var iterator = CommandLine.arguments.makeIterator() while let argument = iterator.next() { if argument == "--testing-library", let libraryName = iterator.next() { return libraryName.lowercased() } } // Fallback if not specified: run XCTest (legacy behavior) return "xctest" } #if true @_silgen_name("$ss13_runAsyncMainyyyyYaKcF") private static func _runAsyncMain(_ asyncFun: @Sendable @escaping () async throws -> ()) #endif static func main() { let testingLibrary = Self.testingLibrary() #if canImport(Testing) if testingLibrary == "swift-testing" { #if true _runAsyncMain { await Testing.__swiftPMEntryPoint() as Never } #else await Testing.__swiftPMEntryPoint() as Never #endif } #endif #if canImport(XCTest) if testingLibrary == "xctest" { XCTMain(__allDiscoveredTests()) as Never } #endif } } ```

And when I compile this file manually, it indeed fails to find flock and __errno and all the other reported symbols. But if I manually add in import Android, then it compiles fine.

Since this is working in CI against the assembled SDK (https://github.com/finagolfin/swift-android-sdk/pull/167) and not on my machine, I'm guessing there must be some difference in the swift modules being imported, or their relation to each other. But I'm not sure what import Android is expected to be imported, versus import Bionic.

Should runner.swift be importing Android instead of Bionic? Or is there some other issue preventing the generated runner from being built?

finagolfin commented 3 days ago

CI is successfully compiling and running test cases against the Swift 6.0 toolchain and SDK

No, it wasn't. I had to patch it specifically for this issue to get it to work on the CI.

But if I manually add in import Android, then it compiles fine.

I'm surprised that works. On linux, it regenerates that file each time so modifying the file makes no difference.

Should runner.swift be importing Android instead of Bionic?

Yes, it is one of the many files showing these import errors now, swift-server/async-http-client#773, as you can see in the new Swift 6 patches too.

Or is there some other issue preventing the generated runner from being built?

That's the one, I will have to patch SwiftPM to fix that. I forgot about it because I was hoping to get an explanation for the underlying reason from the Swift devs, but in the meantime we were not using that broken SwiftPM on the CI, as I had stopped using the latest snapshots because the Foundation rewrite hadn't been ported yet, so it wasn't affecting me.

I'll try to get it in for the next patch release. In the meantime, directly modifying the script text inside the SwiftPM binary with those three perl commands should get your local builds working.

marcprux commented 2 days ago

CI is successfully compiling and running test cases against the Swift 6.0 toolchain and SDK

No, it wasn't. I had to patch it specifically for this issue to get it to work on the CI.

Ahh, I hadn't understood what those perl replacements were doing. Devilishly clever!

But if I manually add in import Android, then it compiles fine.

I'm surprised that works. On linux, it regenerates that file each time so modifying the file makes no difference.

I just mean that I compile runner.swift "by hand" after manually changing the imports. You are right that swift test re-generates the file for each run, and so this doesn't enable the tests to actually run.

I'll try to get it in for the next patch release. In the meantime, directly modifying the script text inside the SwiftPM binary with those three perl commands should get your local builds working.

Will do, thanks for the tip!