※追記 (2024/10/20)
下記の環境でも同様の手順で実施できることを確認
wxWidgets 3.2.6
https://www.wxwidgets.org/news/2024/09/wxwidgets-3.2.6-released/
Mingw-w64 12.0.0 / GCC 14.2.0
https://github.com/niXman/mingw-builds-binaries/releases/tag/14.2.0-rt_v12-rev0
はじめに
ターゲットの環境はWindows10以上
wxWidgets使いの人口が増えればいいなというモチベーション
MinGW-W64のダウンロード・展開
MinGWとはWindowsで動作するバイナリを生成するGCC(移植とは違うらしい)
WindowsにもLinuxにも導入できるが、Windows用ののバイナリを生成するのは変わらない
オフィシャルサイト
「DownLoad」->「MingW-W64-builds」から配布場所(github)に行ける
※「MingW-W64-builds」以外もWindowsで使えるパッケージはあるので、そこは好みで
この中から以下をダウンロードするとよいだろう
「x86_64-13.1.0-release-win32-seh-ucrt-rt_v11-rev1.7z」
古いWindowsでも動くプログラムをコンパイルしたいならこっちを使う
「x86_64-13.1.0-release-win32-seh-msvcrt-rt_v11-rev1.7z」
ucrtとmsvcrtの詳細・違いについては割愛する
ダウンロードして任意の場所に展開する
※今後は「C:\mingw64\bin」のように配置しているものとして説明を続ける
MinGW-w64のパスを通す
ダウンロードして任意の場所に展開したらパスを通す
スタートボタンから「環境変数」と入力して検索すると、
- 「環境変数を編集」(ユーザー環境変数のみ編集可能)
- 「システム環境変数の編集」(制限なし、要管理者権限)
がでてくるので各自で都合が良い方を選ぶ
※「システムのプロパティ」が立ちあがった場合は「環境変数」ボタンがあるのでそれをクリック
「ユーザー環境変数」か「システム環境変数」のPathに展開先の「bin」ディレクトリを指定する
※「ユーザー環境変数」はユーザー固有の設定、「システム環境変数」は全体(全ユーザー)設定
「新規」ボタンからこのように設定を追加する
ちゃんと設定できてればフルパスでなくてもコマンドが実行できるはずだ
wxWidgetsをダウンロード・展開する
wxWidgetsはGUI Toolkitのひとつ・・・と言い切っていいものか
自力で描画はせず、裏でgtkとかqtとかwin32apiとか使うのでGUI Toolkit間の差を吸収するラッパーライブラリのような印象
オフィシャルサイト
メニューの「Downloads」から各種ファイルがダウンロードできるページに遷移するので中段の「Source Code」から「Windows ZIP」または「Windows 7z」を選んでダウンロードする
※「Windows Installer」はわざわざ環境汚したくないので私は選ばない
ダウンロードしたら任意の場所に展開する
私が展開した場所は「C:\wxWidgets\wxWidgets-3.2.2.1」※この配下に「include」ディレクトリ等がある
※今後はここに展開したものとして説明を続ける
wxWidgetsをビルドする
参考:
https://docs.wxwidgets.org/3.2/plat_msw_install.html
※オフィシャルサイトの右ペインから「Quick Links」→「Online Manual」→「User Manual」→「Programming Guides」→「Starting with wxWidgets」→「Installing wxWidgets」さらに中段にある「For native wxMSW port under Microsoft Windows.」のリンクを踏めばWindows環境の手順に行ける
wxWidgetsのライブラリをビルドする
静的ライブラリを作る場合はPower Shellを立ち上げて
cd C:\wxWidgets\wxWidgets-3.2.2.1\build\msw
mingw32-make SHELL=CMD.exe -f makefile.gcc BUILD=release UNICODE=1 SHARED=0 MONOLITHIC=1
動的ライブラリ(dll)を作る場合はPower Shellを立ち上げて
cd C:\wxWidgets\wxWidgets-3.2.2.1\build\msw
mingw32-make SHELL=CMD.exe -f makefile.gcc BUILD=release UNICODE=1 SHARED=1 MONOLITHIC=1
MONOLITHIC=1を指定しているのは、指定しないと細かいファイルがたくさんできるのである程度まとめないから
※オプションの詳細は上記の参考のリンクを参照されたし
ビルドが終わると、
静的ライブラリは「C:\wxWidgets\wxWidgets-3.2.2.1\lib\gcc_lib」に格納される
動的ライブラリは「C:\wxWidgets\wxWidgets-3.2.2.1\lib\gcc_dll」に格納される
※「Visual Studio」とかでビルドすると、「vc_lib」や「vc_dll」などになる
これでwxWidgetsのビルドは完了となる
Hallo worldしてみる
オフィシャルサイトの右ペインの「Quick Links」に「Hello World in wxWidgets」があるのでやってみる
コードを直接転載するのはあれなのでリンク先のコードを「HelloWorld.cpp」で保存したとする
PowerShell上で「HelloWorld.cpp」と同じディレクトリに移動して下記を実行
※下記は静的ライブラリをリンクしている、動的ライブラリをリンクする方法はちょっと忘れた。。。
g++ -O2 -static-libgcc -static-libstdc++ -mthreads -mwindows HelloWorld.cpp -o HelloWorld.exe -I C:\wxWidgets\wxWidgets-3.2.2.1\include -I C:\wxWidgets\wxWidgets-3.2.2.1\lib\gcc_lib\mswu -L C:\wxWidgets\wxWidgets-3.2.2.1\lib\gcc_lib -lwxmsw32u -lwxmsw32u_gl -lwxscintilla -lwxtiff -lwxjpeg -lwxpng -lwxzlib -lwxregexu -lwxexpat -lkernel32 -luser32 -lgdi32 -lcomdlg32 -lwinspool -lwinmm -lshell32 -lshlwapi -lcomctl32 -lole32 -loleaut32 -luuid -lrpcrt4 -ladvapi32 -lversion -lws2_32 -lwininet -loleacc -luxtheme
「HelloWorld.exe」が生成されているはずなので実行してみる
ちゃんと実行できてる
リソースファイル
なくてもコンパイル自体はできるため後回しにしていたが、普通はリソースファイルをリンクする
その最低限の内容は以下の通り
#include "wx/msw/wx.rc"
windresコマンドでリンクできる形式(COFF)に変換
※「wxUSE_DPI_AWARE_MANIFEST=2」はWindowsの高DPIモードに対応させる
windres -i.\resource.rc -o.\resource.o --include-dir C:\wxWidgets\wxWidgets-3.2.2.1\include --define wxUSE_DPI_AWARE_MANIFEST=2
出来上がった「resource.o」を前述のHallo Worldのコンパイルコマンドに含めてやればもっとWindowsっぽい見た目になる
g++ -O2 -static-libgcc -static-libstdc++ -mthreads -mwindows HelloWorld.cpp resource.o -o HelloWorld.exe -I C:\wxWidgets\wxWidgets-3.2.2.1\include -I C:\wxWidgets\wxWidgets-3.2.2.1\lib\gcc_lib\mswu -L C:\wxWidgets\wxWidgets-3.2.2.1\lib\gcc_lib -lwxmsw32u -lwxmsw32u_gl -lwxscintilla -lwxtiff -lwxjpeg -lwxpng -lwxzlib -lwxregexu -lwxexpat -lkernel32 -luser32 -lgdi32 -lcomdlg32 -lwinspool -lwinmm -lshell32 -lshlwapi -lcomctl32 -lole32 -loleaut32 -luuid -lrpcrt4 -ladvapi32 -lversion -lws2_32 -lwininet -loleacc -luxtheme
日本語の扱い
細かい話を置いておくと
ソースをShift-JISで保存して「g++」に「-finput-charset=CP932 -fexec-charset=CP932」をつける
または、ソースをUTF-8で保存して「g++」のオプションに「-fexec-charset=CP932」のどっちか
細かい話
- MinGW-W64はデフォルトだとソースをUTF-8と解釈して実行ファイル上の文字列もUTF-8として出力
- wxWidgets(MSW)は文字列(char*とかstd::string)をShift-JISと解釈
つまりwxWidgets(MSW)の各種関数群にはなんとかShift-JISで文字列を渡さなくてはいけない
具体的には「g++」のオプションを駆使する
- 「-finput-charset=CP932」→入力ファイルをShift-JISと解釈
- 「-fexec-charset=CP932」→実行ファイル上の文字列をShift-JISとして出力
※wxWidgetsライブラリはShift-JISで文字列を受け取ったあと内部的にUnicodeに変換
とってもややこしい
ソースを単にShift-JISで保存するだけではダメか?
MinGW-W64がUTF8 to UTF8なら文字コードの変換は実質的に起きないので、ソースコードをShift-JISで保存するだけでよくないだろうか?(自分も最初はそう思った)
しかし、一部の糞文字(2byte目が0x5c、つまり「\」になってる文字)が化けてしまう
「-finput-charset=CP932 -fexec-charset=CP932」をつけるとMinGW-W64は糞文字も配慮してくれて文字化けしなくなる
たまにこの記事が読みたくなる
https://qiita.com/yumetodo/items/54e1a8230dbf513ea85b
VSCODEでのC/C++拡張の設定
コンパイラのパスに
"C:/mingw64/bin/g++.exe"
インクルードパスに
"C:/wxWidgets/wxWidgets-3.2.2.1/include",
"C:/wxWidgets/wxWidgets-3.2.2.1/lib/gcc_lib/mswu"
を設定する
その他は各自の環境に合わせて設定
{
"configurations": [
{
"name": "Win32",
"includePath": [
"${workspaceFolder}/**",
"C:/wxWidgets/wxWidgets-3.2.2.1/include",
"C:/wxWidgets/wxWidgets-3.2.2.1/lib/gcc_lib/mswu"
],
"defines": [
"_DEBUG",
"UNICODE",
"_UNICODE"
],
"compilerPath": "C:/mingw64/bin/g++.exe",
"cStandard": "gnu17",
"cppStandard": "gnu++20",
"intelliSenseMode": "windows-gcc-x64",
"configurationProvider": "ms-vscode.makefile-tools"
}
],
"version": 4
}
最後に
間違ったこと言ってたらご指摘ください