「Mac OS 10.14 で wxWidgets 開発(その1)」のつづき。
4. wxWidgets のビルド (Mac OS 10.6 対応)
wxWidgets は 3.0.3 を使う。現時点での最新は 3.1.2 だけど、これには Mac OS 10.7 以上が必要なので、10.6 サポートを切らないのなら 3.0 系列が必須となる。
$ cd path/to/wxWidgets-3.0.3
$ mkdir build-osx; cd build-osx
$ ../configure --with-osx_cocoa --with-macosx-version-min=10.6 --with-macosx-sdk=/Developer/SDKs/MacOSX10.6.sdk --disable-shared --enable-monolithic | tee configure.log
$ (date 2>&1; make -j 4 2>&1; date 2>&1) | tee make.log
本当は --prefix
を指定して make install
までやっておいた方がいいような気もするんだけど、今のところこれでも動いている。あまり行儀のいい使い方ではないかも。
5. wxWidgets のビルド (mingw-w64, クロスコンパイル)
--host
を指定するだけで、クロスコンパイルできる。
# 32 bit 版
$ cd path/to/wxWidgets-3.0.3
$ mkdir build-win32; cd build-win32
$ ../configure --host=i686-w64-mingw32 --disable-shared --enable-monolithic | tee configure.log
$ (date 2>&1; make -j 4 2>&1; date 2>&1) | tee make.log
# 64 bit 版
$ cd path/to/wxWidgets-3.0.3
$ mkdir build-win; cd build-win
$ ../configure --host=x86_64-w64-mingw32 --disable-shared --enable-monolithic | tee configure.log
$ (date 2>&1; make -j 4 2>&1; date 2>&1) | tee make.log
wxWidgets のコンパイルはすごく時間がかかる、というイメージがあったんだけど、実際には5分ぐらいで終わった。クロスコンパイルだと、サンプルをビルドしないからかな。
実はこのままだと、libwinpthread-1.dll
という dll に依存する実行プログラムができてしまう。これは既知の問題で、基本的にはリンカオプションで回避するのだが、たまにどうしてもうまくいかないことがあるので、dll の名前を変えて強制的に静的リンクさせるようにする。(Cf. [MinGW] Link pthread statically [Ubuntu])
$ for i in i686 x86_64; do
cd /usr/local/homebrew/Cellar/mingw-w64/6.0.0_2/toolchain-${i}/${i}-w64-mingw32/lib
for j in libpthread.dll.a libwinpthread.dll.a; do
mv $j _${j}
done
done
6. Xcode のプロジェクトを作る
wxWidgets のサンプルプログラム "Life" をビルドする Xcode プロジェクトを作ってみる。
Xcode で新規プロジェクトを作成する。"Cocoa App" を選択する。
Storyboards, Document-Based, Core Data, Unit TEST, UI Tests は全部オフにしておく。
Info.plist 以外のファイルは不要なので、削除してゴミ箱に入れる。
wxWidgets の "demos" の中にある "Life" のファイルを、"wxLife" フォルダ(どこでもよいが)にコピーする。
ビルドに必要なファイルを Xcode のファイルリストに加える。
ビルド設定を変更する。やり方をすぐ忘れてしまうのでメモ:ファイルリストの一番上のプロジェクト名を選択して、"Build Settings" を選ぶと、その下にビルド設定が表示される。
- Architectures : Base SDK :
Mac OS X 10.6
- Deployment : macOS Deployment Target :
macOS 10.6
- Linking : Other Linker Flags :
-L$(PROJECT_DIR)/../wxWidgets-3.0.3/build-osx/lib -lwx_osx_cocoau-3.0 -lwx_osx_cocoau_gl-3.0 -lwxregexu-3.0 -lwxtiff-3.0 -lwxjpeg-3.0 -lwxpng-3.0 -lz -lpthread -liconv
# wxWidgets-3.0.3 への相対パスが正しくなるように注意。 - Search Paths : Header Search Paths :
$(PROJECT_DIR)/../wxWidgets-3.0.3/include $(PROJECT_DIR)/../wxWidgets-3.0.3/build-osx/lib/wx/include/osx_cocoa-unicode-static-3.0
- Search Paths : Library Search Paths :
$(PROJECT_DIR)/../wxWidgets-3.0.3/build-osx/lib
- Apple Clang - Custom Compiler Flags : Other C Flags :
-D__WXMAC__ -D__WXOSX__ -D__WXOSX_COCOA__
- Apple Clang - Language - C++ : C++ Language Dialect :
GNU++98 [-std=gnu++98]
- Apple Clang - Language - C++ : C++ Standard Library :
libstdc++ (GNU C++ standard)
# C++11, libc++ のままだと Mac OS 10.6 SDK ではビルドできない
"Build Phase" を選び、"Link Binary with Libraries" を開いて、次の5つのフレームワークを加える:Carbon, Cocoa, AudioToolbox, OpenGL, IOKit
。
これでビルドに成功する。おー動くやん。
実はこのサンプルには Mac 上で画面が正しく更新されない不具合があります。life.cpp
の LifeCanvas::DrawChanged()
の終了直前に下の3行を追加する。
#if __WXMAC__
Refresh();
#endif
"Puffer Train" を 1500 世代まで進めたところ。
7. MinGW 用の Makefile を作る
makefile.unx
をコピーして makefile.mingw
とし、次のように修正。
CXX = $(shell wx-config --cxx)
PROGRAM = life.exe # .exe を追加
OBJECTS = life.o dialogs.o game.o reader.o liferc.o # $(PROGRAM).o を life.o とする。liferc.o を追加。
# implementation
.SUFFIXES: .o .cpp
.cpp.o :
$(CXX) -c `wx-config --cxxflags` -o $@ $<
all: $(PROGRAM)
$(PROGRAM): $(OBJECTS)
$(CXX) -o $(PROGRAM) -static-libgcc -static-libstdc++ $(OBJECTS) `wx-config --libs`
# -static-libgcc -static-libstdc++ を追加
# 次の2行を追加
liferc.o : life.rc
`wx-config --rescomp` -o $@ $<
clean:
rm -f *.o $(PROGRAM)
wxLife
のディレクトリに移動する。次のコマンドで life.exe
がビルドできる。PATH
を指定しているのは、wx-config
を呼び出すため。これは、32 bit 版/64 bit 版の wxWidgets をビルドしたディレクトリを指定する。
$ PATH="../../wxWidgets-3.0.0/build-win32:$PATH" make -f makefile.mingw # 32 bit
$ PATH="../../wxWidgets-3.0.0/build-win:$PATH" make -f makefile.mingw # 64 bit
ちゃんと動いております。
8. MinGW 上のビルドを Xcode から実行する
上の Makefile を Xcode から呼び出すには、「ターゲット」を作ればよい。これもすぐ忘れてしまうのでメモ。ターゲットは下の四角のところに表示されているので、ここのポップアップメニューを開いて、"Add Target..." を選ぶ。
ターゲットのタイプは、"Cross Platform" で "External Build System" を選ぶ。
ターゲットの名前を wxLife_win32 などとする。
"Info" で作業ディレクトリとコマンドラインを指定する。コマンドは /usr/bin/env
として、PATH
を設定してから /usr/bin/make
を呼び出すようにする。
- Build Tool:
/usr/bin/env
- Arguments:
PATH=$(PROJECT_DIR)/../wxWidgets-3.0.3/build-win32 /usr/bin/make \-f makefile.mingw
- Directory:
$(PROJECT_DIR)/wxLife
command-B (Build) で 32 bit 版がビルドされます。64 bit 版をビルドするには、もう1つ別のターゲットを作って、PATH
の設定を build-win
にすればよい。