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

Pyinstaller v6でビルドすると、macOS版エディタがエラーになる #1022

Closed
Hiroshiba opened this issue Jan 21, 2024 · 9 comments
Labels

Comments

@Hiroshiba
Copy link
Member

Hiroshiba commented Jan 21, 2024

不具合の内容

題のとおりです。0.15.0のビルドで発生しました。

現象・ログ

0.15.0のmacエディタが動かない

# ログ見るためにエンジンを直接起動
$ /Applications/VOICEVOX.app/Contents/MacOS/run
[10649] Error loading Python lib '/Applications/VOICEVOX.app/Contents/Frameworks/Python': dlopen: dlopen(/Applications/VOICEVOX.app/Contents/Frameworks/Python, 0x000A): tried: '/Applications/VOICEVOX.app/Contents/Frameworks/Python' (no such file), '/System/Volumes/Preboot/Cryptexes/OS/Applications/VOICEVOX.app/Contents/Frameworks/Python' (no such file), '/Applications/VOICEVOX.app/Contents/Frameworks/Python' (no such file)

たしかにpython.frameworkがなさそう

$ ls /Applications/VOICEVOX.app/Contents/Frameworks/
Electron Framework.framework/   ReactiveObjC.framework/         VOICEVOX Helper (GPU).app/      VOICEVOX Helper (Renderer).app/
Mantle.framework/               Squirrel.framework/             VOICEVOX Helper (Plugin).app/   VOICEVOX Helper.app/

かわりに/Applications/VOICEVOX.app/Contents/MacOS/engine_internal/にありました。

でもまだ問題がありそう

再現手順

0.15.0のmac版エディタを起動

その他

とりあえずまとめるためのissueです。

ref: https://discord.com/channels/879570910208733277/893889888208977960/1198352832311599305
ref: #857

@Hiroshiba
Copy link
Member Author

こちらのPRで一旦問題を迂回する予定です。

@Hiroshiba
Copy link
Member Author

Hiroshiba commented Jan 21, 2024

@yamachu さんがDiscordに貼ってくださったこちらを見る感じ、仮にパス周りの問題を解決しても署名周りの問題がありそう・・・?

(追記)mac版は署名してないので関係ないかも

@Hiroshiba
Copy link
Member Author

@PickledChair さんのDiscordでの会話を引用させていただきます!
https://discord.com/channels/879570910208733277/893889888208977960/1198542083015835648


@PickledChair
エンジン単体なら期待通り動くのに、App bundleにすると動かなくなるという点で、奇妙な動作ですね……手元でも動かして調べてみたら、VOICEVOX.app の中に含まれているエンジン関連のファイルを外に出して動かすと、普通にエンジンが動きます。なので、v6のPyInstallerが出力した実行ファイルは、起動するとまず自分が App bundle内にあるのかどうかを調べて、App bundle内ならContents/Frameworks以下のPython関連ファイルを、そうでなければengine_internal以下のPython関連ファイルを見にいくようです。

これを踏まえて、engine_internal以下のファイルを全部Contents/Frameworks直下に移すと、エンジンが動くようになりました


@Hiroshiba
お~なるほどです!!!
エンジンのリビルドが不要になるからそちらの方が早いかもですね。ちょっと状況把握します
ここ変えるだけで動くかもって感じなのか~
https://github.com/VOICEVOX/voicevox/blob/8d82be87de841e71f3a23b932118c4b9deb2c766/.github/workflows/build.yml#L284-L288


@PickledChair
そうですね、engine_internal以下のファイルはMacOSディレクトリではなくFrameworksディレクトリに持ってく感じです

@PickledChair
Copy link
Member

PickledChair commented Jan 21, 2024

@Hiroshiba

Discord のやり取りの引用ありがとうございます!

ここ変えるだけで動くかもって感じなのか~
https://github.com/VOICEVOX/voicevox/blob/8d82be87de841e71f3a23b932118c4b9deb2c766/.github/workflows/build.yml#L284-L288

実際に以下の変更を適用してビルドを回してみました:

https://github.com/PickledChair/voicevox/blob/fix/problem-with-pyinstaller-v6/.github/workflows/build.yml#L284-L290

ビルド結果 (dmg / zip) を動かしてみた感じでは、実際に動作するようになりました(エディタのバージョン判定の関係で config.json を消したりする必要があるかもしれませんが)。

ただし、Discord でもおっしゃっていた通りワークアラウンド感が強いので、根本解決かというとちょっと微妙というのは同感です(PyInstaller のドキュメントの「Frameworks ディレクトリは空」という記述と矛盾している感じもありますし、PyInstaller のバグの可能性は大いにあります)。 #1022 (comment) の通り、今回は revert で対応というのが堅実だと思いました。

