XCFramework
概要
ソースコードをそのまま配布して良い場合には、SwiftPM での配信が適している バイナリ互換性の心配も不要になる
バイナリフレームワークを配信するためのフォーマット
実機用/Simulator用, iOS/macOS 用, ...
バイナリフレームワークは、バイナリ互換性を維持するため、Package には依存できない
利用するには?
利用側としては、ソースコードベースのライブラリを利用する場合とあまり変わらない
auto complete もきく。I/F の doc も参照できる
作成するには?
1. Xcode 11 から、Build Option に Build Libraries for Distribution という項目が増えたので、有効にしておく
2. xcode archive で Framework のアーカイブをビルドする
バイナリ互換性の問題
Swift コンパイラがモジュールをインポートしようとすると、対象のライブラリを見つけ出し、その中から呼び出し可能な public API のマニフェストを読み込み、使用する
コンパイル済みのモジュールはバイナリフォーマットであり、コンパイラの内部データ構造を含む。この構造は Swift コンパイラのバージョン毎に変わる可能性がある
新しく、Swift Module Interfaces というフォーマットが導入された
モジュールの前 public API をリストアップする
外部依存を含んだ XCFramework
XCFramework にする対象のライブラリが、また別の外部ライブラリに依存していた場合、利用時に問題が生じる。単XCFramework は .swiftinterface を介してモジュールの public な I/F を Swift コンパイラに示すことができるが、単一の XCFramework は単一のモジュールについてのみ I/F を公開できる。そのため、別の外部ライブラリに依存していた場合、その外部ライブラリが Swift コンパイラのビルド時に見つからず、ビルドエラーとなってしまう。
解決策としては、以下がある。
外部ライブラリの I/F を XCFramework の公開 I/F としない場合、@_implementationOnly import を利用することができる
ただし、@_implementationOnly は document 化もされておらずアルファ版
外部ライブラリを、独自の XCFramework などにして別途提供する
提供した XCFramework が他の XCFramework に静的リンクされていたりすると、重複シンボルエラーとなる
ので、動的リンクにする必要がある
推移的な依存関係を考慮すると、この問題を解決することが困難なケースもあり得る
SPM の場合、外部ライブラリの Package.swift 側で動的リンクできるか決められるが、利用側ではリンク方法を現状指定できないので、注意が必要
モジュール定義を別途提供し、それがビルド時に search path 等経由でコンパイラに見つかるようにしておく
implementation-only imports について
Swift Package を XCFramework としてビルドしたい
現状厳しいようだった
サードパーティ製のツールがあるみたい?
参考