Siv3D | 実行ファイルのサイズを小さくする

2021/12/01に公開

これは Siv3D Advent Calendar 2021 の参加記事です。

Q: Siv3D で、次のような簡単なプログラムをビルドしてみたら、実行ファイルのサイズが 47 MB になりました。大きすぎませんか?

# include <Siv3D.hpp> // OpenSiv3D v0.6.3

void Main()
{
	while (System::Update())
	{
		Circle{ Cursor::Pos(), 100 }.draw();
	}
}

A: これには理由があり、ちょっとした手順を踏むことでサイズをもっと小さくすることができます。

1. Siv3D の実行ファイルに埋め込まれるファイル

Windows 版や macOS 版、Web 版で Siv3D のプログラムをビルドしたとき、生成される実行ファイルには App/engine/ フォルダ(v0.6.3 では約 35MB)のほぼ全てのファイルが埋め込まれます。これは、Siv3D がインストールされていないパソコンでアプリケーションを実行したときにも、Siv3D のフォントや絵文字、楽器の音の生成、シェーダプログラムを使えるようにするためです。

このうち、一部のファイルは、プログラムで特定の機能を利用しない場合に限り、埋め込みをしないことを選択できます。Windows 版では Visual Studio のソリューションエクスプローラー から App/Resource.rc を「コードの表示」で開き、該当ファイルを削除またはコメントアウトすることで、macOS / Linux / Web ではプロジェクトの App/engine/ フォルダから該当ファイルを削除することで埋め込みをキャンセルできます。

削除は慎重に行う必要があります。本来必要なファイルを削除してしまった場合、ユーザがアプリを実行した際に文字が表示されない、音声が再生されないなどのトラブルにつながります。

この記事では、どのファイルを選択すればよいかのガイドラインを示します。記事最後の「5. 削除したはずなのに問題なく使えるように見える現象に注意」も忘れずにチェックしましょう。

2. ファイル埋め込みキャンセルのガイドライン

Typeface::Thin を使っていない

engine/font/mplus/mplus-1p-thin.ttf.zstdcmp を削除できます。

Typeface::Light を使っていない

engine/font/mplus/mplus-1p-light.ttf.zstdcmp を削除できます。

Typeface::Regular を使っていない

ただし、Font のコンストラクタでフォントの種類を選択していない場合には暗黙的に Typeface::Regular が使われているので注意が必要です。

const Font font{ 40 }; // Typeface::Regular
const Font font2{ FontMethod::MSDF, 48 }; // Typeface::Regular

使用していない場合、engine/font/mplus/mplus-1p-regular.ttf.zstdcmp を削除できます。

なお、PrintPutText, SimpleGUI で使われているフォントは Typeface::CJK_Regular_JP なので、Typeface::Regular とは無関係です。

Typeface::Medium を使っていない

engine/font/mplus/mplus-1p-medium.ttf.zstdcmp を削除できます。

Typeface::Bold を使っていない

engine/font/mplus/mplus-1p-bold.ttf.zstdcmp を削除できます。

Typeface::Heavy を使っていない

engine/font/mplus/mplus-1p-heavy.ttf.zstdcmp を削除できます。

Typeface::Black を使っていない

engine/font/mplus/mplus-1p-black.ttf.zstdcmp を削除できます。

カラー絵文字を使っていない

Typeface::ColorEmojiEmoji, _emoji をプログラムで使っていない場合、engine/font/noto-emoji/NotoColorEmoji.ttf.zstdcmp を削除できます。

モノクロ絵文字を使っていない

Typeface::MonochromeEmoji を使わず、Print で絵文字(🐈や🚀など)を表示せず、トランプ描画機能 も使っていない場合、engine/font/noto-emoji/NotoEmoji-Regular.ttf.zstdcmp を削除できます。このファイルを削除できるのは v0.6.3 以降です。

Font Awesome の Brands アイコンを使っていない

Typeface::Icon_Awesome_Brand を使わず、Icon_iconFont Awesome の Brands アイコン を使っていない場合、engine/font/fontawesome/fontawesome-brands.otf.zstdcmp を削除できます。

Font Asesome の Solid アイコンを使っていない

Typeface::Icon_Awesome_Solid を使わず、Icon_icon や SimpleGUI の表示テキストで Font Awesome の Solid アイコン を使っていない場合、engine/font/fontawesome/fontawesome-solid.otf.zstdcmp を削除できます。

Material Design Icons を使っていない

