2017年12月17日

wxWidgets で作成した Windows アプリを Wine で動かす

 wxWidgets の環境整備第3弾。Wine ってどうなんだろうと前から思っていた。エミュレータを使わずに Windows アプリを Mac 上で走らせるものだが、X Window が必要なのが面倒。とおもっていたら、EasyWine というのを使うと Xquartz を明示的にインストールしなくても Wine が使えるらしい。すばらしい。

 インストールしてみた。demos/forty フォルダを Finder で見てみると、forty.exe が EasyWine のアイコンになっている(もしそうなっていなかったら、「情報を見る」で EasyWine を使って開くように設定すればいい)。

20171217-1.png

 ところが、ダブルクリックしても立ち上がらない。EasyWine は立ち上がるのだけど、しばらくすると勝手に終了してしまう。ネットで調べても「Wine は『運が良ければ動く』ぐらいに思っておこう」というような情報ばかりで、なかなか手掛かりがない。勝手に終了する前に何かエラーメッセージを出しているはずだ、といろいろ調べて、やっとつかまえた。コマンドラインから、下のようにすればいい。

$ /Applications/EasyWine.app/Contents/Resources/wine/bin/wine forty.exe
err:module:import_dll Library libgcc_s_sjlj-1.dll (which is needed by L"Z:\\....\\demos\\forty\\forty.exe") not found
err:module:import_dll Library libstdc++-6.dll (which is needed by L"Z:\\....\\demos\\forty\\forty.exe") not found
err:module:LdrInitializeThunk Main exe initialization for L"Z:\\....\\demos\\forty\\forty.exe" failed, status c0000135

 libgcc_s_sjlj-1.dlllibstdc++-6.dll は、どちらも MinGW 由来のライブラリである。これに依存してちゃだめですね。どの DLL に依存しているかは、objdump を使えば確認できる。

$ /usr/local/mingw-w32/bin/i686-w64-mingw32-objdump forty.exe -p | grep DLL
 vma:            Hint    Time      Forward  DLL       First
    DLL Name: ADVAPI32.dll
    DLL Name: COMCTL32.DLL
    DLL Name: COMDLG32.DLL
    DLL Name: libgcc_s_sjlj-1.dll
    DLL Name: GDI32.dll
    DLL Name: KERNEL32.dll
    DLL Name: msvcrt.dll
    DLL Name: ole32.dll
    DLL Name: OLEAUT32.dll
    DLL Name: SHELL32.DLL
    DLL Name: libstdc++-6.dll
    DLL Name: USER32.dll
    DLL Name: WINSPOOL.DRV

 Makefile を下のように修正。

srcdir = ../../../demos/forty
top_srcdir = ../../..
LIBS = -lrpcrt4 -loleaut32 -lole32 -luuid -lwinspool -lwinmm -lshell32 -lcomctl32 -lcomdlg32 -ladvapi32 -lwsock32 -lgdi32
LDFLAGS_GUI = -mwindows
LDFLAGS_GUI += -static  #  これを追加
CXX = i686-w64-mingw32-g++
CXXFLAGS = -DWX_PRECOMP -mthreads -O2 -fno-strict-aliasing 

 ビルドし直す。objdump でもう一度確認。確かに libgcc_s_sjlj-1.dlllibstdc++-6.dll がなくなっている。

$ /usr/local/mingw-w32/bin/i686-w64-mingw32-objdump forty.exe -p | grep DLL
 vma:            Hint    Time      Forward  DLL       First
    DLL Name: ADVAPI32.dll
    DLL Name: COMCTL32.DLL
    DLL Name: COMDLG32.DLL
    DLL Name: GDI32.dll
    DLL Name: KERNEL32.dll
    DLL Name: msvcrt.dll
    DLL Name: ole32.dll
    DLL Name: OLEAUT32.dll
    DLL Name: SHELL32.DLL
    DLL Name: USER32.dll
    DLL Name: WINSPOOL.DRV

 forty.exe をダブルクリックして立ち上げる。動きました!

20171217-2.png
タグ:Mac wxWidgets
posted by toshinagata at 19:36| 日記

2017年12月14日

wxWidgets のクロスコンパイル (PowerPC 編)

 wxWidgets の件の続き。PowerPC は対応は諦めようかとおもっていたのだが、古い Xcode から古いコンパイラや SDK を抽出して新しい Xcode にインストールすることができるらしい。これは試してみなくては。

 使うツールはこちら。

 Clone or Download -> Download ZIP でソースをダウンロード・解凍する。xcodelegacy-master というフォルダができるので、そこに cd する。

$ cd path/to/xcodelegacy-master
$ chmod +x Xcodelegacy.sh

 下の URL から Xcode 3.2.6 と 4.6.3 をダウンロード(Apple ID 必要)。

 コンパイラと 10.5 SDK を取り出して Xcode8 にインストール。

$ ./Xcodelegacy.sh -compilers -osx105 buildpackages
$ sudo ./Xcodelegacy.sh -compilers -osx105 install

 以下のメッセージが出る。

*** Warning: /Developer/SDKs should be a symlink to /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs
Check that /Developer exists, and fix /Developer/SDKs with:
 $ sudo ln -sf '/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs' /Developer/SDKs

 このように対応する。指示された通り。

$ sudo mkdir /Developer
$ sudo ln -sf '/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs' /Developer/SDKs

 試しに Molby プロジェクトを開いてビルドしてみた。なんと、あっさり通ってしまった! Release ビルドで "Dsymutil" 関連のエラーが出たが、デバッグシンボルを DWARF with Dsym から DWARF に変更すると通った。これで、しばらくは PowerPC 対応を継続できるな。(実行テストは相当めんどくさいけど…)

タグ:Mac wxWidgets
posted by toshinagata at 21:49| 日記

2017年12月13日

wxWidgets のクロスコンパイル

 wxWidgets の開発環境整備の件。調べてみると、先人がいらっしゃった。すばらしい。「Mac OSX El CapitanにwxWidgetsのwin32クロスコンパイル開発環境構築しました。」(黄昏フリーランスの日記) こちらを参考にして、うちでも開発環境を整備してみる。

 クロスコンパイラはこちらから。

 32 bits targets (2013/05/31), 64 bits targets (2013/06/22) がある。当面は、32 bits でいくことにする。

 展開して /usr/local にインストール。

$ cd path/to/Downloads
$ mkdir mingw-w32; cd mingw-w32
$ tar xvfz ../mingw-w32-bin_i686-darwin_20130531.tar.bz2
$ cd ..
$ sudo mv mingw-w32 /usr/local

 実行できることを確かめる。

$ export PATH=/usr/local/mingw-w32/bin:$PATH
$ i686-w64-mingw32-gcc -v
Using built-in specs.
COLLECT_GCC=/usr/local/mingw-w32/bin/i686-w64-mingw32-gcc
COLLECT_LTO_WRAPPER=/usr/local/mingw-w32/bin/../libexec/gcc/i686-w64-mingw32/4.9.0/lto-wrapper
Target: i686-w64-mingw32
Configured with: ../../../build/gcc/src/configure --target=i686-w64-mingw32 --prefix=/Users/nightstrike/buildbot/mw64/darwin-x86-x86/build/build/root --with-sysroot=/Users/nightstrike/buildbot/mw64/darwin-x86-x86/build/build/root --with-gnu-ld --with-gnu-as --enable-fully-dynamic-string --disable-multilib
Thread model: win32
gcc version 4.9.0 20130531 (experimental) (GCC) 

 結構古いバージョンだけど大丈夫かな。今まで MinGW 上で使っていた gcc も同じぐらいのバージョンだったから、まあいいか。

 ビルドしてみる。

$ cd path/to/wxWidgets-3.0.0
$ mkdir mswx-build; cd mswx-build
$ ../configure --host=i686-w64-mingw32 --disable-shared --enable-monolithic 2>&1 | tee configure.log
checking build system type... x86_64-apple-darwin15.6.0
checking host system type... i686-w64-mingw32
checking for --disable-gui... no
checking for --enable-monolithic... yes
...(snip)...
Configured wxWidgets 3.0.0 for `i686-w64-mingw32'

  Which GUI toolkit should wxWidgets use?                 msw
  Should wxWidgets be compiled into single library?       yes
  Should wxWidgets be linked as a shared library?         no
  Should wxWidgets support Unicode?                       yes (using wchar_t)
  What level of wxWidgets compatibility should be enabled?
                                       wxWidgets 2.6      no
                                       wxWidgets 2.8      yes
  Which libraries should wxWidgets use?
                                       STL                no
                                       jpeg               builtin
                                       png                builtin
                                       regex              builtin
                                       tiff               builtin
                                       zlib               builtin
                                       expat              builtin
                                       libmspack          no
                                       sdl                no
$ make -j 2 2>&1 | tee make.log

 2時間ぐらいかかったが、無事終了。生成したファイルは下の通り。i686-w64-minw32 がついていることに注意。

$ ls lib
libwx_mswu-3.0-i686-w64-mingw32.a	libwxregexu-3.0-i686-w64-mingw32.a
libwx_mswu_gl-3.0-i686-w64-mingw32.a	libwxscintilla-3.0-i686-w64-mingw32.a
libwxexpat-3.0-i686-w64-mingw32.a	libwxtiff-3.0-i686-w64-mingw32.a
libwxjpeg-3.0-i686-w64-mingw32.a	libwxzlib-3.0-i686-w64-mingw32.a
libwxpng-3.0-i686-w64-mingw32.a		wx
$ ls lib/wx/include
i686-w64-mingw32-msw-unicode-static-3.0

 wxWidgets のサンプルをビルドしてみた。ちゃんと動きます。VMWare 上の MinGW/MSYS でビルドしていた時と比べると、make が普通に速いのが本当に快適です。

1213-1.png

 自分のプロジェクトをビルドしてみると、undefined reference to `....' というリンクエラーが大量に出た。Makefile を調べてみると、ar, ranlibi686-w64-mingw32- がついていなくて、Mac のバージョンが呼び出されていた。そりゃエラーになるわな。要注意。

タグ:Mac wxWidgets
posted by toshinagata at 23:35| 日記