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
Posted at 2017年12月17日 19:36:33
email.png