gccクロスコンパイラの謎
distcc使ってLinux版ビューアのビルド時間を短縮しようと思ったのです。とりあえず、Linux機 (Athlon X2 BE2350 (4150eの同等品) のほかにWindows機 (Athlon X2 4850e) と Mac mini (Core Duo 1.6HGz) があるので。
そこで、Windows (Cygwin) と Mac mini で、gcc のクロスコンパイラをビルドしたのです。このことがあるので、当然 gcc 4.1.2 です。
で、Linuxのオウンコンパイラでビルドしたものと、distcc でコンパイルした結果を比較すると … 一致しません。いや、どちらも起動すると動くのですが、でもバイナリが、そもそもファイルの寸法すら違う。同じバージョンのgccを使っているし、どのプラットフォームでも target=i386-redhat-linux としてビルドしたのに。
いろいろ調べた結果、MacOSで動かしたクロスコンパイラと、Linuxで動くオウンコンパイラは、ファイルの寸法やオブジェクトの size コマンドの結果が一致することがわかりました。問題は Windows 版のクロスコンパイラのようでした。そこで、さらに追求すると、クラスのコンストラクタが、LinuxのオウンコンパイラとMacOS版のクロスコンパイラでは.textセクションに配置されるのですが、Windows版のクロスコンパイラでは.gnu.linkonce.tというセクションに配置されていることがわかりました。これは、GNU ld でリンクする場合には.gnu.linkonce.tに配置されるほうが正統らしいのですが、Linuxのオウンコンパイラがそうしないのだから、クロス側のバグといわざるを得ません。
で、なぜ、こういう差が出るかというと、configure スクリプトが生成する auto-host.h というファイルで HAVE_COMDAT_GROUP というマクロ (定数) が定義されるのですが、LinuxとMacOSではこれが1になるのに、Windows (Cygwin) では0になっているためであることがわかりました。Windowsでの auto-host.h を手で書き直して 1 にすると、めでたく同じ寸法のオブジェクトが作られるようになりました。
とはいえ、これは、何がなんだか、さっぱりわかりません。auto-host.h は、その名の通りホスト環境 (コンパイラが動作するプラットフォーム) の特徴を記録するものです。なぜ、このファイルの内容の違いが、コンパイラが作り出すオブジェクト (本来、これは、ターゲット環境だけに依存するべき) に影響を与えるのでしょうか。
まぁ、今回の目的はgccのコンフィグのデバッグではないので、動けばよし、ということにしてこれ以上追求しないことにしましたが、気持ち悪いです。


最近のコメント