Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

iOS向けにXCFrameworkを提供する #477

Closed
HyodaKazuaki opened this issue Apr 27, 2023 · 11 comments · Fixed by #485
Closed

iOS向けにXCFrameworkを提供する #477

HyodaKazuaki opened this issue Apr 27, 2023 · 11 comments · Fixed by #485

Comments

@HyodaKazuaki
Copy link
Contributor

内容

#471 によってiOS向けの動的ライブラリがビルドされるようになりました。
iOSアプリでは、シミュレータと実機、さらにシミュレータのアーキテクチャごとにビルドされた動的ライブラリを使わないとXcodeが警告やエラーを出します。

  • ios-x86_64-simulator
    • Intel Macのシミュレータ用ライブラリ
  • ios-arm64-simulator
    • Apple Silicon Macのシミュレータ用ライブラリ
  • ios-arm64
    • iPhone用ライブラリ(古いデバイスだとarm64以外のアーキテクチャもありますが、古すぎると動作に支障をきたすと考えられるので無視しています)

しかし、これらを適宜切り替えるのは利用者(VOICEVOXコアを使う開発者)にとって手間です。
そこで、XCFrameworkというものを使うことを提案します。

Pros 良くなる点

  • 利用者の負担が軽減される

XCFrameworkでは、各アーキテクチャ向けの動的ライブラリなどをパッケージにして利用することができます。
Xcode側でこのパッケージから当該のアーキテクチャで必要となるライブラリを利用するため、利用者の負担が軽減されます。

Cons 悪くなる点

  • リリース時に必要なビルド作業が増える
  • VOICEVOX COREと別でonnxruntimeもXCFrameworkにする必要がある

