apple / swift-openapi-generator

Generate Swift client and server code from an OpenAPI document.
https://swiftpackageindex.com/apple/swift-openapi-generator/documentation
Apache License 2.0
1.26k stars 92 forks source link

Possible linker issue: multiple definition of async main #306

Closed tib closed 6 months ago

tib commented 8 months ago

I tried to build a project under Linux, that relies on the Swift OpenAPI generator tool, but I received the following error message:

error: link command failed with exit code 1 (use -v to see invocation)
/usr/bin/ld.gold: error: .build/x86_64-unknown-linux-gnu/debug/swift_openapi_generator.build/Tool.swift.o: multiple definition of 'async_Main'
/usr/bin/ld.gold: .build/x86_64-unknown-linux-gnu/debug/MyProject.build/main.swift.o: previous definition here
/usr/bin/ld.gold: error: .build/x86_64-unknown-linux-gnu/debug/swift_openapi_generator.build/Tool.swift.o: multiple definition of 'async_MainTu'
/usr/bin/ld.gold: .build/x86_64-unknown-linux-gnu/debug/MyProject.build/main.swift.o: previous definition here
clang-13: error: linker command failed with exit code 1 (use -v to see invocation)

My project contains several targets, the main entrypoints are located in different main.swift files, I'm not using the @main annotation at all, just trying to execute my code directly from the main file. Have you ever faced such an issue? Any help is appreciated.

simonjbeaumont commented 8 months ago

I assume you're using Swift 5.8. This was a bug in Swift PM, which was fixed in 5.9: https://github.com/apple/swift-package-manager/pull/6714.

Can you confirm if this is still an issue with 5.9?

simonjbeaumont commented 8 months ago

@tib I noticed you 👍 the above message. Could you confirm whether this means you can or cannot reproduce the issue with Swift 5.9, or whether you're just acknowledging the request to try and haven't done so yet?

tib commented 8 months ago

Unfortunately, I can only confirm that the fix is not working. I'm running my tests using the swift:5.9-amazonlinux2 Docker image, and I'm still able to reproduce the linker issue.

czechboy0 commented 8 months ago

Based on this, I think it means your package also needs to use the tools version 5.9 in Package.swift: https://github.com/apple/swift-package-manager/pull/6714/files#diff-13eb4b18e8a4f2de8467dae905be6bdc133208159aded4aa6dbb6a03be21c6bdR705

Aka at the top:

// swift-tools-version:5.9
tib commented 8 months ago

Oh, nice catch, thanks for pointing this out. I'll update the swift tools version & see if makes any difference or not. brb with my answers in 10 mins. :)

tib commented 8 months ago

That definitely changed something, but now I've got plenty of undefined references. FYI:

configure.swift:2245: error: undefined reference to '$s5Vapor11ApplicationC6FluentE9databases0C3Kit9DatabasesCvg'
configure.swift:2245: error: undefined reference to '$s9SQLiteKit0A13ConfigurationV06FluentA6DriverE6memoryACvgZ'
configure.swift:2969: error: undefined reference to '$s9FluentKit28DatabaseConfigurationFactoryV0A12SQLiteDriverE6sqlite_26maxConnectionsPerEventLoop21connectionPoolTimeoutAC0fB00fD0V_Si7NIOCore10TimeAmountVtFZ'
configure.swift:2969: error: undefined reference to '$s9FluentKit10DatabaseIDV0A12SQLiteDriverE6sqliteACvgZ'
configure.swift:2973: error: undefined reference to '$s5Vapor11ApplicationC6FluentE9databases0C3Kit9DatabasesCvg'
configure.swift:2981: error: undefined reference to '$s9SQLiteKit0A13ConfigurationV06FluentA6DriverE4fileyACSSFZ'
configure.swift:3432: error: undefined reference to '$s9FluentKit28DatabaseConfigurationFactoryV0A12SQLiteDriverE6sqlite_26maxConnectionsPerEventLoop21connectionPoolTimeoutAC0fB00fD0V_Si7NIOCore10TimeAmountVtFZ'
configure.swift:3437: error: undefined reference to '$s9FluentKit10DatabaseIDV0A12SQLiteDriverE6sqliteACvgZ'
configure.swift:3932: error: undefined reference to '$s5Vapor11ApplicationC6FluentE9databases0C3Kit9DatabasesCvg'
configure.swift:4744: error: undefined reference to '$s11PostgresKit24SQLPostgresConfigurationV14ianaPortNumberSivgZ'
configure.swift:4930: error: undefined reference to '$s11PostgresNIO0A10ConnectionC13ConfigurationV3TLSV7disableAGvgZ'
configure.swift:4930: error: undefined reference to '$s11PostgresKit24SQLPostgresConfigurationV8hostname4port8username8password8database3tlsACSS_SiS2SSgAJ0A3NIO0A10ConnectionC0D0V3TLSVtcfC'
configure.swift:4930: error: undefined reference to '$s9FluentKit28DatabaseConfigurationFactoryV0A14PostgresDriverE8postgres13configuration26maxConnectionsPerEventLoop21connectionPoolTimeout11sqlLogLevelAC0fB0011SQLPostgresD0V_Si7NIOCore10TimeAmountV7Logging6LoggerV0T0OtFZ'
configure.swift:4930: error: undefined reference to '$s9FluentKit10DatabaseIDV0A14PostgresDriverE4psqlACvgZ'
configure.swift:8491: error: undefined reference to '$s5Vapor11ApplicationC6FluentE10migrations0C3Kit10MigrationsCvg'
<compiler-generated>:8713: error: undefined reference to '$s5Vapor11ApplicationC6FluentE11autoMigrate7NIOCore15EventLoopFutureCyytGyF'
<compiler-generated>:9363: error: undefined reference to '$s12OpenAPIVapor14VaporTransportCMa'
<compiler-generated>:10513: error: undefined reference to '$s12OpenAPIVapor14VaporTransportC13routesBuilderAC0C006RoutesF0_p_tcfC'
<compiler-generated>:10513: error: undefined reference to '$s5Vapor11ApplicationC6FluentE2db0C3Kit8Database_pvg'
<compiler-generated>:10518: error: undefined reference to '$s12OpenAPIVapor14VaporTransportC0A10APIRuntime06ServerD0AAWP'
/usr/bin/ld.gold: internal error in format_file_lineno, at dwarf_reader.cc:2249
clang-13: error: linker command failed with exit code 1 (use -v to see invocation)
error: fatalError

I have to do some debugging, and see if I can make the issues disappear somehow. Thanks for the help everyone. I appreciate it. 🙏

simonjbeaumont commented 8 months ago

@tib are you trying to write a testTarget for an executableTarget? If so, there are also some limitations in this scenario and our recommendation is put almost all your logic in a library target, with an associated test target, and wrap the library target in a very thin executable target for your entrypoint.

tib commented 8 months ago

Yes, that must be the case, I'll create a library target and see what happens next.

czechboy0 commented 8 months ago

@tib are you still seeing the issue or can we close this?

tib commented 8 months ago

I'm planning to test this using the sample project I shared with you, give me a day or so to verify this, please. Thank you.

tib commented 8 months ago

Seems like I've got other issues under Linux with 5.9.

[2938/2940] Wrapping AST for swift-openapi-examplePackageTests for debugging
error: link command failed with exit code 1 (use -v to see invocation)
/app/Sources/MyProjectHummingbirdServer/configure.swift:682: error: undefined reference to '$s11Hummingbird13HBApplicationC0A6FluentE03addC0yyF'
/app/Sources/MyProjectHummingbirdServer/configure.swift:1072: error: undefined reference to '$s11Hummingbird13HBApplicationC0A6FluentE6fluentAD8HBFluentVvg'
/app/Sources/MyProjectHummingbirdServer/configure.swift:1072: error: undefined reference to '$s9SQLiteKit0A13ConfigurationV06FluentA6DriverE6memoryACvgZ'
/app/Sources/MyProjectHummingbirdServer/configure.swift:2204: error: undefined reference to '$s9FluentKit28DatabaseConfigurationFactoryV0A12SQLiteDriverE6sqlite_26maxConnectionsPerEventLoop21connectionPoolTimeoutAC0fB00fD0V_Si7NIOCore10TimeAmountVtFZ'
/app/Sources/MyProjectHummingbirdServer/configure.swift:2382: error: undefined reference to '$s9FluentKit10DatabaseIDV0A12SQLiteDriverE6sqliteACvgZ'
/app/Sources/MyProjectHummingbirdServer/configure.swift:2774: error: undefined reference to '$s11Hummingbird13HBApplicationC0A6FluentE6fluentAD8HBFluentVvg'
/app/Sources/MyProjectHummingbirdServer/configure.swift:4433: error: undefined reference to '$s9SQLiteKit0A13ConfigurationV06FluentA6DriverE4fileyACSSFZ'
/app/Sources/MyProjectHummingbirdServer/configure.swift:5180: error: undefined reference to '$s9FluentKit28DatabaseConfigurationFactoryV0A12SQLiteDriverE6sqlite_26maxConnectionsPerEventLoop21connectionPoolTimeoutAC0fB00fD0V_Si7NIOCore10TimeAmountVtFZ'
/app/Sources/MyProjectHummingbirdServer/configure.swift:5847: error: undefined reference to '$s9FluentKit10DatabaseIDV0A12SQLiteDriverE6sqliteACvgZ'
/app/Sources/MyProjectHummingbirdServer/configure.swift:7036: error: undefined reference to '$s11Hummingbird13HBApplicationC0A6FluentE6fluentAD8HBFluentVvg'
<compiler-generated>:7461: error: undefined reference to '$s11Hummingbird13HBApplicationC0A6FluentE6fluentAD8HBFluentVvg'
<compiler-generated>:7461: error: undefined reference to '$s17HummingbirdFluent8HBFluentV7migrate7NIOCore15EventLoopFutureCyytGyF'
<compiler-generated>:7466: error: undefined reference to '$s11Hummingbird13HBApplicationC0A6FluentE2db0C3Kit8Database_pvg'
<compiler-generated>:7808: error: undefined reference to '$s18OpenAPIHummingbird18HBOpenAPITransportVyAC11Hummingbird13HBApplicationCcfC'
<compiler-generated>:7808: error: undefined reference to '$s18OpenAPIHummingbird18HBOpenAPITransportVN'
<compiler-generated>:7808: error: undefined reference to '$s18OpenAPIHummingbird18HBOpenAPITransportVN'
<compiler-generated>:7808: error: undefined reference to '$s18OpenAPIHummingbird18HBOpenAPITransportV0A10APIRuntime15ServerTransportAAWP'
<compiler-generated>:7808: error: undefined reference to '$s18OpenAPIHummingbird18HBOpenAPITransportV0A10APIRuntime15ServerTransportAAWP'
<compiler-generated>:4527: error: undefined reference to '$s14ArgumentParser15ParsableCommandPAAE4mainyyFZ'
/app/Sources/MyProjectHummingbirdServer/entrypoint.swift:4740: error: undefined reference to '$s14ArgumentParser15ParsableCommandPAAE13configurationAA0D13ConfigurationVvgZ'
/app/Sources/MyProjectHummingbirdServer/entrypoint.swift:4886: error: undefined reference to '$s14ArgumentParser15ParsableCommandPAAE12_commandNameSSvgZ'
/app/Sources/MyProjectHummingbirdServer/entrypoint.swift:4938: error: undefined reference to '$s14ArgumentParser17ParsableArgumentsPAAE8validateyyKF'
/app/Sources/MyProjectHummingbirdServer/entrypoint.swift:4938: error: undefined reference to '$s14ArgumentParser17ParsableArgumentsPAAE11_errorLabelSSvgZ'
/app/.build/aarch64-unknown-linux-gnu/debug/MyProjectHummingbirdServer.build/entrypoint.swift.o(.data.rel.ro+0x28): error: undefined reference to '$s14ArgumentParser15ParsableCommandMp'
/app/.build/aarch64-unknown-linux-gnu/debug/MyProjectHummingbirdServer.build/entrypoint.swift.o(.data.rel.ro+0x58): error: undefined reference to '$s14ArgumentParser17ParsableArgumentsMp'
/app/Sources/MyProjectVaporServer/configure.swift:2918: error: undefined reference to '$s5Vapor11ApplicationC6FluentE9databases0C3Kit9DatabasesCvg'
/app/Sources/MyProjectVaporServer/configure.swift:2918: error: undefined reference to '$s9SQLiteKit0A13ConfigurationV06FluentA6DriverE6memoryACvgZ'
/app/Sources/MyProjectVaporServer/configure.swift:4609: error: undefined reference to '$s9FluentKit28DatabaseConfigurationFactoryV0A12SQLiteDriverE6sqlite_26maxConnectionsPerEventLoop21connectionPoolTimeoutAC0fB00fD0V_Si7NIOCore10TimeAmountVtFZ'
<compiler-generated>:5280: error: undefined reference to '$s9FluentKit10DatabaseIDV0A12SQLiteDriverE6sqliteACvgZ'
/app/Sources/MyProjectVaporServer/configure.swift:5437: error: undefined reference to '$s5Vapor11ApplicationC6FluentE9databases0C3Kit9DatabasesCvg'
/app/Sources/MyProjectVaporServer/configure.swift:5437: error: undefined reference to '$s9SQLiteKit0A13ConfigurationV06FluentA6DriverE4fileyACSSFZ'
/app/Sources/MyProjectVaporServer/configure.swift:7091: error: undefined reference to '$s9FluentKit28DatabaseConfigurationFactoryV0A12SQLiteDriverE6sqlite_26maxConnectionsPerEventLoop21connectionPoolTimeoutAC0fB00fD0V_Si7NIOCore10TimeAmountVtFZ'
/app/Sources/MyProjectVaporServer/configure.swift:7091: error: undefined reference to '$s9FluentKit10DatabaseIDV0A12SQLiteDriverE6sqliteACvgZ'
/app/Sources/MyProjectVaporServer/configure.swift:7421: error: undefined reference to '$s5Vapor11ApplicationC6FluentE10migrations0C3Kit10MigrationsCvg'
<compiler-generated>:8483: error: undefined reference to '$s5Vapor11ApplicationC6FluentE11autoMigrate7NIOCore15EventLoopFutureCyytGyF'
<compiler-generated>:8503: error: undefined reference to '$s12OpenAPIVapor14VaporTransportCMa'
<compiler-generated>:8508: error: undefined reference to '$s12OpenAPIVapor14VaporTransportC13routesBuilderAC0C006RoutesF0_p_tcfC'
<compiler-generated>:8508: error: undefined reference to '$s5Vapor11ApplicationC6FluentE2db0C3Kit8Database_pvg'
<compiler-generated>:8513: error: undefined reference to '$s12OpenAPIVapor14VaporTransportC0A10APIRuntime06ServerD0AAWP'
<compiler-generated>:8513: error: undefined reference to '$s12OpenAPIVapor14VaporTransportC0A10APIRuntime06ServerD0AAWP'
clang-13: error: linker command failed with exit code 1 (use -v to see invocation)
error: fatalError
[2939/2940] Linking swift-openapi-examplePackageTests.xctest

Any ideas? 🤔

Update: you can try this out, on the dev branch in the private sample repository by running the following commands:

docker build -t my-project-test-image -f Docker/MyProjectTests.Dockerfile .
docker run --name my-project-test-instance --rm my-project-test-image

Many thanks for the help. 🙏

czechboy0 commented 8 months ago

Not sure, this seems like a SwiftPM issue, can you open an issue there to ask for help? If you comment out any test targets that link an executable, does the issue go away?

simonjbeaumont commented 8 months ago

If you comment out any test targets that link an executable, does the issue go away?

I strongly suspect this will be the issue, as mentioned in https://github.com/apple/swift-openapi-generator/issues/306#issuecomment-1742762046.

FWIW, I was able to run swift build --build-tests in a Linux container when commenting out the test targets that depend on executable targets.

tib commented 8 months ago

I was not able to run swift build --build-tests got more or less the same error message.

Just tried out using library targets insdtead of executables and I can confirm that approach works just fine (but I'm not too happy for the addition of the new targets as a workaround... 😅).

Anyway, the strange thing is that if I create a brand new Vapor project I'm able to build & test the executable target, without further issues, so something is definitely not working properly when I'm trying to use the Swift OpenAPI tools with SPM under Linux.

Shall we close this issue or do you want to investigate it a bit more?

czechboy0 commented 8 months ago

Let's keep it open, we should figure out the root cause. I suspect it won't be unique to Swift OpenAPI Generator, but will affect all projects with a build plugin producing files + an executable target linked in a test.

tib commented 8 months ago

All right, at least now we have a sample project that we can use to reproduce the issue... 🙈

Thank you again for your help. 🙏

czechboy0 commented 6 months ago

@tib I believe this is a bug in SwiftPM. Can you try the following workaround: add the dependencies for the symbols that you're seeing the errors for explicitly to the test target as well? I recently hit the same thing and this workaround worked for me.

In your case, it seems adding Hummingbird, OpenAPIHummingbird, Vapor, and OpenAPIVapor product dependencies to their respective test targets should fix it.

tib commented 6 months ago

Will try this tomorrow, I'm currently working on my spec lib update with the new OpenAPI stuff. 😅

tib commented 6 months ago

Update 1: I was using the wrong commit, now I'm trying to fix the issue with your proposed solution.

Update 2: Tried to test an executable target and liked other targets, still getting an error. Will do some more investigation...

czechboy0 commented 6 months ago

Is it still the missing symbols from the transports? Did you add the dependencies explicitly to the test target?

tib commented 6 months ago

Update 3: your workaround fixes the linker issue. I can confirm it. I had to add every single target dependency explicitly when I'm trying to test an executable.

czechboy0 commented 6 months ago

Thanks for letting us know! cc @simonjbeaumont