apple / swift-nio

Event-driven network application framework for high performance protocol servers & clients, non-blocking.
https://swiftpackageindex.com/apple/swift-nio/documentation
Apache License 2.0
7.99k stars 651 forks source link

Build errors when building against a Static Linux SDK #2893

Closed briancoyner closed 1 month ago

briancoyner commented 1 month ago

Expected behavior

An application with a dependency on SwiftNIO successfully builds with a Swift 6 OSS toolchain + Static Linux SDK.

Note: The swift-6.0-DEVELOPMENT-SNAPSHOT-2024-09-17-a toolchain is used vs the swift-6.0-RELEASE because of another issue with swift-collections. That issue is fixed in the "09-17" toolchain release.

Note: Xcode 15.4.0 vs Xcode 16.0.0 because of an issue described here:

Actual behavior

main branch error

$ xcrun --toolchain org.swift.600202409171a swift build --swift-sdk aarch64-swift-linux-musl
Building for debugging...
In file included from /Users/someuser/Developer/some-app/.build/checkouts/swift-nio/Sources/CNIOLinux/shim.c:25:
/Users/someuser/Developer/some-app/.build/checkouts/swift-nio/Sources/CNIOLinux/include/CNIOLinux.h:33:10: fatal error: 'linux/udp.h' file not found
   33 | #include <linux/udp.h>
      |          ^~~~~~~~~~~~~
1 error generated.

2.72.0 tag error

$ xcrun --toolchain org.swift.600202409171a swift build --swift-sdk aarch64-swift-linux-musl
/Users/someuser/Developer/some-app/.build/checkouts/swift-nio/Sources/NIOPosix/PosixSingletons+ConcurrencyTakeOver.swift:76:12: error: conflicting arguments to generic parameter 'T' ('Optional<UnsafeRawPointer>.AtomicRepresentation' vs. 'Optional<UnsafeRawPointer>.AtomicRepresentation')

...

/Users/someuser/Developer/some-app/.build/checkouts/swift-nio/Sources/NIOPosix/PosixSingletons+ConcurrencyTakeOver.swift:112:35: error: 'nil' requires a contextual type

...

additional errors 

Steps to reproduce

  1. Install the Swift 6 OSS toolchain + SDK (swift-6.0-DEVELOPMENT-SNAPSHOT-2024-09-17-a).
  2. A simple application using SPM with a dependency on SwiftNIO.
  3. Execute the following to build the application.
$ xcrun --toolchain org.swift.600202409171a swift build --swift-sdk aarch64-swift-linux-musl
See errors noted above (for both `main` and `2.72.0`)

Also, building without the Static Linux SDK succeeds:

$ xcrun --toolchain org.swift.600202409171a swift build                                     
Building for debugging...
[215/215] Applying Demo
Build complete! (20.94s)

If possible, minimal yet complete reproducer code (or URL to code)

Here's a basic Package.swift manifest that can be used:

// swift-tools-version: 6.0
import PackageDescription

let package = Package(
    name: "Demo",
    platforms: [
       .macOS(.v14)
    ],
    dependencies: [
        .package(url: "https://github.com/apple/swift-nio.git", .upToNextMajor(from: "2.70.0"))
        // .package(url: "https://github.com/apple/swift-nio.git", branch: "main")
    ],
    targets: [
        .executableTarget(
            name: "Demo",
            dependencies: [
                .product(name: "NIOPosix", package: "swift-nio")
            ],
            swiftSettings: swiftSettings
        ),
    ],
    swiftLanguageModes: [
        .v6
    ]
)

// MARK: - Swift Settings

var swiftSettings: [SwiftSetting] {
    return [
        .enableUpcomingFeature("ExistentialAny")
    ]
}

SwiftNIO version/commit hash

main and 2.72.0

System & version information

Sonoma 14.6.1

*****
***** Swift Toolchain
*****   Name: swift-6.0-DEVELOPMENT-SNAPSHOT-2024-09-17-a
*****   Path: /Library/Developer/Toolchains/swift-6.0-DEVELOPMENT-SNAPSHOT-2024-09-17-a.xctoolchain
*****     ID: org.swift.600202409171a
*****    SDK: aarch64-swift-linux-musl
*****    SPM: Swift Package Manager - Swift 6.0.0-dev
*****  Xcode: /Applications/Xcode15.4.0.app/Contents/Developer
*****
Lukasa commented 1 month ago

Thanks for this! The main issues were introduced by #2891, so @rnro should probably take a look at that.

For the others, those issues are a bit weird. conflicting arguments to generic parameter 'T' ('Optional<UnsafeRawPointer>.AtomicRepresentation' vs. 'Optional<UnsafeRawPointer>.AtomicRepresentation') appears to be complaining about two identical types. The other error is also odd.

@al45tair, do you have any ideas what's going on there?

rnro commented 1 month ago

Thanks for letting us know about this. I've put up a PR which should fixup the linux/udp.h issue. https://github.com/apple/swift-nio/pull/2894

al45tair commented 1 month ago

@Lukasa I'm not sure about the AtomicRepresentation error; that likely means that we've got two modules defining some type or other, but normally that happens with C types rather than Swift ones.

As for <linux/udp.h>, if NIO has started requiring that then we may need to work out what it's using and add that to the Static SDK. Note that the Static SDK does not include the Linux headers, because those are GPL'd; to make things work for NIO and a couple of other things, it does include some shims that declare just the things that are being used.

Lukasa commented 1 month ago

We just reverted the requirement of it: we'll use it if it's there, but we don't require it.

AtomicRepresentation is the one I'm worried about, but I don't see where it could be coming from. Any chances this is related to using the toolchain with an older xcode?

briancoyner commented 1 month ago

In case it helps, the swift-6.0-DEVELOPMENT-SNAPSHOT-2024-07-02-a toolchain + SDK builds without any known issues. More specifically, a Vapor (4.104+) app with dependencies on SwiftNIO (2.70.0), plus all transitive dependencies builds and runs on that toolchain + SDK. I don't recall if the swift-6.0-DEVELOPMENT-SNAPSHOT-2024-08-22-a worked or not (that was the last dev toolchain I tried before the release). I am thinking it didn't work since I reverted my project back to 07-02.

al45tair commented 1 month ago

AtomicRepresentation is the one I'm worried about, but I don't see where it could be coming from. Any chances this is related to using the toolchain with an older xcode?

Not sure. You're not the only one reporting this problem, FWIW; I'm intending to spend some time trying to work out what's going on a little later today. My guess is that those types are different, in spite of being rendered the same in the error message, and usually that means they're from different modules.

finagolfin commented 1 month ago

I am also seeing these errors when trying to cross-compile NIO on macOS 13 using the OSS toolchain to Android in my CI:

/Users/runner/work/swift-android-sdk/swift-android-sdk/swift-nio/Sources/NIOPosix/PosixSingletons+ConcurrencyTakeOver.swift:76:12: error: conflicting arguments to generic parameter 'T' ('Optional<UnsafeRawPointer>.AtomicRepresentation' vs. 'Optional<UnsafeRawPointer>.AtomicRepresentation')
 74 |             dlopen(nil, RTLD_NOW),
 75 |             "swift_task_enqueueGlobal_hook"
 76 |         )?.assumingMemoryBound(to: UnsafeRawPointer?.AtomicRepresentation.self)
    |            `- error: conflicting arguments to generic parameter 'T' ('Optional<UnsafeRawPointer>.AtomicRepresentation' vs. 'Optional<UnsafeRawPointer>.AtomicRepresentation')
 77 |         guard let concurrencyEnqueueGlobalHookPtr = concurrencyEnqueueGlobalHookPtr else {
 78 |             return false

/Users/runner/work/swift-android-sdk/swift-android-sdk/swift-nio/Sources/NIOPosix/PosixSingletons+ConcurrencyTakeOver.swift:112:35: error: 'nil' requires a contextual type
110 |                 guard
111 |                     concurrencyEnqueueGlobalHookAtomic.compareExchange(
112 |                         expected: nil,
    |                                   `- error: 'nil' requires a contextual type
113 |                         desired: enqueueOnNIOPtr.pointee,
114 |                         ordering: .relaxed

/Users/runner/work/swift-android-sdk/swift-android-sdk/swift-nio/Sources/NIOPosix/PosixSingletons+ConcurrencyTakeOver.swift:114:36: error: cannot infer contextual base in reference to member 'relaxed'
112 |                         expected: nil,
113 |                         desired: enqueueOnNIOPtr.pointee,
114 |                         ordering: .relaxed
    |                                    `- error: cannot infer contextual base in reference to member 'relaxed'
115 |                     ).exchanged
116 |                 else {

Cross-compiling with the exact same Android SDK from a linux runner using the official Swift linux toolchain works fine. Cross-compilation from macOS using 5.10.1 and the official July 15 6.1 snapshot or July 19 6.0 snapshot works in my Android CI, so this probably regressed in the macOS toolchain in the last couple months, when there were no official snapshots of the static linux SDK or my Android SDK to catch it.

al45tair commented 1 month ago

OK, the AtomicRepresentation problem is apparently happening because both Synchronization and Atomics export AtomicRepresentation, and because Foundation imports Synchronization, and because there's a issue in the compiler that makes extensions globally visible, we end up with two conflicting AtomicRepresentation types (rdar://132885963, apparently).

This problem doesn't affect Apple platforms because Foundation is build with library evolution, and the visibility issue only happens when that is turned off, as is the case on non-Apple platforms.

finagolfin commented 1 month ago

I can confirm the linked workaround got NIO to cross-compile from mac to Android again, and all the same tests pass on the Android emulator.

leinelissen commented 1 month ago

I can also confirm that swift-6.0-DEVELOPMENT-SNAPSHOT-2024-09-17-a and the accompanying Linux SDK can successfully cross-compile a Vapor app for the latest swift-nio commit on main (1b33db2).