grpc-swift: "undefined symbols" error when building for release.
What are you trying to achieve?
I’m the maintainer of ZcashLightClientKit. I’m trying to release a new version of the SDK through Cocoapods and I’m having problems with SwiftNIO (it’s a dependency of grpc-swift).
What have you tried so far?
Building for release fails. 😦 whereas debug builds seem to work fine (probably because the active architecture of my mac is intel 64-bit)
The error after pod trunk push --skip-tests --allow-warnings verbose
Undefined symbols for architecture arm64:
"_catmc_nio_atomic__Bool_compare_and_exchange", referenced from:
NIOPosix.PendingDatagramWritesManager.add(envelope: NIOCore.AddressedEnvelope<NIOCore.ByteBuffer>, promise: NIOCore.EventLoopPromise<()>?) -> Swift.Bool in PendingDatagramWritesManager.o
NIOPosix.PendingStreamWritesManager.add(data: NIOCore.IOData, promise: NIOCore.EventLoopPromise<()>?) -> Swift.Bool in PendingWritesManager.o
"_catmc_nio_atomic__Bool_create_with_existing_storage", referenced from:
NIOPosix.PendingDatagramWritesManager.init(msgs: Swift.UnsafeMutableBufferPointer<__C.CNIODarwin_mmsghdr>, iovecs: Swift.UnsafeMutableBufferPointer<__C.iovec>, addresses: Swift.UnsafeMutableBufferPointer<__C.sockaddr_storage>, storageRefs: Swift.UnsafeMutableBufferPointer<Swift.Unmanaged<Swift.AnyObject>>, controlMessageStorage: NIOPosix.UnsafeControlMessageStorage) -> NIOPosix.PendingDatagramWritesManager in PendingDatagramWritesManager.o
NIOPosix.PendingStreamWritesManager.init(iovecs: Swift.UnsafeMutableBufferPointer<__C.iovec>, storageRefs: Swift.UnsafeMutableBufferPointer<Swift.Unmanaged<Swift.AnyObject>>) -> NIOPosix.PendingStreamWritesManager in PendingWritesManager.o
function signature specialization <Arg[1] = Owned To Guaranteed, Arg[2] = Owned To Guaranteed> of generic specialization <NIOPosix.ServerSocket> of NIOPosix.BaseSocketChannel.init(socket: A, parent: NIOCore.Channel?, eventLoop: NIOPosix.SelectableEventLoop, recvAllocator: NIOCore.RecvByteBufferAllocator) throws -> NIOPosix.BaseSocketChannel<A> in SocketChannel.o
function signature specialization <Arg[1] = Owned To Guaranteed, Arg[2] = Owned To Guaranteed> of generic specialization <NIOPosix.PipePair> of NIOPosix.BaseSocketChannel.init(socket: A, parent: NIOCore.Channel?, eventLoop: NIOPosix.SelectableEventLoop, recvAllocator: NIOCore.RecvByteBufferAllocator) throws -> NIOPosix.BaseSocketChannel<A> in SocketChannel.o
"_catmc_nio_atomic_long_create_with_existing_storage", referenced from:
variable initialization expression of NIOPosix.MultiThreadedEventLoopGroup.(index in _C2B1528F4FBA68A3DBFA89DBAEBE9D4D) : NIOConcurrencyHelpers.NIOAtomic<Swift.Int> in BaseSocket.o
one-time initialization function for (nextEventLoopGroupID in _C2B1528F4FBA68A3DBFA89DBAEBE9D4D) in MultiThreadedEventLoopGroup.o
function signature specialization <Arg[0] = Owned To Guaranteed, Arg[1] = Owned To Guaranteed> of NIOPosix.MultiThreadedEventLoopGroup.init(threadInitializers: [(NIOPosix.NIOThread) -> ()], selectorFactory: () throws -> NIOPosix.Selector<NIOPosix.NIORegistration>) -> NIOPosix.MultiThreadedEventLoopGroup in MultiThreadedEventLoopGroup.o
"_catmc_nio_atomic__Bool_store", referenced from:
NIOPosix.BaseSocketChannel.close0(error: Swift.Error, mode: NIOCore.CloseMode, promise: NIOCore.EventLoopPromise<()>?) -> () in BaseSocketChannel.o
NIOPosix.BaseSocketChannel.becomeActive0(promise: NIOCore.EventLoopPromise<()>?) -> () in BaseSocketChannel.o
NIOPosix.PendingDatagramWritesManager.(didWrite in _DAB463F912477C8697B1F8AEBF8BD15A)(_: NIOPosix.IOResult<Swift.Int>, messages: Swift.UnsafeMutableBufferPointer<__C.CNIODarwin_mmsghdr>?) -> NIOPosix.OneWriteOperationResult in PendingDatagramWritesManager.o
function signature specialization <Arg[0] = [Closure Propagated : closure #1 (NIOPosix.WriteMechanism) throws -> NIOPosix.OneWriteOperationResult in NIOPosix.PendingStreamWritesManager.triggerAppropriateWriteOperations(scalarBufferWriteOperation: (Swift.UnsafeRawBufferPointer) throws -> NIOPosix.IOResult<Swift.Int>, vectorBufferWriteOperation: (Swift.UnsafeBufferPointer<__C.iovec>) throws -> NIOPosix.IOResult<Swift.Int>, scalarFileWriteOperation: (Swift.Int32, Swift.Int, Swift.Int) throws -> NIOPosix.IOResult<Swift.Int>) throws -> NIOPosix.OverallWriteResult, Argument Types : [NIOPosix.PendingStreamWritesManager@callee_guaranteed (@unowned Swift.UnsafeRawBufferPointer) -> (@unowned NIOPosix.IOResult<Swift.Int>, @error @owned Swift.Error)@callee_guaranteed (@unowned Swift.UnsafeBufferPointer<__C.iovec>) -> (@unowned NIOPosix.IOResult<Swift.Int>, @error @owned Swift.Error)@callee_guaranteed (@unowned Swift.Int32, @unowned Swift.Int, @unowned Swift.Int) -> (@unowned NIOPosix.IOResult<Swift.Int>, @error @owned Swift.Error)]> of generic specialization <NIOPosix.PendingStreamWritesManager> of (extension in NIOPosix):NIOPosix.PendingWritesManager.triggerWriteOperations(triggerOneWriteOperation: (NIOPosix.WriteMechanism) throws -> NIOPosix.OneWriteOperationResult) throws -> NIOPosix.OverallWriteResult in PendingWritesManager.o
NIOPosix.PendingStreamWritesManager.(didWrite in _E8AD929129EAA2971226E80CBC6171E1)(itemCount: Swift.Int, result: NIOPosix.IOResult<Swift.Int>) -> NIOPosix.OneWriteOperationResult in PendingWritesManager.o
generic specialization <NIOPosix.ServerSocket> of NIOPosix.BaseSocketChannel.close0(error: Swift.Error, mode: NIOCore.CloseMode, promise: NIOCore.EventLoopPromise<()>?) -> () in SocketChannel.o
generic specialization <NIOPosix.Socket> of NIOPosix.BaseSocketChannel.close0(error: Swift.Error, mode: NIOCore.CloseMode, promise: NIOCore.EventLoopPromise<()>?) -> () in SocketChannel.o
...
"_catmc_nio_atomic__Bool_load", referenced from:
NIOPosix.BaseSocketChannel.isActive.getter : Swift.Bool in BaseSocketChannel.o
NIOPosix.BaseStreamSocketChannel.isWritable.getter : Swift.Bool in BaseStreamSocketChannel.o
function signature specialization <Arg[0] = [Closure Propagated : closure #1 (NIOPosix.WriteMechanism) throws -> NIOPosix.OneWriteOperationResult in NIOPosix.PendingDatagramWritesManager.triggerAppropriateWriteOperations(scalarWriteOperation: (Swift.UnsafeRawBufferPointer, Swift.UnsafePointer<__C.sockaddr>, Swift.UInt32, Swift.Optional<NIOCore.AddressedEnvelope<NIOCore.ByteBuffer>.Metadata>) throws -> NIOPosix.IOResult<Swift.Int>, vectorWriteOperation: (Swift.UnsafeMutableBufferPointer<__C.CNIODarwin_mmsghdr>) throws -> NIOPosix.IOResult<Swift.Int>) throws -> NIOPosix.OverallWriteResult, Argument Types : [NIOPosix.PendingDatagramWritesManager@callee_guaranteed (@unowned Swift.UnsafeRawBufferPointer, @unowned Swift.UnsafePointer<__C.sockaddr>, @unowned Swift.UInt32, @guaranteed NIOCore.AddressedEnvelope<NIOCore.ByteBuffer>.Metadata?) -> (@unowned NIOPosix.IOResult<Swift.Int>, @error @owned Swift.Error)@callee_guaranteed (@unowned Swift.UnsafeMutableBufferPointer<__C.CNIODarwin_mmsghdr>) -> (@unowned NIOPosix.IOResult<Swift.Int>, @error @owned Swift.Error)]> of generic specialization <NIOPosix.PendingDatagramWritesManager> of (extension in NIOPosix):NIOPosix.PendingWritesManager.triggerWriteOperations(triggerOneWriteOperation: (NIOPosix.WriteMechanism) throws -> NIOPosix.OneWriteOperationResult) throws -> NIOPosix.OverallWriteResult in PendingWritesManager.o
function signature specialization <Arg[0] = [Closure Propagated : closure #1 (NIOPosix.WriteMechanism) throws -> NIOPosix.OneWriteOperationResult in NIOPosix.PendingStreamWritesManager.triggerAppropriateWriteOperations(scalarBufferWriteOperation: (Swift.UnsafeRawBufferPointer) throws -> NIOPosix.IOResult<Swift.Int>, vectorBufferWriteOperation: (Swift.UnsafeBufferPointer<__C.iovec>) throws -> NIOPosix.IOResult<Swift.Int>, scalarFileWriteOperation: (Swift.Int32, Swift.Int, Swift.Int) throws -> NIOPosix.IOResult<Swift.Int>) throws -> NIOPosix.OverallWriteResult, Argument Types : [NIOPosix.PendingStreamWritesManager@callee_guaranteed (@unowned Swift.UnsafeRawBufferPointer) -> (@unowned NIOPosix.IOResult<Swift.Int>, @error @owned Swift.Error)@callee_guaranteed (@unowned Swift.UnsafeBufferPointer<__C.iovec>) -> (@unowned NIOPosix.IOResult<Swift.Int>, @error @owned Swift.Error)@callee_guaranteed (@unowned Swift.Int32, @unowned Swift.Int, @unowned Swift.Int) -> (@unowned NIOPosix.IOResult<Swift.Int>, @error @owned Swift.Error)]> of generic specialization <NIOPosix.PendingStreamWritesManager> of (extension in NIOPosix):NIOPosix.PendingWritesManager.triggerWriteOperations(triggerOneWriteOperation: (NIOPosix.WriteMechanism) throws -> NIOPosix.OneWriteOperationResult) throws -> NIOPosix.OverallWriteResult in PendingWritesManager.o
NIOPosix.PendingStreamWritesManager.description.getter : Swift.String in PendingWritesManager.o
NIOPosix.PipeChannel.description.getter : Swift.String in PipeChannel.o
NIOPosix.DatagramChannel.isWritable.getter : Swift.Bool in SocketChannel.o
...
"_catmc_nio_atomic_unsigned_long_long_create_with_existing_storage", referenced from:
variable initialization expression of NIOPosix.SelectableEventLoop.scheduledTaskCounter : NIOConcurrencyHelpers.NIOAtomic<Swift.UInt64> in BaseSocket.o
function signature specialization <Arg[0] = Owned To Guaranteed, Arg[1] = Owned To Guaranteed, Arg[2] = Owned To Guaranteed> of NIOPosix.SelectableEventLoop.init(thread: NIOPosix.NIOThread, parentGroup: NIOPosix.MultiThreadedEventLoopGroup?, selector: NIOPosix.Selector<NIOPosix.NIORegistration>, canBeShutdownIndividually: Swift.Bool) -> NIOPosix.SelectableEventLoop in SelectableEventLoop.o
"_catmc_nio_atomic_long_add", referenced from:
NIOPosix.MultiThreadedEventLoopGroup.next() -> NIOCore.EventLoop in MultiThreadedEventLoopGroup.o
function signature specialization <Arg[0] = Owned To Guaranteed, Arg[1] = Owned To Guaranteed> of NIOPosix.MultiThreadedEventLoopGroup.init(threadInitializers: [(NIOPosix.NIOThread) -> ()], selectorFactory: () throws -> NIOPosix.Selector<NIOPosix.NIORegistration>) -> NIOPosix.MultiThreadedEventLoopGroup in MultiThreadedEventLoopGroup.o
"_catmc_nio_atomic_unsigned_long_long_add", referenced from:
merged generic specialization <NIOPosix.SelectableEventLoop, NIOCore.EventLoopFuture<()>> of (extension in NIOCore):NIOCore.EventLoop.submit<A>(() throws -> A1) -> NIOCore.EventLoopFuture<A1> in Bootstrap.o
NIOPosix.SelectableEventLoop.initiateClose(queue: __C.OS_dispatch_queue, completionHandler: (Swift.Result<(), Swift.Error>) -> ()) -> () in SelectableEventLoop.o
NIOPosix.SelectableEventLoop.scheduleTask<A>(deadline: NIOCore.NIODeadline, _: () throws -> A) -> NIOCore.Scheduled<A> in SelectableEventLoop.o
NIOPosix.SelectableEventLoop.execute(() -> ()) -> () in SelectableEventLoop.o
closure #2 (Swift.Result<(), Swift.Error>) -> () in doClose #1 () -> () in NIOPosix.SelectableEventLoop.initiateClose(queue: __C.OS_dispatch_queue, completionHandler: (Swift.Result<(), Swift.Error>) -> ()) -> () in SelectableEventLoop.o
generic specialization <NIOPosix.ServerSocket> of NIOPosix.BaseSocketChannel.close0(error: Swift.Error, mode: NIOCore.CloseMode, promise: NIOCore.EventLoopPromise<()>?) -> () in SocketChannel.o
generic specialization <NIOPosix.Socket> of NIOPosix.BaseSocketChannel.close0(error: Swift.Error, mode: NIOCore.CloseMode, promise: NIOCore.EventLoopPromise<()>?) -> () in SocketChannel.o
...
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
About this issue
- Original URL
- State: open
- Created 2 years ago
- Reactions: 2
- Comments: 27
Sorry, I’d missed that the
pod lib --lint
output contained a complete compile log.The first failed compile step attempts to link NIOPosix, and the command line invocation is:
This appears to correctly request
NIOConcurrencyHelpers
, but it does not requestCNIOAtomics
. This is unlike what happens in several of the compile steps, which do appropriately request to includeCNIOAtomics
. This is a problem, becauseCNIOAtomics
is ultimately what defines this symbol.Ultimately I am unfamiliar with the compilation mechanism of Cocoapods so it’s not really easy for me to diagnose this, but it appears that the principal issue is that Cocoapods is not linking
CNIOAtomics
appropriately with things that transitively depend on it. My guess, however, is that this is caused by@inlinable
annotations hitting the public API of a different module (that is, we’ve got an@inlinable
attribute inNIOConcurrencyHelpers
that exposes symbols fromCNIOAtomics
) but Cocoapods not appropriately linking the target. This is also probably related to the fact that Cocoapods appears to be producing frameworks, which are presumably dynamically linked, rather than the statically linked melange that SwiftPM produces.I think we’d need someone expert in Cocoapods to be more confident, but my guess is that we probably have to rewrite the podspecs to express the full transitive linkage graph for each pod: that is, we need to tell Cocoapods to link not only every one of the actual module dependencies but also every one of the transitive set to guard against this kind of problem.
Linking cannot be nondeterministic, but build order can affect the outcome. In particular it’s possible to try to link a library that is not present because it hasn’t been built yet.
@steve-ham thanks for putting this together. I cloned your repo and tried to do
pod lib lint --verbose 2> error_log.txt 1> error_log.txt
this is the error I got. error_log.txt error_log.txt