実現方法

  1. シミュレータ用ライブラリをfat binaryにする
  • x86_64とarm64向けのシミュレータは別々のままXCFrameworkに変換することはできません(参考 : https://developer.apple.com/forums/thread/711294 )。そこで、lipoコマンドを使って両者を1つのfat binaryに変換します。
  1. ライブラリをXCFrameworkに変換する
  • xcodebuildコマンドにある-create-xcframeworkオプションを使うことで動的ライブラリ自体をXCFrameworkに固めることができます。

ヘッダファイルを含めることができるため、これをXcodeにD&Dするだけで利用できるようになると思われます。
悪くなる点にも書きましたが、VOICEVOX COREと別でonnxruntimeもXCFrameworkにする必要があります。

その他

これだけだとVOICEVOX CoreのAPIしか見えないので、Swiftからは非常に扱いづらいです。
そのため、エンジンのような機能を追加で作る必要がありそうです。
onnxruntimeとVOICEVOX Coreを分離してXCFrameworkとして利用することができるのかは調査できていません。

@Hiroshiba
Copy link
Member

良いですね!!!
こちらもとりあえず今のこのコアのリポジトリで進めてしまって良さそうに思いました!!

通常のビルド後にまとめる処理を実行する感じでしょうか。

@HyodaKazuaki
Copy link
Contributor Author

良いですね!!! こちらもとりあえず今のこのコアのリポジトリで進めてしまって良さそうに思いました!!

通常のビルド後にまとめる処理を実行する感じでしょうか。

おっしゃる通りです。
iOS向けの動的ライブラリをビルドする手順のあとで、lipoコマンドによるシミュレータ向けライブラリの統合処理と、XCFrameworkに変換する処理を加えた上でGitHub Releasesに公開する感じになると思います。

@HyodaKazuaki
Copy link
Contributor Author

HyodaKazuaki commented Apr 27, 2023

voicevox_core.xcframeworkonnxruntime.xcframeworkをそれぞれ作成してテストしてみましたが、voicevox_core.xcframeworkの中にあるlibvoicevox.dylibからlibonnxruntime.dylibが見えないようで実行することができませんでした。

すみません私の不手際で見えなかっただけでした。
シミュレータ上では動作することを確認しました。

@PickledChair
Copy link
Member

PickledChair commented Apr 27, 2023

Issue 作成ありがとうございます!(同趣旨の Issue を作ろうとしていましたがモタモタしていました……)

voicevox_core.xcframeworkonnxruntime.xcframework をそれぞれ作成してテストしてみました
シミュレータ上では動作することを確認しました。

確認ありがとうございます。 voicevox_core.xcframeworkonnxruntime.xcframework をそれぞれ作る方法でいけそうですね!

(1つ興味があるのですが、それぞれの xcframework の名前を、元の binary と同じ名前の libvoicevox_core.xcframeworklibonnxruntime.xcframework にしなくてもうまく行ったということでしょうか? 過去に似たようなことを試した時に、初め -output に指定する名前に lib を付けずに -create-xcframework してみたのですが、うまくいかず、stack overflow の回答にあった "Binary Target name should match the name of the module defined by xcframework." という情報や、Zenn の記事の事例を参考に lib をつけた名前にしたところうまく行った、ということがありました。私は詳しくないので、実は名前に関して別の設定や規則があるのを見つけられなかっただけかもしれません。もしより正しい知識がありましたら教えていただけると嬉しいです。)

これだけだとVOICEVOX CoreのAPIしか見えないので、Swiftからは非常に扱いづらいです。
そのため、エンジンのような機能を追加で作る必要がありそうです。

Swift あるいは Objective-C による Binding を作るとより便利だ、ということですね(例としては、onnxruntime がちょうど Objective-C のインターフェースを提供していますね)。先に Binding を作るか、後で作るかの選択になりそうですね。現在は Android 版とほとんどのコードを共有する形でスマホ版の VOICEVOX を作る方向性になっており、VOICEVOX のプロジェクトとしては Swift や Objective-C の Binding を使わない可能性があります。Binding の作成の優先度については、スマホ版の開発の中で判断していけると良さそうです( VOICEVOX のプロジェクトの中で Binding を使う必要性があれば、優先度も上がりそうです)。

@PickledChair
Copy link
Member

また、もう1つ確認したいことがあるのですが、作成した xcframework にはモデルファイルが含まれない、という認識であっているでしょうか? もし含まれない場合、モデルファイルのみを含んだ zip ファイルも個別に配布すると(特に voicevox_mobile の作業で行うと思われる自動ビルド向けに)便利そうです。既存の別のプラットフォーム向けに配布されている zip からモデルファイルだけ抽出して使うというのも可能ではありますが……。

@HyodaKazuaki
Copy link
Contributor Author

(1つ興味があるのですが、それぞれの xcframework の名前を、元の binary と同じ名前の libvoicevox_core.xcframework と libonnxruntime.xcframework にしなくてもうまく行ったということでしょうか? 過去に似たようなことを試した時に、初め -output に指定する名前に lib を付けずに -create-xcframework してみたのですが、うまくいかず、stack overflow の回答にあった "Binary Target name should match the name of the module defined by xcframework." という情報や、Zenn の記事の事例を参考に lib をつけた名前にしたところうまく行った、ということがありました。私は詳しくないので、実は名前に関して別の設定や規則があるのを見つけられなかっただけかもしれません。もしより正しい知識がありましたら教えていただけると嬉しいです。)

試した限りでは、libvoicevox_core.dyliblibonnxruntime.0.14.0.dylibを内包するXCFrameworkの名前をvoicevox_core.xcframeworkonnxruntime.xcframeworkとしても問題なく動作しました。

Swift あるいは Objective-C による Binding を作るとより便利だ、ということですね(例としては、onnxruntime がちょうど Objective-C のインターフェースを提供していますね)。先に Binding を作るか、後で作るかの選択になりそうですね。現在は Android 版とほとんどのコードを共有する形でスマホ版の VOICEVOX を作る方向性になっており、VOICEVOX のプロジェクトとしては Swift や Objective-C の Binding を使わない可能性があります。Binding の作成の優先度については、スマホ版の開発の中で判断していけると良さそうです( VOICEVOX のプロジェクトの中で Binding を使う必要性があれば、優先度も上がりそうです)。

Bindingについては、そのまま扱うことに抵抗がなければ必要ないかもしれません。
ただ、voicevox_coreを生で扱うとUnsafePointerが頻出しまくるため、Swiftで作ることを考えると好ましく無いと思われます。

また、もう1つ確認したいことがあるのですが、作成した xcframework にはモデルファイルが含まれない、という認識であっているでしょうか?

おっしゃる通りです。
モデルやOpenJTalkの辞書は別で用意してパスを通したり環境変数に与えたりする必要があります。

もし含まれない場合、モデルファイルのみを含んだ zip ファイルも個別に配布すると(特に voicevox_mobile の作業で行うと思われる自動ビルド向けに)便利そうです。既存の別のプラットフォーム向けに配布されている zip からモデルファイルだけ抽出して使うというのも可能ではありますが……。

あったほうが便利だと思います。いかがでしょうか? @Hiroshiba

@Hiroshiba
Copy link
Member

modelディレクトリだけも配るの、たしかにスマホ向けにあった方が便利そうに思いました。
まあでもopenjtalkの辞書も必要だったりと、意外と全部入りのzipの方が便利かもです。
とりあえず全部入りのzipから作る形で進んで、最終的にまた調整を検討するとかどうでしょう?

@HyodaKazuaki
Copy link
Contributor Author

modelディレクトリだけも配るの、たしかにスマホ向けにあった方が便利そうに思いました。 まあでもopenjtalkの辞書も必要だったりと、意外と全部入りのzipの方が便利かもです。 とりあえず全部入りのzipから作る形で進んで、最終的にまた調整を検討するとかどうでしょう?

それで良いと思います。

@AsanoGenki
Copy link

どなたかプロジェクトにVoicevoxのXCFrameworkを追加する方法を教えていただけませんか?XCFrameworkをプロジェクトに追加したことがなくてやり方がわかりません、、

@Hiroshiba
Copy link
Member

@AsanoGenki 答えられるかわかりませんが、とりあえず新しくissueを立てていただければ!

@Hiroshiba
Copy link
Member

issue作成ありがとうございます! せっかくなのでリンク貼っときます 🙏
#785

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants