やってみる

アウトプットすべく己を導くためのブログ。その試行錯誤すらたれ流す。

MinGWでHelloWorld(Gtkmm3版)に成功した

ついにGtkmm3のHelloWorldに成功した。 今回は取り急ぎ、事前準備(環境変数)のことだけ。

window

証拠の画像。

前回まで

MinGW環境を新たに構築し、GTKmm3をソースコードからコンパイルした。

今回

今回はコンパイルで生成されたGTKmm3のDLLを使ってHelloWorldしてみた。 しかし、失敗した時と同様のエラーダイアログが発生した。 libstdc++-6.dllの競合が原因だった。環境変数のPathを調整して解決した。

libstdc++-6.dllの競合

これまで苦しめられてきた(1,2)以下のエラーダイアログ。

__gxx_personality_v0

ググってみたら同じ境遇の方がおられる様子。

"g++ libstdc++-6.dll"で検索。

"g++ libstdc++-6.dll rpath"で検索。

どうやらlibstdc++-6.dllの競合によって起こっている場合があるらしい。 以前、考えたとおり。

試してみた

-Wl,-rpath C:/MinGW_GET/bin

-Wl,-rpath C:/MinGW_GET/binを付与してHelloWorldのソースコードコンパイルしてみる。

しかし、exeを実行しても同様のエラーダイアログが表示されて実行できない。

msysから実行する

hello.exeをmsysから起動すると実行できた。

  1. C:\MinGW_GET\msys\1.0\msys.batを実行。
  2. hello.exeコマンドを打って実行。
  3. hello.exeが起動できた。

今まではファイラから直接exeをダブルクリックして実行していてエラーダイアログが出ていた。 でも、msysから実行すればイケるらしい。

なんじゃそりゃ。

原因の予想

おそらく、環境変数のPathの中に、libstdc++-6.dllが配置してあるパスが2つ以上あるのだろう。

今回参照させたいのはC:/MinGW_GET/bin。それ以外のどれかのパスにlibstdc++-6.dllが配置してあるパスがあるはず。 たぶんそいつが参照されてしまうせいで、例のエラーダイアログが出たのだろう。

ようするにGTKmm3をコンパイルした時に使用したlibstdc++-6.dllを参照すれば成功するはず。 でも今はべつのlibstdc++-6.dllを参照してしまっているせいでエラーになっていると予想した。

環境変数の確認

早速、環境変数のPathを確認する。

面倒すぎるが、1つずつ確認するしかない。

libstdc++-6.dllがあるなら。ないなら×。パス自体が存在しないなら

ユーザ環境変数PATH

結果 パス
C:\HaxeToolkit\haxe\
C:\HaxeToolkit\neko
× C:\Program Files\Gtk+\bin
× C:\Documents and Settings\Administrator\Application Data\npm
C:\Documents and Settings\All Users\Application Data\chocolatey\lib\msys2

問題なし。

システム環境変数Path

結果 パス
× C:\Ruby193\bin
× C:\gtkmm\bin
× C:\Program Files\Windows Resource Kits\Tools\
× %SystemRoot%\system32
× %SystemRoot%
× %SystemRoot%\System32\Wbem
× C:\Python27\Scripts
D:\tools\Xml\libxml\libxslt-1.1.26.win32\bin
D:\tools\Xml\libxml\libxml2-2.7.8.win32\bin
D:\tools\Xml\libxml\iconv-1.9.2.win32\bin
D:\tools\Xml\libxml\zlib-1.2.5\bin
D:\tools\Compiler\PortablePython2.7.3.2\App
D:\tools\Server\Node\nvmw
× C:\WINDOWS\system32\WindowsPowerShell\v1.0
× C:\Program Files\Microsoft\Web Platform Installer\
× C:\root\tool\System
× C:\Program Files\Mono-3.2.3\bin
C:\Program Files\GtkSharp\2.12\bin
× c:\Program Files\Microsoft SQL Server\100\Tools\Binn\
× c:\Program Files\Microsoft SQL Server\100\DTS\Binn\
× C:\Python27
× C:\Program Files\Git\cmd
× C:\Program Files\Pandoc\
× C:\Program Files\nodejs\
× C:\Documents and Settings\All Users\Application Data\chocolatey\bin
× C:/MinGW_GET/msys/1.0/bin
× C:/MinGW_GET/msys/1.0/gtk3/bin
× C:/MinGW_GET/msys/1.0/home/m4-1.4.14-1-bin/bin
C:/MinGW_GET/bin

調整

システム環境変数Pathを以下のように調整した。

  • C:/MinGW_GET/binを先頭にした(C:\Program Files\GtkSharp\2.12\binよりも前)

今回のエラーとは関係ないが、GTKmm3のDLL参照パスを追加しておいた。

  • C:/MinGW_GET/msys/1.0/gtkmm3/binを追加

結果的に、以下のようにした。

C:/MinGW_GET/bin;
C:/MinGW_GET/msys/1.0/bin;
C:/MinGW_GET/msys/1.0/gtk3/bin;
C:/MinGW_GET/msys/1.0/gtkmm3/bin;
C:/MinGW_GET/msys/1.0/home/m4-1.4.14-1-bin/bin;
C:\Ruby193\bin;
C:\gtkmm\bin;
C:\Program Files\Windows Resource Kits\Tools\;
%SystemRoot%\system32;
%SystemRoot%;
%SystemRoot%\System32\Wbem;
C:\Python27\Scripts;
D:\tools\Xml\libxml\libxslt-1.1.26.win32\bin;
D:\tools\Xml\libxml\libxml2-2.7.8.win32\bin;
D:\tools\Xml\libxml\iconv-1.9.2.win32\bin;
D:\tools\Xml\libxml\zlib-1.2.5\bin;
D:\tools\Compiler\PortablePython2.7.3.2\App;
D:\tools\Server\Node\nvmw;
C:\WINDOWS\system32\WindowsPowerShell\v1.0;
C:\Program Files\Microsoft\Web Platform Installer\;
C:\root\tool\System;
C:\Program Files\Mono-3.2.3\bin;
C:\Program Files\GtkSharp\2.12\bin;
c:\Program Files\Microsoft SQL Server\100\Tools\Binn\;
c:\Program Files\Microsoft SQL Server\100\DTS\Binn\;
C:\Python27;
C:\Program Files\Git\cmd;
C:\Program Files\Pandoc\;
C:\Program Files\nodejs\;
C:\Documents and Settings\All Users\Application Data\chocolatey\bin;

競合を発見した

C:\Program Files\GtkSharp\2.12\bin;にあった。 だいぶ昔、GtkSharpをインストールした記憶があるような無いような…。

汚染されすぎな環境変数

ほかにも、昔インストールしただろうけど記憶にないものが多数ある。 パスが存在しないものまである。

優先順位

Pathに書く順序を変えた。C:/MinGW_GET/binを先頭にし、C:\Program Files\GtkSharp\2.12\binよりも前にした。 その後、exeをダブルクリックで実行すると、実行できた!

どうやら先頭のパスが優先されるらしい。

GtkSharp

GtkSharpはインストールしたことすら忘れていた。 使っていないから削除してもいいのだが、使うかも知れないので念のためとっておく。 ただ、もしかするとGtkSharpのほうで不都合が出るかもしれない。

異なるMinGWのバージョンは共存できない?

異なるMinGWのバージョンは共存できないのだろうか。

MinGWのファイル自体は配置できる。 でも、異なるMinGWのバージョンでコンパイルしたexeは、そのバージョンのlibstdc++-6.dllファイルを必要とするらしい。

exeファイル実行時に困る。

exeは特定バージョンのlibstdc++-6.dllに依存する

MinGWコンパイルしてできたexeファイルは、libstdc++-6.dllに依存する。 しかもlibstdc++-6.dllは、MinGWのバージョンによって異なる。 よって、exeごとに適切なバージョンのlibstdc++-6.dllを参照させてやらねば実行時にエラーダイアログが出る。

今回の場合を考えてみる

ファイラからダブルクリックで実行すると失敗したのは、環境変数のPathにあったlibstdc++-6.dllが、exeが必要とするバージョンのlibstdc++-6.dllと違ったからだろう。

msysから実行すると起動できたのは、そのmsysが参照するlibstdc++-6.dllが、exeが必要とするバージョンのlibstdc++-6.dllと一致したからだろう。

今、環境変数のPathにあるMinGWのバージョンは5.3.0。 だからファイラからダブルクリックでexeを実行したとき、5.3.0のlibstdc++-6.dllを参照する。 ファイラからダブルクリックで実行したときは、5.3.0でコンパイルされたexeでないと、例のようなエラーダイアログが出て実行できないかもしれない。ようするにバージョンの差異による問題が生じうる。

たとえば、MinGW4.6.2でコンパイルしたexeを実行するときは、4.6.2のlibstdc++-6.dllを参照すべき。 そのためには、MinGW4.6.2と一緒にインストールしたmsysから、exeを呼び出して実行すればいいらしい。 ファイラからダブルクリックで実行したら、環境変数のPathに通した5.3.0のlibstdc++-6.dllを参照してしまう。

複雑な依存関係

MinGWコンパイルしたexeの依存関係…なんて面倒なんだ。 絶対こんなこと忘れる。 依存関係に翻弄されるのは嫌だ。勘弁してくれ。よしなにやってくれ。

実行時は何も考えず、ダブルクリックしたら起動するようにしてくれ。 あのエラーダイアログから、こんな背後やら事実関係を推測する過程がとても大変で面倒。

おわり

とにかく、今はMinGW5.3.0だけでいい。 これでGTKmm3開発環境が整った。

次回はソースコードをアップできるか。 その前に、環境変数の調整の仕方をメモっておくか。