SylpheedをMinGWでビルドするときのコンパイルエラー(interface)

sylpheedを手元のMinGW環境でビルドしてみようとしてエラーになった。
gcc -Eで試してみたらソースの変数名interfaceがなぜかstructに変更されていた。

static struct Interface {
 GtkWidget *checkbtn_always_show_msg;
 GtkWidget *checkbtn_always_mark_read;
 GtkWidget *checkbtn_openunread;
 GtkWidget *checkbtn_remember_lastsel;

 GtkWidget *checkbtn_openinbox;
 GtkWidget *checkbtn_openinbox_startup;
 GtkWidget *checkbtn_change_account_on_folder_sel;
 GtkWidget *checkbtn_immedexec;

 GtkWidget *checkbtn_show_trayicon;
 GtkWidget *checkbtn_minimize_to_tray;
 GtkWidget *checkbtn_tray_toggle_window;
} struct;

なんでこんなことになるんだろうと調べてみたら、
C:\MinGW\include\basetyps.hで#define interface _COM_interfaceと定義されていて、
最終的に_COM_interfaceがstructに再定義されるためのようです。


basetyps.hはMinGWのみなので、Linux環境だと問題にならないようです。


以前ビルドを試してみたときはコレひっかからなかったかは不明。
ただ手元の環境が腐っている可能性がなきにしもあらず。

Sylpheed のプラグインを書く

sylpheed 3.xからプラグイン機能が追加されたようなので、
ものは試しということで受信したメールを別アカウントに送信するプラグインを作ってみました。


sylpheedの新着メールチェック機能と組みあわせることで、自動転送っぽいことができるようになります。
*1
本来そんなことはメールクライアントでやるんじゃなくて、サーバ側で設定するのが筋です。


使い方については別途ページを用意しました。
要はautoforwardrcを書いて、プラグインを配置して、ツールメニューから有効にするだけです。
*2


ダウンロードは以下から sylpheed-autoforward-0.1.0.zip
http://gigo-ice.org/tech/sylpheed.ja.html


Windows環境だとプラグインを書くことよりも、ビルドできる環境を用意するほうが面倒臭いというオチ。
sylpheed --debugで起動するとデバッグモードで起動できることを初めて知った。

他に公開されているプラグインがあれば教えてください。

*1:大量にメールを一括受信するような使用は想定していません。コールバックが呼ばれまくるので

*2:起動時には無効になっています

FLTK 2.0.x r7725をビルドするときのエラーへの対処

GUIツールキットとして有名なFLTKをMinGW環境でビルドしてみた。
MinGW環境はmingw-getでインストールできる4.5.0系のg++によるもの。

この環境ではauto-importの警告とかUnwind_Resumeの多重定義エラーが出たりする。

auto-importの警告とは以下のようなもの。

c:/mingw/bin/../lib/gcc/mingw32/4.5.0/../../../../mingw32/bin/ld.exe: warning: auto-importing has been activated without --enable-auto-import specified on the command line.
This should work unless it involves constant data structures referencing symbols from auto-imported DLLs.

Unwind_Resumeのエラーは以下のようなもの。

Creating library file: ../lib/libfltk2_images.dll.ac:/mingw/bin/../lib/gcc/mingw32/4.5.0/libgcc_eh.a(unwind-dw2.o):(.text+0x28c8): multiple definition of `_Unwind_Resume'

それらに対処するには--enable-auto-importをリンカに渡してやるとかリンク時のライブラリ指定の除外をしてやれば良い。

具体的には-Wl,--enable-auto-importとか-Wl,--exclude-libs,libgcc_eh.aとかを指定するということ。

ref. http://forums.codeblocks.org/index.php?topic=10508.0

というわけで、トップレベルにあるmakeincludeに細工をしてやれば良い。
差分としては以下のように修正する。

--- makeinclude.orig	2010-10-28 23:07:15 +0900
+++ makeinclude	2010-10-28 23:36:25 +0900
@@ -65,7 +65,7 @@
 RANLIB		= ranlib
 
 # programs and definitions to make shared libraries:
-DSOCOMMAND	= $(CXX) -Wl,--out-implib,../lib/lib$(DSONAME).a -shared -DFL_SHARED -DFL_LIBRARY -DFL_IMAGES_LIBRARY -DFL_GLUT_LIBRARY -DFL_FORMS_LIBRARY -DFL_GL_LIBRARY  -o
+DSOCOMMAND	= $(CXX) -Wl,--out-implib,../lib/lib$(DSONAME).a -Wl,--exclude-libs,libgcc_eh.a -shared -DFL_SHARED -DFL_LIBRARY -DFL_IMAGES_LIBRARY -DFL_GLUT_LIBRARY -DFL_FORMS_LIBRARY -DFL_GL_LIBRARY  -o
 DSOLINK		= 
 DSOPREFIX	= 
 DSOSUFFIX	= .dll
@@ -77,8 +77,8 @@
 ZLIBINC		= 
 
 # libraries to link with:
-LDLIBS = -mwindows -Wl,--enable-runtime-pseudo-reloc -lpthread  -lmsimg32 -lole32 -luuid -lcomctl32 -lwsock32 -lsupc++
-GLDLIBS = -mwindows -Wl,--enable-runtime-pseudo-reloc -lglu32 -lopengl32 -lpthread  -lmsimg32 -lole32 -luuid -lcomctl32 -lwsock32 -lsupc++
+LDLIBS = -mwindows -Wl,--enable-runtime-pseudo-reloc -Wl,--enable-auto-import -lpthread  -lmsimg32 -lole32 -luuid -lcomctl32 -lwsock32 -lsupc++
+GLDLIBS = -mwindows -Wl,--enable-runtime-pseudo-reloc -Wl,--enable-auto-import -lglu32 -lopengl32 -lpthread  -lmsimg32 -lole32 -luuid -lcomctl32 -lwsock32 -lsupc++
 LINKFLTK = -L../lib -lfltk2
 LINKFLTKGL = -L../lib -lfltk2_gl -lfltk2
 LINKFLTKFORMS = -L../lib -lfltk2_forms -lfltk2

モダンなMinGWの始め方

以前、MinGWCUImingw-getコマンドでインストールするようになるっぽい、
なんて書いていましたが、しばらく見ないうちに初期セットアップ用のインストーラが公開されていました。

mingw-get-inst-20100909.exeをダウンロードしてpre-packaged repository catalogを選択してインストールすることができます。
通常はMSYS Basic SystemとMinGW Developer Toolsあたりまでを選択してインストールしておけば十分でしょう。

Gauche-dbd-pg 0.2.1をビルドしたがuseに失敗する

上記環境でGauche-dbd-pg 0.2.1をビルドしたが、
goshで(use dbd.pg)してみるとLoadLibraryに失敗する。

Windows 7側で問題ないのにXP Modeだと発生するというのも不可解。
dependency walkerで依存を調べてみたら以下のような依存関係となっていた。

SECUR32.DLL > NETAPI32.DLL > DNSAPI.DLL > IPHLPAPI.DLL > MPRAPI.DLL > SETUPAPI.DLL > MPR.DLL > SHELL32.DLL > SHDOCVW.DLL > MSHTML.DLL > IMGUTIL.DLL > MSJAVA.DLL

MSJAVA.DLLが見付からなくてfailしている様子。

secur32.dllへのリンクはlibpq側で必須なので、
さしあたり、libpqは--with-opensslなしでビルドし、かつbinディレクトリに0バイトのmsjava.dllを配置することで妥協してみた。

MinGW環境をちょろっとセットアップするには

Gauche野良ビルドでうまくロードできないDLLができてしまうので、
再検証用に一度MinGW環境をリセットすることにした。

やることは3つ。

  1. MinGWのバイナリを展開
  2. MSYS-1.0.11.exeをインストール
  3. MSYSのバイナリを展開

MinGWのサイトから以下をダウンロードしてきてc:/MinGWに展開しておく。
ちなみに以下はgcc 4.4.0の環境にするためのものです。
(最低限にするんだったらまったくいらないものも混じってます。)

autoconf-7-1-mingw32-bin.tar.lzma
autoconf2.1-2.13-4-mingw32-bin.tar.lzma
autoconf2.5-2.64-1-mingw32-bin.tar.lzma
automake-4-1-mingw32-bin.tar.lzma
automake1.10-1.10.2-1-mingw32-bin.tar.lzma
automake1.11-1.11-1-mingw32-bin.tar.lzma
automake1.4-1.4p6-1-mingw32-bin.tar.lzma
automake1.5-1.5-1-mingw32-bin.tar.lzma
automake1.6-1.6.3-1-mingw32-bin.tar.lzma
automake1.7-1.7.9-1-mingw32-bin.tar.lzma
automake1.8-1.8.5-1-mingw32-bin.tar.lzma
automake1.9-1.9.6-3-mingw32-bin.tar.lzma
binutils-2.20.51-1-mingw32-bin.tar.lzma
expat-2.0.1-1-mingw32-bin.tar.gz
gcc-c++-4.4.0-mingw32-bin.tar.gz
gcc-c++-4.4.0-mingw32-dll.tar.gz
gcc-core-4.4.0-mingw32-bin.tar.gz
gcc-core-4.4.0-mingw32-dll.tar.gz
gdb-7.1-2-mingw32-bin.tar.gz
gendef-1.0.1346-1-mingw32-bin.tar.lzma
gmp-4.2.4-mingw32-dll.tar.gz
libcharset-1.13.1-1-mingw32-dll-1.tar.lzma
libexpat-2.0.1-1-mingw32-dev.tar.gz
libexpat-2.0.1-1-mingw32-dll-1.tar.gz
libiconv-1.13.1-1-mingw32-bin.tar.lzma
libiconv-1.13.1-1-mingw32-dev.tar.lzma
libiconv-1.13.1-1-mingw32-dll-2.tar.lzma
libltdl-2.2.7a-1-mingw32-dev.tar.lzma
libltdl-2.2.7a-1-mingw32-dll-7.tar.lzma
libmpc-0.8.1-1-mingw32-dll-2.tar.lzma
libmpfr-2.4.1-1-mingw32-dll-1.tar.lzma
libpopt-1.15-1-mingw32-dev.tar.lzma
libpopt-1.15-1-mingw32-dll-0.tar.lzma
libpthread-2.8.0-3-mingw32-dll-2.tar.lzma
libtool-2.2.7a-1-mingw32-bin.tar.lzma
libz-1.2.3-1-mingw32-dev.tar.gz
libz-1.2.3-1-mingw32-dll-1.tar.gz
make-3.82-1-mingw32-bin.tar.lzma
mingw-catgets-1.0-bin.tar.gz
mingw-catgets-1.0-dev.tar.gz
mingw-libgnurx-2.5.1-bin.tar.gz
mingw-libgnurx-2.5.1-dev.tar.gz
mingw-utils-0.4-1-mingw32-bin.tar.lzma
mingwrt-3.18-mingw32-dev.tar.gz
mingwrt-3.18-mingw32-dll.tar.gz
mpfr-2.4.1-mingw32-dll.tar.gz
pexports-0.44-1-mingw32-bin.tar.lzma
pthreads-w32-2.8.0-3-mingw32-dev.tar.lzma
w32api-3.14-mingw32-dev.tar.gz

pthreadだけはpthread-win32カテゴリからダウンロードする。
そちらだとファイル名がリネームされていてリンクするのに都合が良くなっています。
具体的には以下のように変更されました。

  pthreadGC2.dll  -> libpthread-2.dll
  libpthreadGC2.a -> libpthread.dll.a


MinGWは5.1.6のインストーラがあるけど使わなくてもいいです。
(そっちだとgcc 3.4.5がセットアップされたりした記憶があります。)
MinGW自体も現在はインストーラはリリースせず、mingw-getなるCUIベースでセットアップできるようなものに
移行する方向らしいです。


次にMSYS-1.0.11.exeをインストールする。
これはおとなしくインストーラを使います。インストールするとmsys.batとか用意されているので楽だから、というのが理由です。


最後にMSYSのバイナリを展開して終りです。
このあたりは必要に応じて新しいバイナリを選択すると良いでしょう。
m4はそのままだとバージョンが古いので置き換えました。
あとはランタイムでDLLが必要だとかそんな理由です。
詳細はリリースノートをこまめに読むといいと思います。

bison-2.4.2-1-msys-1.0.13-bin.tar.lzma
flex-2.5.35-2-msys-1.0.13-bin.tar.lzma
libiconv-1.13.1-2-msys-1.0.13-dll-2.tar.lzma
libintl-0.17-2-msys-dll-8.tar.lzma
libregex-1.20090805-2-msys-1.0.13-dll-1.tar.lzma
m4-1.4.14-1-msys-1.0.13-bin.tar.lzma
perl-5.6.1_2-2-msys-1.0.13-bin.tar.lzma
libcrypt-1.1_1-3-msys-1.0.13-dll-0.tar.lzma
coreutils-5.97-3-msys-1.0.13-bin.tar.lzma
coreutils-5.97-3-msys-1.0.13-ext.tar.lzma

とまあこれだけなんですが、
初めてMinGWをインストールしたとき、ものによってはダウンロードページにMinGW版とMSYS版両方あるとか
なんだかよくわからなくて途方にくれたことがあったのをふと思いだしました。

MinGW環境でSylpheedのtrunkをビルドしてみる

ふと思い立って、sylpheedをビルドしてみることにした。

ビルド手順についてはhttp://sylpheed.sraoss.jp/wiki/index.php?Sylpheed%2FWin32が詳しい。
いくつか現状にそぐわないところがあるのでそのへんは適宜読みかえて環境を準備。


home以下のtrunkディレクトリを用意して、ソースコードをまずはチェックアウト。
リビジョンはr2217。

configure.in:88: warning: macro `AM_PATH_GLIB_2_0' not found in library
configure.in:92: warning: macro `AM_PATH_GTK_2_0' not found in library
configure.in:112: warning: macro `AM_GLIB_GNU_GETTEXT' not found in library
configure.in:151: warning: macro `AM_PATH_GPGME' not found in library
libtoolize: putting auxiliary files in `.'.
libtoolize: copying file `./ltmain.sh'
libtoolize: Consider adding `AC_CONFIG_MACRO_DIR([m4])' to configure.in and
libtoolize: rerunning libtoolize, to keep the correct libtool macros in-tree.
libtoolize: Consider adding `-I m4' to ACLOCAL_AMFLAGS in Makefile.am.
libsylph/Makefile.am: installing `./depcomp'
configure.in: installing `./ylwrap'
configure.in:88: error: possibly undefined macro: AM_PATH_GLIB_2_0
      If this token and others are legitimate, please use m4_pattern_allow.
      See the Autoconf documentation.
configure.in:92: error: possibly undefined macro: AM_PATH_GTK_2_0
configure.in:112: error: possibly undefined macro: AM_GLIB_GNU_GETTEXT
configure.in:151: error: possibly undefined macro: AM_PATH_GPGME

何も考えずにautogen.shを実行するといろいろ怒られるので、aclocalにGTKのパスを指定してあげることにする。

aclocal -I ac -I c:/GTK/share/aclocal \
  && libtoolize --force --copy \
  && autoheader \
  && automake --add-missing --foreign --copy \
  && autoconf \
  && ./configure $@

すると以下のようにAM_PATH_GPGMEが見付からないというエラーが出ます。

configure.in:151: warning: macro `AM_PATH_GPGME' not found in library
libtoolize: putting auxiliary files in `.'.
libtoolize: copying file `./ltmain.sh'
libtoolize: Consider adding `AC_CONFIG_MACRO_DIR([m4])' to configure.in and
libtoolize: rerunning libtoolize, to keep the correct libtool macros in-tree.
libtoolize: Consider adding `-I m4' to ACLOCAL_AMFLAGS in Makefile.am.
configure.in:151: error: possibly undefined macro: AM_PATH_GPGME
      If this token and others are legitimate, please use m4_pattern_allow.
      See the Autoconf documentation.

とりあえずac/missingから*.m4をacディレクトリにコピーしてから再度autogen.shを実行してみます。

sylpheed 2.7.1

GnuPG         : no
JPilot        : no
LDAP          : no
OpenSSL       : yes
iconv         : yes
compface      : no
IPv6          : yes
GtkSpell      : no
Oniguruma     : no

The binary will be installed in /usr/local/bin

Configure finished, type 'make' to build.

Onigurumaは有効にしたいので、onig-5.9.1を--prefix=/mingwでビルドインストールする。
で、trunk/makewin32.shを実行してみる。

sylpheed 2.7.1

GnuPG         : no
JPilot        : no
LDAP          : no
OpenSSL       : yes
iconv         : yes
compface      : no
IPv6          : no
GtkSpell      : no
Oniguruma     : yes

The binary will be installed in /home/khayashi/dist/bin

Configure finished, type 'make' to build.

Onigurumaを無事検出できているのがわかります。

ではmakeしてみます。

/bin/sh ../libtool --tag=CC   --mode=link gcc -mtune=pentium3  -O3 -mms-bitfields -mwindows -I/mingw/include -version-info 0:1:0 -export-dynamic -no-undefined -export-symbols libsylph-0.def  -o libsylph-0.la -rpath /home/khayashi/dist/lib account.lo base64.lo codeconv.lo customheader.lo displayheader.lo filter.lo folder.lo html.lo imap.lo mbox.lo md5.lo md5_hmac.lo mh.lo news.lo nntp.lo pop.lo prefs.lo prefs_account.lo prefs_common.lo procheader.lo procmime.lo procmsg.lo quoted-printable.lo recv.lo session.lo smtp.lo socket.lo ssl.lo stringtable.lo sylmain.lo unmime.lo utils.lo uuencode.lo virtual.lo xml.lo syl-marshal.lo -Lc:/GTK/lib -lgobject-2.0 -lgmodule-2.0 -lglib-2.0 -lintl   -lws2_32 -lssl32 -leay32 -L/mingw/lib -lonig

