23 Sept 2015

MinGW-w64 GCCでのconfig.guessを改善

MSYS2環境下でネイティブなMinGW-w64 GCCを使っている人は経験あると思うがMinGW-w64 GCCをtoolchainとしてautotools系のconfigureを走らせた時に--build/--hostを適切に指定する必要がある.これを指定しなくても良くしたいというお話.
autotoolsではtoolchainの判別にconfig.{guess,sub}というシェルスクリプトを利用している.
その中でtoolchainのtarget machineの判別にはuname -mが用いられている.
MSYS2の場合unameが返すのはMSYS2に関する情報なので例えば64bitのMSYS2を使っているのであればMinGW-w64 GCCのtargetが32bitであってもtarget machineはx86_64であるとして検出されてしまうことになる(逆もしかり).
これがtarget machine誤判定の理由である.
また,config.guessでは(mingw.orgの)MinGWであろうとMinGW-w64であろうとtarget vendorは'pc'と決め打ちされている.
通常,MinGW-w64を使用する際は'w64'が用いられる.
更に,target osの判定にはuname -sが用いられるのだがMSYS2は環境変数MSYSTEMの値によりuname -sが返す値を変更するようになっており,例えばwin7で動かしておりMSYSTEMがMINGW32に設定されているとuname -sはMINGW32_NT-6.1を返すはずである.
この場合問題になるのが64bit targetなMinGW-w64 GCCを使っている時である.通常何も変更を加えておらず素直にMSYS2を使って64bitなMinGW-w64 GCCを使っている場合MSYSTEMはMINGW64に設定されているはずである.
つまりuname -sはMINGW64* (*は環境により異なる)となる.uname -sがMINGW64*となる時,config.guessはお節介にもtarget osをmingw64に設定する.実際そのようなtarget osが使われることなど無いにもかかわらずである.これは常にmingw32となってくれればいい.
このように様々なことが重なりあって--build/--hostを毎回指定しなければいけない事態が生じてしまっている.
しかし,これ自体はしかたのないこととも言える.クロスコンパイルのように見えて実際はネイティブなコンパイルという通常の*nix環境とは異なる構造だからである.
とは言え面倒であることには変わらないのでconfig.guessに修正を加えて適切に32bit, 64bitによって{i686,x86_64}-w64-mingw32が選択されるようにする.

この修正を加えたconfig.guessをautomakeのperl_libdirsに上書きすればOK.
これでautotools系のconfigure前にautoreconf -ivfとかすればいい.
ただし,注意が必要でccという名前のコマンドがPATHにある場合MinGW-w64 GCCのbindir(通常は/mingw64/bin or /mingw32/bin)にMinGW-w64 GCCのgcc.exeのシンボリックリンクとしてccが存在してないと目的のものとは違うコンパイラで判別が実行されてしまう.
これはconfig.guessがcc gcc...etc. といった順で判別を試行するためである.

今回の内容はMSYS2使っているけれどtoolchainは自前で用意しているという奇特な方向けかもしれない.

No comments:

Post a Comment