Skip to content

Swift test failing on macOS with Swift 6.0 toolchain #173

Closed
@marcprux

Description

@marcprux

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
#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<T>(_ body: () throws -> T) throws -> T {
        try lock()
        defer { unlock() }
        return try body()
    }

    public func withLock<T>(_ 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 (#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?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions