やってみる

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

GTK+3ライブラリの参照設定ができなかったログ

参照設定をいじくりまわしたが、どうにもできなかったログ。

前回まで

前回GTK+3を使ったコードのコンパイルと実行ができた。

しかし、exeを実行すると、エラーダイアログが出る。

「エントリポイントが見つかりません」

「プロシージャエントリポイント g_list_free_full がダイナミックリンクライブラリ libglib-2.0-0.dll から見つかりませんでした。」

ErrorDialog

そこで、GTK+3のDLLファイルをexeとおなじディレクトリに配置することで解決した。

dialog

でも、プロジェクトごとに同じDLLファイルをいくつも配置したくない。

今回は、ライブラリの参照設定でなんとかできないか模索したけど解決しなかったログ。

参照エラー?

ライブラリの参照パスにDLLディレクトリを指定してやればイケそう。

libglib-2.0-0.dllなどのGTK+3のDLLファイルが存在するディレクトリパスね。

そういうのに該当するのがpkg-config --cflags --libs gtk+-win32-3.0なのではないのか?

そもそもpkg-configって何?

テキトーにコマンドとして打ってみたら、なんか出た。

>pkg-config --cflags --libs gtk+-win32-3.0
-mms-bitfields -IC:/MinGW/msys/1.0/gtk3/include/gtk-3.0 -IC:/MinGW/msys/1.0/gtk3
/include/atk-1.0 -IC:/MinGW/msys/1.0/gtk3/include/cairo -IC:/MinGW/msys/1.0/gtk3
/include/gdk-pixbuf-2.0 -IC:/MinGW/msys/1.0/gtk3/include/glib-2.0 -IC:/MinGW/msy
s/1.0/gtk3/lib/glib-2.0/include -IC:/MinGW/msys/1.0/gtk3/include/pango-1.0 -IC:/
MinGW/msys/1.0/gtk3/include/pixman-1 -IC:/MinGW/msys/1.0/gtk3/include -IC:/MinGW
/msys/1.0/gtk3/include/freetype2 -IC:/MinGW/msys/1.0/gtk3/include/libpng15  -Wl,
-luuid -LC:/MinGW/msys/1.0/gtk3/lib -lgtk-3 -lgdk-3 -limm32 -lshell32 -lole32 -l
atk-1.0 -lgio-2.0 -lpangocairo-1.0 -lgdk_pixbuf-2.0 -lcairo-gobject -lpangoft2-1
.0 -lpangowin32-1.0 -lgdi32 -lfreetype -lfontconfig -lpango-1.0 -lm -lcairo -lgo
bject-2.0 -lglib-2.0 -lintl

"-I:..."って、たぶんインクルードディレクトリを設定する引数だと思う。 VC++コンパイラであるcl.exeもおなじだった気がする。 -IC:...だけど、たぶん同じ意味だろう。

ならば、gcc-IC:C:\MinGW\msys\1.0\gtk3\binを追加すればイケそう。 と思ったが同じエラーが出た。

参照パスを確認

http://arithmeticoverflow.blog.fc2.com/blog-entry-47.html

>gcc -print-search-dirs
インストール: c:\mingw\bin\../lib/gcc/mingw32/4.6.2/
プログラム: =c:/mingw/bin/../libexec/gcc/mingw32/4.6.2/;c:/mingw/bin/../libexec/
gcc/;c:/mingw/bin/../lib/gcc/mingw32/4.6.2/../../../../mingw32/bin/mingw32/4.6.2
/;c:/mingw/bin/../lib/gcc/mingw32/4.6.2/../../../../mingw32/bin/
ライブラリ: =c:/mingw/bin/../lib/gcc/mingw32/4.6.2/;c:/mingw/bin/../lib/gcc/;c:/
mingw/bin/../lib/gcc/mingw32/4.6.2/../../../../mingw32/lib/mingw32/4.6.2/;c:/min
gw/bin/../lib/gcc/mingw32/4.6.2/../../../../mingw32/lib/;c:/mingw/bin/../lib/gcc
/mingw32/4.6.2/../../../mingw32/4.6.2/;c:/mingw/bin/../lib/gcc/mingw32/4.6.2/../
../../;/mingw/lib/mingw32/4.6.2/;/mingw/lib/

>set path
Path=...;C:/MinGW/msys/1.0/gtk3/bin;...

環境変数pathC:/MinGW/msys/1.0/gtk3/bin;がある。 exe実行時に参照してくれないの?

環境変数

LIB, Path(ユーザ環境変数,システム環境変数) にC:\MinGW\msys\1.0\gtk3\binを追記したが、同じエラー。

というか、LIBなんて環境変数、いつできたんだ? なんかそれっぽい名前だったからテキトーに追記して試してみただけ。

pragma

ソースコードに以下を追記しても参照してくれなかった。

#pragma comment(lib, "libatk-1.0-0.dll")
#pragma comment(lib, "libgdk_pixbuf-2.0-0.dll")
#pragma comment(lib, "libgio-2.0-0.dll")
#pragma comment(lib, "libglib-2.0-0.dll")
#pragma comment(lib, "libgobject-2.0-0.dll")
#pragma comment(lib, "libpango-1.0-0.dll")

絶対パスで指定してもダメ。

#pragma comment(lib, "C:/MinGW/msys/1.0/gtk3/bin/libatk-1.0-0.dll")
#pragma comment(lib, "C:/MinGW/msys/1.0/gtk3/bin/libgdk_pixbuf-2.0-0.dll")
#pragma comment(lib, "C:/MinGW/msys/1.0/gtk3/bin/libgio-2.0-0.dll")
#pragma comment(lib, "C:/MinGW/msys/1.0/gtk3/bin/libglib-2.0-0.dll")
#pragma comment(lib, "C:/MinGW/msys/1.0/gtk3/bin/libgobject-2.0-0.dll")
#pragma comment(lib, "C:/MinGW/msys/1.0/gtk3/bin/libpango-1.0-0.dll")

ググってみた

http://www.mingw.org/wiki/HOWTO_Specify_the_Location_of_Libraries_for_use_with_MinGW

説明がUnixベース。

-L

ライブラリを参照するパスを指定する。

書式がイマイチわからない。以下を試してみた。

  • -L C:/MinGW/msys/1.0/gtk3/bin
  • -L C:\MinGW\msys\1.0\gtk3\bin
  • -LC:/MinGW/msys/1.0/gtk3/bin
  • -LC:\MinGW\msys\1.0\gtk3\bin

同様のエラー。参照できてない。

--library-path=C:/MinGW/msys/1.0/gtk3/binは以下のエラーになった。

gcc.exe: エラー: 認識できないオプション '--library-path=C:/MinGW/msys/1.0/gtk3/bin' です

-l

ライブラリの名前を指定する。

  • -l libatk-1.0-0.dll
  • -l latk-1.0-0.dll
  • -l C:/MinGW/msys/1.0/gtk3/bin/libatk-1.0-0.dll
  • -l C:\MinGW\msys\1.0\gtk3\bin\libatk-1.0-0.dll

  • -llibatk-1.0-0.dll

  • -llatk-1.0-0.dll
  • -lC:/MinGW/msys/1.0/gtk3/bin/libatk-1.0-0.dll
  • -lC:\MinGW\msys\1.0\gtk3\bin\libatk-1.0-0.dll

同様のエラー。参照できてない。

ld --verbose

  1. コンソールで以下のコマンドを打つ

ld --verbose | grep SEARCH_DIR | tr -s ' ;' \\012

  1. 以下のような結果になる

    ld --verbose | grep SEARCH_DIR | tr -s ' ;' \012 SEARCH_DIR("=/usr/local/lib")0\SEARCH_DIR("=/lib")0\SEARCH_DIR("=/usr/lib")0

よくわからんけど、3つパスがある?

  • /usr/local/lib
  • /lib
  • /usr/lib

これ、完全にUnixのパスでは? Windows上では存在しないだろうからどこも参照されないのだろう。 Unixの常識はまったく知らないから、どんなパスなのかさっぱりわからない。

これ、どこで設定しているんだ?どうやって設定するの? 見るだけで変更できないじゃん。

というか、grepとかtrって、Unixのコマンドでは? なぜか動いている謎。

たぶんこのパスはgccのデフォルト設定なのかな? でも、gtkmm3を使わないプロジェクトだってある。 毎回参照するデフォルト参照パスにはしたくない。

gtkmm3のライブラリは、それを使うプロジェクトだけに使いたい。 だからコンパイルのコマンドで都度指定したい。

c:/msys/1.0/local

  1. c:/msys/1.0/localディレクトリを作成する
  2. そこにDLLファイルを配置する
  3. exeを実行する

同様のエラー。やはり参照されない。

c:/MinGW/local

  1. c:/MinGW/localディレクトリを作成する
  2. そこにDLLファイルを配置する
  3. exeを実行する

同様のエラー。やはり参照されない。

specファイル

http://www.mingw.org/wiki/SpecsFileHOWTO

gccにspecファイルを指定するといろいろ設定できるらしい。 参照するライブラリパスもそのひとつ。

  1. コンソールを起動する
  2. 右のコマンドを打つ gcc -dumpspecs > specs
  3. カレントディレクトリにspecsという名前のファイルができているはず
  4. テキストエディタでspecsファイルを開く
  5. 以下のような行がある

    *link_libgcc: %D

  6. その部分を以下のようにする

    *link_libgcc: %D -L C:/MinGW/msys/1.0/gtk3/bin

  7. gccコンパイルするとき、-specs=<path_to_specs_file>とする。今回は以下のようにした。

Makefile

hello: hello.c
    gcc -o hello.exe hello.c `pkg-config --cflags --libs gtk+-3.0` -mwindows -specs=C:/specs

compile.bat

set make="C:\MinGW\bin\mingw32-make.exe"
set file="Makefile"
%make% -f %file%
pause
  1. compile.batを実行してコンパイルする
  2. できたexeを実行する
  3. 同様のエラー。失敗。

だめだこりゃ。

*link_libgcc:
%D -L C:/MinGW/msys/1.0/gtk3/bin

という内容から察するに、gccの-Lパラメータと同じ。 すでに-Lは試していて、それが効いていない。

おなじディレクトリに配置

最悪だがexeとおなじディレクトリにgtkのdllを配置してみる。

exeを実行するたびに同様のDLL見つからないエラーがでる。 必要なdllを表示させていく。 一個ずつ配置していく。

  • libglib-2.0-0.dll
  • libatk-1.0-0.dll
  • libgdk_pixbuf-2.0-0.dll
  • libgio-2.0-0.dll
  • libgobject-2.0-0.dll
  • libpango-1.0-0.dll

7回目の実行でできた! GTKのメッセージボックスが出た。

dialog

しかし、gtk+3のプロジェクトごとに毎回、おなじDLLをコピーせねばならない。 ファイルサイズが無駄に浪費される。 どうにかしたいのだが、これ以上、参照パスを追加する手立てが見つけられない。 すごく気持ち悪い。

統一性のないgccの区切り文字

最後にグチ。gccの区切り文字が多すぎ。統一性がない。混乱する。

パターン
区切らない -LC:/dir
スペース -L C:/dir
= -specs=C:/specs
パラメータ 結果
-specs=C:/specs OK
-specs C:/specs OK
-specsC:/specs gcc.exe: エラー: 認識できないオプション '-specsC:/specs' です

パラメータの種類ごとに区切り文字が違うのか。 構文として統一すべきだと思うのだが。わかりづらすぎる。

ほかにも、以下のような罠が存在する。

  • gccコマンドではソースコードの後ろにpkg-config --cflags --libs gtk+-3.0をつけなければエラーになる
  • Makefileのインデントはスペースではダメ。TABを使うこと

環境構築をはじめてからずっと、知らねーよと言いたくなる罠が満載。