wxWidgets をビルドする 2018年新春編

去る2月に、wxWidgets の開発版である 3.1.1 がリリースされた。前回の開発版である wxWidgets 3.1.0 のリリースからは2年ぐらい経っている。

2016年に wxWidgets をビルドする という記事を書いたが、2年も経つとビルドシステムにも色々と変化が生じている。この記事では、3.1.1リリース直後の現在(2018年3月)における、 wxWidgets の最新の開発版(3.1.1 または Git の master ブランチ)のビルド方法をまとめてみる。

(筆者が記事を書くのにもたついている間に、最新の安定版である 3.0.4 もリリースされたが、この記事はもっぱら最新の開発版を対象とする。)

ビルドシステムに関する変化で最も大きなものは、 CMake のサポートだろう。(wxWidgets を使ったアプリケーションを CMake でビルドすることは昔からできたが、 wxWidgets 自体を CMake でビルドできるようになった)

Git からビルドする場合の注意

要約:README-GIT.md を読め。

wxWidgets は、 zlib や expat など、いくつかのサードパーティーライブラリーに依存している。以前はリポジトリー内にこれらの依存ライブラリーのソースを直接持っていたが、これをやめて git submodule で管理するようになった。そのため、 git clone の際は

$ git clone --recurse-submodules ...

という風に --recurse-submodules オプションをつける必要がある。あるいは、 --recurse-submodules なしで clone してしまった、もしくはすでに clone 済みの場合は

$ git submodule update --init

を実行する必要がある。

Windows の場合は、 include/wx/msw/setup0.hinclude/wx/msw/setup.h にコピーする必要がある。(これは以前と同じ)

リリース版の tarball からビルドする場合

https://github.com/wxWidgets/wxWidgets/releases から最新のリリースに対応する tarball を取ってくる。

$ curl -LO https://github.com/wxWidgets/wxWidgets/releases/download/v3.1.1/wxWidgets-3.1.1.tar.bz2
$ tar xf wxWidgets-3.1.1.tar.bz2
$ cd wxWidgets-3.1.1
$ ./configure --disable-unsafe_conv_in_wxstring --with-cxx=14

CMake でビルドする場合

ルートディレクトリーに CMakeLists.txt が置かれているので、普通にビルドできるはずだ。例えば、

$ mkdir my-build; cd my-build
$ cmake ..

を実行する。すると Makefile 等が生成されるので、 make でビルドできる。

ビルドオプションについては、おなじみの

  • wxBUILD_SHARED=ON|OFF
  • wxBUILD_MONOLITHIC=ON|OFF

などが指定できる。目新しいオプションとしては、

  • wxBUILD_CXX_STANDARD=11|14 : wxWidgets自体のビルドに使用するC++標準を指定する
  • wxUSE_UNSAFE_WXSTRING_CONV=ON|OFF (後述)

がある。ビルドオプションは build/cmake/options.cmake で定義されているようで、気になる方は覗いてみると良いだろう。

こういうオプションを指定したい場合は、 cmake 実行時に例えば

$ cmake .. -DwxUSE_UNSAFE_WXSTRING_CONV=OFF -DwxBUILD_CXX_STANDARD=14

とする。

CMake によるビルドで生成される wx-config スクリプトはまだ不完全 (cf. #18026 (CMake: Complete wx-config creation) – wxWidgets) なようで、 wxWidgets 自体のビルドを CMake でビルドするのは現時点では時期尚早かもしれない。(wxWidgets を使うアプリケーションを CMake でビルドするのは問題ない)

伝統的な方法でビルドする場合

以前の記事を参照してほしい。

増えた configure オプションとしては、

  • --disable-unsafe_conv_in_wxstring (後述)
  • --with-cxx=11|14|17: wxWidgets自身のビルドに使用するC++標準を指定する。 --enable-cxx11 の一般化と言って良いだろうか。

がある。

wxUSE_UNSAFE_WXSTRING_CONV / --disable-unsafe_conv_in_wxstring について

wxWidgets の文字列クラス wxString は const char * や const wchar_t * への変換演算子を提供しているが、 const char * は旧来の(UTF-8とは限らない)マルチバイト文字列への変換なので、UTF-8を扱いたいプログラムでうっかりUTF-8じゃないマルチバイト文字列が紛れ込んでしまう可能性がある。

void foo(const char *s);
wxString wxstr = L"hoge\u3042";
foo(wxstr); // コンパイルが通ってしまう。日本語 Windows なら Shift-JIS!
std::string str = (const char *)wxstr; // 同上

この挙動を変える(const char * への変換演算子を削除する)ことは、非互換な変更となってしまうのでできないが、ユーザーが望めば const char * への変換演算子を削除できるようにしよう、というのがこのオプションである。

UTF-8 な文字列へ明示的に変換したい場合は、 .utf8_str() または .ToStdString(wxConvUTF8) を使うと良い:

void foo(const char *s);
wxString wxstr = L"hoge\u3042";
foo(wxstr.utf8_str()); // 明示的に UTF-8 へ変換 (1)
std::string str = wxstr.ToStdString(wxConvUTF8); // 明示的に UTF-8 へ変換 (2)

特に、 .ToStdString() の方は間に NUL 文字 (\0) が挟まっていても対応できるので、オススメである。これらの方法は wxUSE_UNSAFE_WXSTRING_CONV の有無に関わらず動作する。

参照:wxBlog: Safer S… (wxWidgets の公式ブログ)

公式ブログにも書かれているように、この「const char * への変換演算子を削除する」挙動は、 wxWidgets 自体のビルド時に指定しなくても、アプリケーション側で個別に指定することもできる(ODR? 知らん)。

(歴史の長いC++ライブラリーが文字列クラスを再発明するのは悪しき風習と思われるかもしれない。文句があるならタイムマシンでも使って90年代初頭のC++にstd::stringをねじ込む&Windowsが最初からUTF-8を採用するような歴史改変をしてきてほしい。)

(ちなみに、 .ToStdString(wxConvUTF8) で UTF-8 な std::string に変換できる機能は筆者が実装した(ドヤ): Trac #17461, PR #259


コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です