@Hiroshiba
Copy link
Member Author

Hiroshiba commented Jan 21, 2024

@PickledChair 緊急の調査本当に助かりました、ありがとうございました!!

PyInstaller のドキュメントの「Frameworks ディレクトリは空」という記述と矛盾している感じもありますし

こちらに関しては、pyinstallerを.appにするビルドをすればそうなる、ということなのかもと思いました!
ただ結局、なぜContents/MacOSにrunがあるのにContents/Frameworkを探しに行くのかは謎なのですが・・・。

ということでPyinstallerのコードをちょっとだけ探ったのですが、近そうな内容の理由が書いてました。MacOSは署名が必要で~みたいな感じっぽいです。
https://github.com/pyinstaller/pyinstaller/blob/225c0ad56db0ab94b34250c860f408c04019604b/PyInstaller/building/osx.py#L153-L305
(ChatGPTで和訳してみました https://chat.openai.com/share/09f5ea99-0aff-4a55-93d9-3f1b9a7d6a31

署名周りも考慮した良い方法は、たぶんpyinstallerで.appを作るようにビルドし、出来上がったものをContents以下のディレクトリにそれぞれコピーする感じかなと思いました。
けどまあ大変なので、 @PickledChair さんの方法もありなのかなと思いました!
より正確にするなら、*.frameworkFrameworksに、それ以外はResourcesに移動・・・?

あるいは、今まで通りengine関連のファイルを全部rootに展開する(engine_internalディレクトリをやめる)ようにして、↓のinternal_dirを使わずroot_dirを使うようにする手もあるかもとか思いました。

def internal_root() -> Path:
"""
コンパイル時に収集された実行ファイル内部用のルートディレクトリを返す。
開発環境ではリポジトリのルートディレクトリを返す。
"""
root_dir = Path(__file__).parents[2]
return root_dir.resolve(strict=True)

このあたりはたぶん @sabonerune さんが土地勘あると思うので、直感どうかお聞きしたいです。
(エンジン関連のファイルがべちゃっと展開されても、エディタ側でrevertしたエンジンディレクトリを分ける方針が進んだら解決するので、まあ分けなくても良いかもとは思ってます。将来的に仕様が変わらなそうな方を進むと良さそう?)

@sabonerune
Copy link
Contributor

engine_internalディレクトリをやめる場合はビルド時に渡しているengine_internalを空文字にすればいいはずです。

contents_directory="engine_internal",

その場合、internal_dirroot_dirと同じ場所を返すようになるだけなので必ずしもinternal_dirを廃止する必要はないと思います。

@Hiroshiba
Copy link
Member Author

Hiroshiba commented Jan 21, 2024

@sabonerune たしかにです!!

contents_directoryに入れずに全部ぶちまけてMacOSに突っ込むのが良い気がしてきました。
Contents/Framewoksに入れるのは将来pyinstallerの仕様が変わるかもだけど、run.exeのある場所にぶちまける方法はv5/v6どちらも有効なので一旦メンテナンス性が高そう)

もう1点ちょっと確認したいことが 🙇
たしかlinux環境でキーボードが使えなくなる?みたいなエディタ側の不具合があったと思うのですが、あれってrun.exeと同階層にエンジン関連ファイルが大量に置かれていても、エディタ側でvv-engineディレクトリに突っ込むようにすれば解決される、という認識であってそうでしょうか 👀

となるとまあ、v5のときの仕様に戻しちゃうのが良いのかな~とか思ってます。

@sabonerune
Copy link
Contributor

Linux環境でキーボードが効かなくなっていたのはvv-engineディレクトリにエンジンを移動すれば解決するはずです。
確かエンジン由来の共有ライブラリをエディタが誤って読み込んでいたことが原因のはずなので…

@Hiroshiba
Copy link
Member Author

Hiroshiba commented Jan 22, 2024

@sabonerune ありがとうございます!!

最終的な判断のメモです!
Pyinstallerをv6にバージョンアップする場合でも、とりあえずrun.exeと同じディレクトリにいろんなファイルが入っても良い形(contents_directoryを利用しない形)が良いのかなと思いました!

もしMac版でも署名するようになった場合はおそらくこの辺りをどうするか考える必要が出てくるかもしれません。
またrun.exe以外のファイルが大量に散乱しているのはあまり良くないことだとも思います。
contents_directoryを使いつつ、エディター側(.app下)でも問題がなさそうな形があればそれも良いのかなと思います。
(Frameworks下に全部突っ込むのはあまりよろしくなさそうだけど、Resource下に突っ込むのはまあまあ問題なさそう、みたいな。)

皆様ありがとうございました!!

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

No branches or pull requests

3 participants