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

Most upvoted comments

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:

/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang
 -target x86_64-apple-ios10.0-simulator
 -dynamiclib
 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator15.2.sdk
 -L/Users/steve/Library/Developer/Xcode/DerivedData/App-cqtbcyakcqxmvtbzqvlbycstjulk/Build/Products/Release-iphonesimulator/SwiftNIOPosix
 -L/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/iphonesimulator
 -L/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator15.2.sdk/usr/lib/swift
 -F/Users/steve/Library/Developer/Xcode/DerivedData/App-cqtbcyakcqxmvtbzqvlbycstjulk/Build/Products/Release-iphonesimulator/SwiftNIOPosix
 -F/Users/steve/Library/Developer/Xcode/DerivedData/App-cqtbcyakcqxmvtbzqvlbycstjulk/Build/Products/Release-iphonesimulator/CNIOAtomics
 -F/Users/steve/Library/Developer/Xcode/DerivedData/App-cqtbcyakcqxmvtbzqvlbycstjulk/Build/Products/Release-iphonesimulator/CNIODarwin
 -F/Users/steve/Library/Developer/Xcode/DerivedData/App-cqtbcyakcqxmvtbzqvlbycstjulk/Build/Products/Release-iphonesimulator/CNIOLinux
 -F/Users/steve/Library/Developer/Xcode/DerivedData/App-cqtbcyakcqxmvtbzqvlbycstjulk/Build/Products/Release-iphonesimulator/CNIOWindows
 -F/Users/steve/Library/Developer/Xcode/DerivedData/App-cqtbcyakcqxmvtbzqvlbycstjulk/Build/Products/Release-iphonesimulator/SwiftNIOConcurrencyHelpers
 -F/Users/steve/Library/Developer/Xcode/DerivedData/App-cqtbcyakcqxmvtbzqvlbycstjulk/Build/Products/Release-iphonesimulator/SwiftNIOCore
 -F/Users/steve/Library/Developer/Xcode/DerivedData/App-cqtbcyakcqxmvtbzqvlbycstjulk/Build/Products/Release-iphonesimulator/_NIODataStructures
 -filelist /Users/steve/Library/Developer/Xcode/DerivedData/App-cqtbcyakcqxmvtbzqvlbycstjulk/Build/Intermediates.noindex/Pods.build/Release-iphonesimulator/SwiftNIOPosix.build/Objects-normal/x86_64/NIOPosix.LinkFileList
 -install_name @rpath/NIOPosix.framework/NIOPosix
 -Xlinker -rpath
 -Xlinker /usr/lib/swift
 -Xlinker -rpath
 -Xlinker @executable_path/Frameworks
 -Xlinker -rpath
 -Xlinker @loader_path/Frameworks
 -dead_strip
 -Xlinker -object_path_lto
 -Xlinker /Users/steve/Library/Developer/Xcode/DerivedData/App-cqtbcyakcqxmvtbzqvlbycstjulk/Build/Intermediates.noindex/Pods.build/Release-iphonesimulator/SwiftNIOPosix.build/Objects-normal/x86_64/NIOPosix_lto.o
 -Xlinker -objc_abi_version
 -Xlinker 2
 -fobjc-arc
 -fobjc-link-runtime
 -L/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/iphonesimulator
 -L/usr/lib/swift
 -Xlinker -add_ast_path
 -Xlinker /Users/steve/Library/Developer/Xcode/DerivedData/App-cqtbcyakcqxmvtbzqvlbycstjulk/Build/Intermediates.noindex/Pods.build/Release-iphonesimulator/SwiftNIOPosix.build/Objects-normal/x86_64/NIOPosix.swiftmodule
 -framework CNIODarwin
 -framework CNIOLinux
 -framework CNIOWindows
 -framework NIOConcurrencyHelpers
 -framework NIOCore
 -framework _NIODataStructures
 -framework Foundation
 -Xlinker -no_adhoc_codesign
 -compatibility_version 1
 -current_version 1
 -Xlinker -dependency_info
 -Xlinker /Users/steve/Library/Developer/Xcode/DerivedData/App-cqtbcyakcqxmvtbzqvlbycstjulk/Build/Intermediates.noindex/Pods.build/Release-iphonesimulator/SwiftNIOPosix.build/Objects-normal/x86_64/NIOPosix_dependency_info.dat
 -o /Users/steve/Library/Developer/Xcode/DerivedData/App-cqtbcyakcqxmvtbzqvlbycstjulk/Build/Intermediates.noindex/Pods.build/Release-iphonesimulator/SwiftNIOPosix.build/Objects-normal/x86_64/Binary/NIOPosix

This appears to correctly request NIOConcurrencyHelpers, but it does not request CNIOAtomics. This is unlike what happens in several of the compile steps, which do appropriately request to include CNIOAtomics. This is a problem, because CNIOAtomics 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 in NIOConcurrencyHelpers that exposes symbols from CNIOAtomics) 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