代码之家  ›  专栏  ›  技术社区  ›  Lukasz Kujawa

将rxswift链接到命令行工具的正确方法

  •  0
  • Lukasz Kujawa  · 技术社区  · 6 年前

    我正在尝试为命令行工具构建RXSwift,但它比iOS应用程序更难实现。

    我创建了一个新的命令行项目,并用 pod

    $ cat Podfile
    # Podfile
    use_frameworks!
    
    target 'HelloRx' do
        pod 'RxSwift',    '~> 4.0'
    end
    
    
    $ pod --version
    1.5.3
    
    

    XCODE 10.1

    打开工作区(.xcworkspace)后,在不添加任何代码的情况下,项目生成良好,但在运行时崩溃:

    dyld: Library not loaded: @rpath/RxAtomic.framework/Versions/A/RxAtomic
      Referenced from: /Users/luke/Library/Developer/Xcode/DerivedData/HelloRx-ftbkqquhoytidfesyxazbaovndbu/Build/Products/Debug/HelloRx
      Reason: image not found
    

    动态依赖项对二进制文件不可见。

    $ otool -l HelloRx | grep -A 2 RPATH | grep path
             path @executable_path/../Frameworks (offset 12)
             path @loader_path/Frameworks (offset 12)
             path @executable_path/../Frameworks (offset 12)
             path @loader_path/Frameworks (offset 12)
    

    Xcode假定二进制文件可以在 Frameworks 相对于二进制文件的目录。不幸的是,如果我查看构建目录,没有 框架 dir,因此出错。

    $ ls
    HelloRx         Pods_HelloRx.framework  RxCocoa
    HelloRx.swiftmodule RxAtomic        RxSwift
    
    $ ls ..
    Debug
    

    为了使它更加混乱,所有框架都被复制到自己的框架中。 Rx* 直接,而不是一个全局 框架 迪尔

    我可以通过在“构建设置”>>“运行路径搜索路径”中添加更多路径来解决这一问题。

    '@executable_path/RxAtomic'
    '@executable_path/RxSwift'
    

    我做了这个技巧,但二进制仍然崩溃。

    dyld: Library not loaded: @rpath/libswiftAppKit.dylib
      Referenced from: /Users/luke/Library/Developer/Xcode/DerivedData/HelloRx-ftbkqquhoytidfesyxazbaovndbu/Build/Products/Debug/RxSwift/RxSwift.framework/Versions/A/RxSwift
      Reason: image not found
    
    

    现在是RXSwift失踪了 libswiftAppKit.dylib .

    这可以通过添加另一个运行路径来“修复”。

    '/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/macosx'
    

    这最终会停止崩溃,但我的应用程序会发出许多警告:

    objc[64025]: Class _TtCE6AppKitVSo17NSAnimationEffectP33_9E6F1C1DB126EBCC5B18B8BAC8A387CC26_CompletionHandlerDelegate is implemented in both /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/macosx/libswiftAppKit.dylib (0x101360b98) and /Users/luke/Library/Developer/Xcode/DerivedData/HelloRx-ftbkqquhoytidfesyxazbaovndbu/Build/Products/Debug/HelloRx (0x10059a250). One of the two will be used. Which one is undefined.
    objc[64025]: Class _TtC8Dispatch16DispatchWorkItem is implemented in both /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/macosx/libswiftDispatch.dylib (0x101a7c6d0) and /Users/luke/Library/Developer/Xcode/DerivedData/HelloRx-ftbkqquhoytidfesyxazbaovndbu/Build/Products/Debug/HelloRx (0x10059bd28). One of the two will be used. Which one is undefined.
    objc[64025]: Class _TtC10FoundationP33_45BFD3D387700B862E3A7353B97EF7ED20_CharacterSetStorage is implemented in both /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/macosx/libswiftFoundation.dylib (0x101c34f00) and /Users/luke/Library/Developer/Xcode/DerivedData/HelloRx-ftbkqquhoytidfesyxazbaovndbu/Build/Products/Debug/HelloRx (0x10059d5e8). One of the two will be used. Which one is undefined.
    objc[64025]: Class _TtC10Foundation12_DataStorage is implemented in both /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/macosx/libswiftFoundation.dylib (0x101c34fa8) and /Users/luke/Library/Developer/Xcode/DerivedData/HelloRx-ftbkqquhoytidfesyxazbaovndbu/Build/Products/Debug/HelloRx (0x10059d690). One of the two will be used. Which one is undefined.
    ...
    

    我可以忍受警告,但这显然不是正确的解决方案。这让我想,解决这个问题的正确方法是什么?

    (我是Xcode和Swift的新手,所以我可能在做一些疯狂的事情)

    1 回复  |  直到 6 年前
        1
  •  1
  •   Fabio Felici    6 年前

    一个快速的方法是将所有pods框架作为静态libs。

    1. 在项目导航器上选择PODS项目
    2. 在所有pods目标之上选择主pods项目
    3. 转到生成设置并更改 Mach-O Type Static Library . 这将改变所有的豆荚 MACH-O型 作为 静态库 . (每次跑步 pod install 这将被更改回原来的版本,因此您可能需要再次执行此操作)
    4. 干净的

    此方法的优点是输出将是单个可执行文件。

    如果要使用动态框架,请遵循本教程: https://medium.com/livefront/how-to-add-a-dynamic-swift-framework-to-a-command-line-tool-bab6426d6c31 . 通过使用第二种方法,您的输出将不仅仅是一个可执行文件,而且还必须提供所有动态框架。

    推荐文章