如何在没有 Xcode 的情况下 link CocoaPods 库(integrate_targets false)

How to link CocoaPods library without Xcode (integrate_targets false)

我有一个没有 Xcode 的 swift 项目。我想使用 CocoaPods 中的一个库。鉴于以下 Podfile

platform :osx, '10.11'
install! 'cocoapods', :integrate_targets => false
target 'Foo' do
  pod "PlainPing"
end
pre_install do |installer|
  installer.analysis_result.specifications.each do |s|
    s.swift_version = '4.2' unless s.swift_version
  end
end

我可以轻松地将库构建到 .a.swiftmodule 文件中:

pod install
cd Pods
xcodebuild

但是使用 swiftc 的编译库似乎很棘手,我无法猜测正确的搜索路径拼写或 google 它们。我的最佳选择:

swiftc -I ./build/Release/PlainPing -L ./build/Release/PlainPing -lPlainPing main.swift 

失败

main.swift:2:8: error: cannot load underlying module for 'PlainPing'

似乎 -L 库搜索路径有效,但 swiftc 缺少实际使用 .a 库文件的内容。

CocoaPod手动编译版本

要编译包含 Swift 和 Objective-C 代码的 CocoaPods 库,请执行以下操作:

  1. 复制你的main.swiftPods/PlainPing/Pod/Classes
  2. 编译PlainPingObjective-C代码
  3. 发出PlainPing.swiftmodule
  4. 编译PlainPing发射对象
  5. 编译应用包括发出的对象和main.swift

脚本(复制并粘贴到终端):

 echo "1. Compiling Objective-C code" && \
 clang \
      -c \
      -fmodules \
      -fobjc-weak \
      -arch x86_64 \
      -w \
      SimplePing.m \
 && \
 echo "2. Emitting PlainPing.swiftmodule" && \
 swiftc \
      -emit-module \
      -module-name PlainPing \
      -import-objc-header SimplePing.h \
      PlainPing.swift SimplePingAdapter.swift \
 && \
 echo "3. Compiling PlainPing" && \
 swiftc \
      -emit-object \
      -module-name PlainPing \
      -import-objc-header SimplePing.h \
      PlainPing.swift SimplePingAdapter.swift \
 && \
 echo "4. Compiling app" && \
 swiftc \
      -o app \
      -I . \
      -L . \
      *.o main.swift \
 && \
 echo "5. Running app" && \
 ./app

使用 xcodebuild 的版本

确保在Podfile的第二行添加use_frameworks!

脚本(复制并粘贴到终端):

echo "Compiling Pods" && \
pod install && \
xcodebuild -project Pods/Pods.xcodeproj \
&& \
echo "Compiling App" && \
dir="build/Pods.build/Release/PlainPing.build/Objects-normal/x86_64" && \
swiftc \
  -o app \
  -L "$dir" \
  -I "$dir" \
  main.swift \
  $(find $dir -name '*.o' -exec echo -n '{} ' \;) \
&& \
echo "Running App" && \
./app

样本main.swift

import Foundation
import PlainPing

PlainPing.ping("www.apple.com", withTimeout: 1.0, completionBlock: { (timeElapsed:Double?, error:Error?) in
    if let latency = timeElapsed {
        print("latency (ms): \(latency)")
    }

    if let error = error {
        print("error: \(error.localizedDescription)")
    }
})

RunLoop.main.run()