2015年03月02日
Linux環境にwineをインストールするとWindowsターゲットのクロスコンパイルが失敗する
Ubuntu などの最近の Linux ディストリビューションは、MinGW 環境をターゲットにしたクロスコンパイラが標準パッケージに含まれているので、非常に簡単に Windows 向けのバイナリをコンパイルすることが可能です。Windows 上で MinGW + MSYS あるいは cygwin で、Linux を前提としたツールをコンパイルするのはそれなりに大変なので、Linux 環境でクロスコンパイルしている方も多いと思います。私も愛用しています。
わかってしまえば非常にマヌケな話なのですが、ビルドしたバイナリを Linux 上でテストまでしたいなと思い、何気なく wine(Windows API 互換レイヤー)をインストールして色々検証していて、久しぶりにビルドしてみたら、突然全く触ってないあたりのクロスコンパイル(正確には configure)が失敗するようになり、原因の究明に苦労したので、その時のメモです。
わかってしまえば非常にマヌケな話なのですが、ビルドしたバイナリを Linux 上でテストまでしたいなと思い、何気なく wine(Windows API 互換レイヤー)をインストールして色々検証していて、久しぶりにビルドしてみたら、突然全く触ってないあたりのクロスコンパイル(正確には configure)が失敗するようになり、原因の究明に苦労したので、その時のメモです。
今回は GCC の依存ライブラリであり、実際に失敗した libelf を例にあげます。一つ一つ関係しそうな所を潰して行った結果、最終的に、以下の部分が OK パターンと NG パターンで異なる所まで絞り込みました。
当然のことながら、wine を導入すると、Windows 向けのバイナリが正常実行できるようになってしまうので、このような判定方法の configure は間違えてしまいます。configure が失敗してくれたから良かったものの、もしたまたま通っていたら、さらにわかりにくいことになっていたかもしれません…。
とりあえずこの時は、ビルド環境の Ubuntu 14.04 から、以下のようにして wine をアンインストールして、ビルドが失敗する問題は解決しました。
checking whether the C compiler (i686-w64-mingw32-gcc ) works... yes
checking whether the C compiler (i686-w64-mingw32-gcc ) is a cross-compiler... no
なぜか Linux 上で Windows 向けバイナリをビルドしようとしているのに、cross compiler だと正しく判定できていません。libelf 0.8.13 の configure は、以下のようにして cross compiler を判定していました。
cross_compiling=$ac_cv_prog_cc_cross cat > conftest.$ac_ext << EOF #line 735 "configure" #include "confdefs.h" main(){return(0);} EOF if { (eval echo configure:740: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ac_cv_prog_cc_works=yes # If we can't run a trivial program, we are probably using a cross compiler. if (./conftest; exit) 2>/dev/null; then ac_cv_prog_cc_cross=no else ac_cv_prog_cc_cross=yes fi (略)要するに、return 0 するだけの簡単なプログラムをコンパイルして実行してみて、失敗(戻り値が非ゼロ)したらクロスコンパイラという判定です。
当然のことながら、wine を導入すると、Windows 向けのバイナリが正常実行できるようになってしまうので、このような判定方法の configure は間違えてしまいます。configure が失敗してくれたから良かったものの、もしたまたま通っていたら、さらにわかりにくいことになっていたかもしれません…。
とりあえずこの時は、ビルド環境の Ubuntu 14.04 から、以下のようにして wine をアンインストールして、ビルドが失敗する問題は解決しました。
$ sudo apt-get autoremove wine