なんとな~くしあわせ?の日記

JavaとかAWSの設定とかをメモする技術ブログ

wxWidgets-2.9.5 msw

ビルドしようとしたら Win9.x系のコードがundefined referenceになってた...ほげー

環境:Debian Wheezy
コンパイラ

$ /usr/x86_64-w64-mingw32/bin/gcc --version
gcc (rubenvb-4.7.2-release) 4.7.2
Copyright (C) 2012 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

basedllのビルドでエラーとなる

basedll_ffile.o:ffile.cpp:(.text+0x4cc4): undefined reference to `wxMSLU__wfopen(wchar_t const*, wchar_t const*)'
basedll_file.o:file.cpp:(.text+0xa0): undefined reference to `wxMSLU__waccess(wchar_t const*, int)'
basedll_file.o:file.cpp:(.text+0x2c9d): undefined reference to `wxMSLU__wremove(wchar_t const*)'
basedll_file.o:file.cpp:(.text+0x4b66): undefined reference to `wxMSLU__wopen(wchar_t const*, int, int)'
basedll_file.o:file.cpp:(.text+0x5d1a): undefined reference to `wxMSLU__wopen(wchar_t const*, int, int)'
basedll_file.o:file.cpp:(.text+0xdf6b): undefined reference to `wxMSLU__wremove(wchar_t const*)'
/usr/bin/../lib/gcc/x86_64-w64-mingw32/4.7.2/../../../../x86_64-w64-mingw32/bin/ld: basedll_file.o: 誤った再配置アドレス 0x0 がセクション `.pdata' 内にあります
collect2: error: ld returned 1 exit status

setup0.hの中身
デフォルトで0になってるからMSLU系のコードはそもそもビルドしないはず…?

/* --- start MSW options --- */
// ----------------------------------------------------------------------------
// Windows-only settings
// ----------------------------------------------------------------------------

// Set wxUSE_UNICODE_MSLU to 1 if you're compiling wxWidgets in Unicode mode
// and want to run your programs under Windows 9x and not only NT/2000/XP.
// This setting enables use of unicows.dll from MSLU (MS Layer for Unicode, see
// http://www.microsoft.com/globaldev/handson/dev/mslu_announce.mspx). Note
// that you will have to modify the makefiles to include unicows.lib import
// library as the first library (see installation instructions in install.txt
// to learn how to do it when building the library or samples).
//
// If your compiler doesn't have unicows.lib, you can get a version of it at
// http://libunicows.sourceforge.net
//
// Default is 0
//
// Recommended setting: 0 (1 if you want to deploy Unicode apps on 9x systems)
#ifndef wxUSE_UNICODE_MSLU
    #define wxUSE_UNICODE_MSLU 0
#endif

追記 8/24:configure実行時のオプション設定

なんか最近MinGWビルドが壊れ気味…(wxWidgets-2.9.5)
libtiff => builtin不可
expat => builtin不可
なのでこの2つは別にビルドしてインストールしておく

あとwxMSLUがクソ邪魔なので --disable-mslu してみる。

./configure CXXFLAGS=-std=c++11 --enable-unicode --disable-debug --with-msw \
--with-libjpeg=builtin --with-libpng=builtin --with-regex=builtin           \
--with-zlib=builtin --enable-std_containers --enable-std_iostreams          \
--enable-std_string --disable-mslu

追記 8/24:どうも上の設定を追加してもビルドの時設定が効いていないくさい、これはまたwx-devにメールでしょうか…

原因と思わしきところはここ。
①wxUSE_UNICODE_MSLUがなぜか1になりsetup0.hで定義されているので、「#if wxUSE_UNICODE_MSLU || defined(__WX_STRICT_ANSI_GCC__)」以下が有効になる。
②そんな関数はソースにないのでUndefined reference...

wxWidgets/include/wx/filefn.h

    // finally the default char-type versions
    #if wxUSE_UNICODE
        #if wxUSE_UNICODE_MSLU || defined(__WX_STRICT_ANSI_GCC__)
            // implement the missing file functions in Win9x ourselves
            WXDLLIMPEXP_BASE int wxMSLU__wopen(const wxChar *name,
                                               int flags, int mode);
            WXDLLIMPEXP_BASE int wxMSLU__waccess(const wxChar *name,
                                                 int mode);
            WXDLLIMPEXP_BASE int wxMSLU__wchmod(const wxChar *name,
                                                 int mode);
            WXDLLIMPEXP_BASE int wxMSLU__wmkdir(const wxChar *name);
            WXDLLIMPEXP_BASE int wxMSLU__wrmdir(const wxChar *name);

            WXDLLIMPEXP_BASE int
            wxMSLU__wstat(const wxChar *name, wxStructStat *buffer);

            #define   wxCRT_Open       wxMSLU__wopen

            #define   wxCRT_Access     wxMSLU__waccess
            #define   wxCRT_Chmod      wxMSLU__wchmod
            #define   wxCRT_MkDir      wxMSLU__wmkdir
            #define   wxCRT_RmDir      wxMSLU__wrmdir
            #define   wxCRT_Stat       wxMSLU__wstat
        #else // !wxUSE_UNICODE_MSLU
            #define wxCRT_Open      wxCRT_OpenW
            #define wxCRT_Access    wxCRT_AccessW
            #define wxCRT_Chmod     wxCRT_ChmodW
            #define wxCRT_MkDir     wxCRT_MkDirW
            #define wxCRT_RmDir     wxCRT_RmDirW
            #define wxCRT_Stat      wxCRT_StatW
        #endif // wxUSE_UNICODE_MSLU/!wxUSE_UNICODE_MSLU
    #else // !wxUSE_UNICODE
        #define wxCRT_Open      wxCRT_OpenA
        #define wxCRT_Access    wxCRT_AccessA
        #define wxCRT_Chmod     wxCRT_ChmodA
        #define wxCRT_MkDir     wxCRT_MkDirA
        #define wxCRT_RmDir     wxCRT_RmDirA
        #define wxCRT_Stat      wxCRT_StatA
    #endif // wxUSE_UNICODE/!wxUSE_UNICODE

解決法

つまりはこれwxUSE_UNICODEが0であれ、1であれ定義されるのが悪い。
本当は --disable-mslu した時に #undef wxUSE_UNICODE してやるべきなのでは?
とりま wxWidgets/include/wx/msw/setup0.h の 「#define wxUSE_UNICODE_MSLU 0」の部分をコメントアウトして様子を見る。

その後

「#define wxUSE_UNICODE_MSLU 0」の部分を変えても無駄だった。
条件をほとんど変えず「CXXFLAGS='-std=c++11'」を抜くことでビルドが正常に完了した。
ちょっとエラーの原因がわかりにくいですね…

追記

なんか「CXXFLAGS='-std=gnu++11'」だとビルド通るという情報があるようなないような…
Google グループ