Typeface::Icon_Awesome_Solid を使わず、Icon_icon や SimpleGUI の表示テキストで Material Design Icons を使っていない場合、engine/font/materialdesignicons/materialdesignicons-webfont.ttf.zstdcmp を削除できます。

プログラムによる楽器の音生成を使っていない

GMInstrument を使わず、MIDI ファイル(拡張子 .mid)の読み込みや MIDI ファイルからの波形のレンダリングもしていない場合、engine/soundfont/GMGSx.sf2.zstdcmp を削除できます。

3. フォントをさらに削除する

engine/font/noto-emoji/noto-cjk/NotoSansCJK-Regular.ttc.zstdcmp の削除は 2 通りの方法があります。

(A) Windows 版または Web 版

Typeface::CJK_Regular_JP 以外の Typeface::CJK_Regular_* を使っていないか、すべての Typeface::CJK_Regular_* が自動的に Typeface::CJK_Regular_JP にフォールバックしても問題ないのであれば、engine/font/noto-emoji/noto-cjk/NotoSansCJK-Regular.ttc.zstdcmp を削除して、代わりに engine/font/noto-cjk/NotoSansJP-Regular.otf.zstdcmp を使うことができます。

(B) 全プラットフォーム

Typeface::CJK_Regular_* を ASCII 文字の表示にしか使っていない場合、engine/font/noto-emoji/noto-cjk/NotoSansCJK-Regular.ttc.zstdcmp を削除できます。このとき、すべての Typeface::CJK_Regular_* は自動的に engine/font/min/siv3d-min.woff にフォールバックします。このフォントは Typeface::CJK_Regular_JP のうち ASCII 文字だけを残したサブセットフォントです。PrintSimpleGUITypeface::CJK_Regular_JP を使っていて、フォールバックが発生します。

4. 実際に削除してみてファイルサイズがどれだけ減るか調べる

ここまで説明したガイドラインに沿うと、冒頭のプログラムでは以下のファイルを削除しても問題ないことがわかりました。

  • engine/font/mplus/mplus-1p-thin.ttf.zstdcmp
  • engine/font/mplus/mplus-1p-light.ttf.zstdcmp
  • engine/font/mplus/mplus-1p-regular.ttf.zstdcmp
  • engine/font/mplus/mplus-1p-medium.ttf.zstdcmp
  • engine/font/mplus/mplus-1p-bold.ttf.zstdcmp
  • engine/font/mplus/mplus-1p-heavy.ttf.zstdcmp
  • engine/font/mplus/mplus-1p-black.ttf.zstdcmp
  • engine/font/noto-cjk/NotoSansCJK-Regular.ttc.zstdcmp
  • engine/font/noto-emoji/NotoColorEmoji.ttf.zstdcmp
  • engine/font/noto-emoji/NotoEmoji-Regular.ttf.zstdcmp
  • engine/font/fontawesome/fontawesome-brands.otf.zstdcmp
  • engine/font/fontawesome/fontawesome-solid.otf.zstdcmp
  • engine/font/materialdesignicons/materialdesignicons-webfont.ttf.zstdcmp
  • engine/soundfont/GMGSx.sf2.zstdcmp

これらを、1. の手順に沿って削除してからリビルドしてみた結果、47 MB あった実行ファイルは、15 MB になりました。およそ 3 分の 1 です!

5. 削除したはずなのに問題なく使えるように見える現象に注意

Siv3D のアプリケーションは、実行の高速化のために、自身が起動されたとき、自動的に engine ファイルの圧縮展開済みファイルを、実行したパソコンにキャッシュします。例えば engine/font/noto-emoji/NotoColorEmoji.ttf.zstdcmp を同梱している Siv3D アプリ A を実行すると、NotoColorEmoji.ttf がそのパソコンのキャッシュフォルダ(Windows の場合、ユーザ名/AppData/Local/Siv3D/ (隠しフォルダ) )に保存されます。その後、同じパソコンで Siv3D アプリ B を実行すると、そのパソコンに NotoColorEmoji.ttf がキャッシュされていた場合は、そのキャッシュされているファイルをロードします。

このキャッシュの仕組みがあるため、埋め込みファイルを削除したはずなのに、開発 PC ではその削除した機能を正しく使えてしまうという現象が発生します。もちろんそのアプリをキャッシュが存在しない別の PC で起動すると、その機能は使えません。キャッシュが存在しないユーザの環境を再現する場合、自分の開発 PC にある Siv3D キャッシュフォルダの中身を削除して検証する必要があります。

Discussion