GCC cross-compiler

Mac OS XFreeBSD のバイナリを吐く gcc をビルドしてみた。いわゆるクロスコンパイラ。


まずは binutils を入手して適当なディレクトリに展開。
ftp://ftp.gnu.org/pub/gnu/binutils/
FreeBSD 以外へのクロスコンパイラをビルドするかもしれないので、専用のディレクトFreeBSD を作って、そこで作業をする。

% ../configure --prefix=/usr/local/cross --target=i686-freebsd6
% make
# make install

prefix は適当に。
これで、FreeBSD 用の ar とか as とか ld といったものが手に入った。


次は GCC。ダウンロードして適当なディレクトリに展開。
ftp://ftp.gnu.org/pub/gnu/gcc
これまた FreeBSD というディレクトリを用意して、そこで作業することにする。
事前にFreeBSD 用の binutils へのパスを通しておく。
gmp, mpfr が必要。macports で入れたなら、/opt/local に入ってる。

% export PATH=$PATH:/usr/local/cross/bin
% ../configure --prefix=/usr/local/cross --target=i686-freebsd6 --enable-language=c --with-gmp=/opt/local --with-mpfr=/opt/local
% make
# make install

たまに、なぜか ld がパーミッションの関係で失敗する。sudo でその場しのぎ。
これで gcc が完成。


とはいっても、標準ライブラリが全くそろっておらず、普通の C をコンパイルできない。
そこで、FreeBSD のものをもってくる。
/usr/include と /usr/lib があれば十分だろう。tar で固めて Mac へ送り、/usr/local/cross に展開。
これでクロスコンパイル環境が整ったはず。

% i686-freebsd6-gcc hello.c
% file a.out
a.out: ELF 32-bit LSB executable, Intel 80386, version 1 (FreeBSD), for FreeBSD 6.4, statically linked, for FreeBSD 6.4, not stripped

。。。あれ?statically linked なの?
試しに、ライブラリが必要な pthread を使ったソースをコンパイルしてみたけど、これもやはり statically linked になる。

% i686-freebsd6-gcc thr.c -lpthread -v
Using built-in specs.
Target: i686-freebsd6
コンフィグオプション: ../configure --prefix=/usr/local/cross --target=i686-freebsd6 --enable-languages=c --with-gmp=/opt/local --with-mpfr=/opt/local
スレッドモデル: posix
gcc version 4.3.3 (GCC) 
COLLECT_GCC_OPTIONS='-v' '-mtune=generic'
 /usr/local/cross/libexec/gcc/i686-freebsd6/4.3.3/cc1 -quiet -v thr.c -quiet -dumpbase thr.c -mtune=generic -auxbase thr -version -o /tmp/ccP5ERQ8.s
存在しないディレクトリ "/usr/local/cross/lib/gcc/i686-freebsd6/4.3.3/../../../../i686-freebsd6/sys-include" を無視します
#include "..." の探索はここから始まります:
#include <...> の探索はここから始まります:
 /usr/local/cross/lib/gcc/i686-freebsd6/4.3.3/include
 /usr/local/cross/lib/gcc/i686-freebsd6/4.3.3/include-fixed
 /usr/local/cross/lib/gcc/i686-freebsd6/4.3.3/../../../../i686-freebsd/include
探索リストの終わり
GNU C (GCC) version 4.3.3 (i686-freebsd6)
	compiled by GNU C version 4.3.2, GMP version 4.2.4, MPFR version 2.4.0.
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
Compiler executable checksum: bc96bc205c8801d1fe5ca81e8c4eadba
COLLECT_GCC_OPTIONS='-v' '-mtune=generic'
 /usr/local/cross/lib/gcc/i686-freebsd6/4.3.3/../../../../i686-freebsd6/bin/as -o /tmp/ccMCaXjz.o /tmp/ccP5ERQ8.s
COMPILER_PATH=/usr/local/cross/libexec/gcc/i686-freebsd6/4.3.3/:/usr/local/cross/libexec/gcc/i686-freebsd6/4.3.3/:/usr/local/cross/libexec/gcc/i686-freebsd6/:/usr/local/cross/lib/gcc/i686-freebsd6/4.3.3/:/usr/local/cross/lib/gcc/i686-freebsd6/:/usr/local/cross/lib/gcc/i686-freebsd6/4.3.3/../../../../i686-freebsd6/bin/
LIBRARY_PATH=/usr/local/cross/lib/gcc/i686-freebsd6/4.3.3/:/usr/local/cross/lib/gcc/i686-freebsd6/4.3.3/../../../../i686-freebsd6/lib/
COLLECT_GCC_OPTIONS='-v' '-mtune=generic'
 /usr/local/cross/libexec/gcc/i686-freebsd6/4.3.3/collect2 -V -dynamic-linker /libexec/ld-elf.so.1 /usr/local/cross/lib/gcc/i686-freebsd/4.3.3/../../../../i686-freebsd6/lib/crt1.o /usr/local/cross/lib/gcc/i686-freebsd6/4.3.3/../../../../i686-freebsd6/lib/crti.o /usr/local/cross/lib/gcc/i686-freebsd6/4.3.3/crtbegin.o -L/usr/local/cross/lib/gcc/i686-freebsd6/4.3.3 -L/usr/local/cross/lib/gcc/i686-freebsd6/4.3.3/../../../../i686-freebsd6/lib /tmp/ccMCaXjz.o -lpthread -lgcc -lgcc_eh -lc -lgcc -lgcc_eh /usr/local/cross/lib/gcc/i686-freebsd6/4.3.3/crtend.o /usr/local/cross/lib/gcc/i686-freebsd6/4.3.3/../../../../i686-freebsd6/lib/crtn.o
GNU ld (GNU Binutils) 2.19.1
  Supported emulations:
   elf_i386_fbsd
   elf_i386
   i386bsd

ロスコンパイル環境で dynamically linked にするのは無理なのかなぁ。
a.out に共有ライブラリへのパスをハードコードする以上、無理っぽい気もする。