*** Warning: This system can not link to static lib archive /mingw/lib/libonig.la.
*** I have the capability to make that library automatically link in when
*** you link to this library.  But I can only do this if you have a
*** shared version of the library, which you do not appear to have.
libtool: link: /mingw/bin/nm  .libs/account.o .libs/base64.o .libs/codeconv.o .libs/customheader.o .libs/displayheader.o .libs/filter.o .libs/folder.o .libs/html.o .libs/imap.o .libs/mbox.o .libs/md5.o .libs/md5_hmac.o .libs/mh.o .libs/news.o .libs/nntp.o .libs/pop.o .libs/prefs.o .libs/prefs_account.o .libs/prefs_common.o .libs/procheader.o .libs/procmime.o .libs/procmsg.o .libs/quoted-printable.o .libs/recv.o .libs/session.o .libs/smtp.o .libs/socket.o .libs/ssl.o .libs/stringtable.o .libs/sylmain.o .libs/unmime.o .libs/utils.o .libs/uuencode.o .libs/virtual.o .libs/xml.o .libs/syl-marshal.o   | sed -n -e 's/^.*[	 ]\([ABCDGIRSTW][ABCDGIRSTW]*\)[	 ][	 ]*_\([_A-Za-z][_A-Za-z0-9]*\)\{0,1\}$/\1 _\2 \2/p' | /bin/sed -e '/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //' | sort | uniq > .libs/libsylph-0.exp
libtool: link: if test "x`/bin/sed 1q .libs/libsylph-0.def`" = xEXPORTS; then cp .libs/libsylph-0.def .libs/libsylph-0-0.dll.def; else echo EXPORTS > .libs/libsylph-0-0.dll.def; cat .libs/libsylph-0.def >> .libs/libsylph-0-0.dll.def; fi
libtool: link:  gcc -mtune=pentium3 -shared .libs/libsylph-0-0.dll.def  .libs/account.o .libs/base64.o .libs/codeconv.o .libs/customheader.o .libs/displayheader.o .libs/filter.o .libs/folder.o .libs/html.o .libs/imap.o .libs/mbox.o .libs/md5.o .libs/md5_hmac.o .libs/mh.o .libs/news.o .libs/nntp.o .libs/pop.o .libs/prefs.o .libs/prefs_account.o .libs/prefs_common.o .libs/procheader.o .libs/procmime.o .libs/procmsg.o .libs/quoted-printable.o .libs/recv.o .libs/session.o .libs/smtp.o .libs/socket.o .libs/ssl.o .libs/stringtable.o .libs/sylmain.o .libs/unmime.o .libs/utils.o .libs/uuencode.o .libs/virtual.o .libs/xml.o .libs/syl-marshal.o   -Lc:/GTK/lib -lgobject-2.0 -lgmodule-2.0 -lglib-2.0 /mingw/lib/libintl.dll.a -L/mingw/lib /mingw/lib/libiconv.dll.a -lws2_32 -lssl32 -leay32  -mtune=pentium3 -mms-bitfields -mwindows   -o .libs/libsylph-0-0.dll -Wl,--enable-auto-image-base -Xlinker --out-implib -Xlinker .libs/libsylph-0.dll.a
Creating library file: .libs/libsylph-0.dll.a.libs/filter.o:filter.c:(.text+0x997): undefined reference to `reg_set_encoding'
.libs/filter.o:filter.c:(.text+0x9af): undefined reference to `regcomp'
.libs/filter.o:filter.c:(.text+0x9d8): undefined reference to `regexec'
.libs/filter.o:filter.c:(.text+0x9e2): undefined reference to `regfree

あっさりリンクエラーになっています。

というわけで、Onigurumaをスタティックでリンクしないように再ビルドします。
oni-5.9.1/Makefileを以下のように修正します。-no-undefined をつける、ということですね。

libonig_la_LDFLAGS = -no-undefined -version-info $(LTVERSION)

あとは、flexやbisonも必要です。

  • bison-2.4.1-1-msys-1.0.11-bin.tar.lzma
  • flex-2.5.35-1-msys-1.0.11-bin.tar.lzma
  • libregex-1.20090805-1-msys-1.0.11-dev.tar.lzma
  • libregex-1.20090805-1-msys-1.0.11-dll-1.tar.lzma

上記パッケージをtar --lzma -xvfとかで展開しときます。

test -f quote_fmt_lex.c || /bin/sh ../ylwrap quote_fmt_lex.l .c quote_fmt_lex.c -- /bin/sh /home/kenhys/Project/sylpheed/trunk/missing --run flex  
make[2]: *** [quote_fmt_lex.c] Error 1

bison,flexをインストールしたあと、上記エラーが出ることがありますが、makewin32.shを再実行してみてください。

これでビルドしたsylpheed.exeが起動せず。
c:/GTKからlibglib-2.0-0.dllをコピーして、元のintl.dllをlibintl-8.dllにしてしのいだ。