Skip to content

20080323

Ryota Shioya edited this page Mar 24, 2022 · 2 revisions

dst/ターゲット環境/クロスコンパイラの構築方法/gcc-ppc64/20080323.md

概要

  • 必要なもの

    • binutils
    • gcc
    • glibc
    • カーネルヘッダ
    • gmp,mpfr
  • 作業手順概要

    • binutilsを作成
    • glibcのヘッダだけ作成
    • glibc構築用gccの作成(C言語のみ)
    • glibcの構築
    • glibc構築用gccの作成(C言語のみ)2回目
    • フルglibcの構築
    • フルgccの作成(すべての言語)
  • glibcとgccはお互いに依存しているので,何回かに分けて無効オプションを外しながら構築を繰り返す必要がある

  • 注意

    • configure,makeを行う場合は,必ずソースがおいてあるディレクトリ以外で行うこと
    • 文中では,ソース中にworkと言うディレクトリを掘り,そこからの相対パス(../configureなど)で実行している

リンク

1. 環境

1.1 環境変数の設定

.rcの名前でファイル作成

#
# .rc
# cross compile environment
#

CROSS=~/opt/gcc-4.2.1-ppc64
export PATH=${CROSS}/bin:${PATH} 

export CROSS_HOST_LIB=${CROSS}/host-lib
export PPC64_HOST=powerpc64-unknown-linux-gnu
export PPC64_TARGET=powerpc64-unknown-linux-gnu

上記のファイルを以下のようにして読み込んでおく

source ./.rc

1.2 ディレクトリ作成

  • ${CROSS}以下にインストールを行うものとする
  • '-p'は,中間ディレクトリも含めて,再帰的に一気にディレクトリ作成を行うオプション
mkdir ${CROSS} -p

2. カーネルヘッダの展開

rpm2cpio kernel-headers-2.6.18-1.2798.fc6.ppc64.rpm | cpio --extract --make-directories
mkdir ${CROSS}/${PPC64_TARGET}/include -p
chmod 755 usr -R # 展開したままだと600になっていて,他人が使えない
cp -a usr/include/ ${CROSS}/${PPC64_TARGET}/
  • カーネルソース内のヘッダの位置はディストリビューションによってかわるかもしれず

  • シンボリックリンクが含まれているので,展開時は上記のようにrpm用コマンドで展開する

  • カーネルヘッダ自体はfedoraのものを使用

3. binutils作成

../configure \
--target=${PPC64_TARGET} \
--prefix=${CROSS} \
--enable-64-bit-bfd
make
make install 
  • intlがどーのこーのでエラーが出たら以下のオプションを追加
--disable-nls
  • 以下のオプションはホストが32bitのとき用(64でも多分問題ない)
--enable-64-bit-bfd
  • 追加のファイルコピー
mkdir ${CROSS}/include
cp -v ../include/libiberty.h ${CROSS}/include

4. glibcのヘッダだけを作る

libc_cv_c_cleanup=yes \
libc_cv_z_relro=yes \
libc_cv_z_initfirst=yes \
libc_cv_z_nodlopen=yes \
libc_cv_z_nodelete=yes \
libc_cv_forced_unwind=yes \
libc_cv_mlong_double_128ibm=yes \
libc_cv_mlong_double_128=yes \
libc_cv_powerpc64_tls=yes \
libc_cv_initfini_array=yes \
libc_cv_gcc___thread=yes \
AR=powerpc64-unknown-linux-gnu-ar \
RANLIB=powerpc64-unknown-linux-gnu-ranlib \
ac_cv_type_long_double=no \
../configure \
--prefix=${CROSS} \
--host=${PPC64_TARGET} \
--with-headers=${CROSS}/${PPC64_TARGET}/include \
--with-binutils=${CROSS}/${PPC64_TARGET}/bin \
--enable-add-ons \
--disable-sanity-checks \
--disable-versioning \
--disable-profile \
--with-tls \
make install-headers
  • クロス用gccはまだないので使えない

  • makeは単独でたたく必要はなく,"make install-headers"だけでよい

  • とりあえずconfigureを何とかしてごまかし通す

    • バイナリは生成しないのでリンク関係は全部うそついても大丈夫
  • ファイルが足りないので仕上げ

    • work中のbitsを参照
cp -v bits/stdio_lim.h ${CROSS}/include/bits
mkdir ${CROSS}/include/gnu -p
touch ${CROSS}/include/gnu/stubs.h

5. gcc(glibc作成用)の作成

../configure \
--prefix=${CROSS} \
--target=${PPC64_TARGET} \
--with-headers=${CROSS}/include \
--enable-languages=c \
--disable-libmudflap \
--disable-libssp \
--disable-threads \
--disable-shared \
--disable-multilib \
--disable-biarch \
make all-gcc
make install
  • この時点で出来るgccはかなり不完全
    • 色々disableしてall-gccでコンパイルしないと通らない
  • make install時にエラーが出るが気にしない
  • 前のステップのファイル追加コピーを忘れていると,エラーになる
    • stubs.h等が足りないと言われる
    • 一度失敗するとファイルをそのあとでコピーしても失敗し続ける
    • make distcleanすべし

6. glibcの作成

ファイルの書き換え

// 書き換え前
static void
call_gmon_start(void)
// 書き換え後
static void __attribute__ ((noinline))
call_gmon_start(void)

make

CC=powerpc64-unknown-linux-gnu-gcc \
AR=powerpc64-unknown-linux-gnu-ar \
RANLIB=powerpc64-unknown-linux-gnu-ranlib \
ac_cv_type_long_double=no \
libc_cv_forced_unwind=yes \
libc_cv_c_cleanup=yes \
../configure --prefix=${CROSS} \
--host=${PPC64_TARGET} \
--with-headers=${CROSS}/${PPC64_TARGET}/include \
--with-tls \
--with-__thread \
--enable-thread \
--enable-add-ons \
--enable-kernel=2.6.18 \
--disable-sanity-checks \
--disable-multilib \
--disable-biarch \
make gnulib=-lgcc
make install
  • 最後まで通らなくても一回installする
    • この段階ではglibcのコアだけ出来ていれば良い
    • 次のステップ(gccのコンパイル)でリンクに失敗した場合,このステップでmakeに-iを付け手実行してみるとよい
      • '-i'は,エラーを無視して続行

7. フルglibc用GCCの作成その2

../configure \
--prefix=${CROSS} \
--target=${PPC64_TARGET} \
--with-headers=${CROSS}/include \
--with-libs=${CROSS}/lib \
--enable-languages=c \
--disable-multilib \
--disable-biarch \
--disable-libmudflap \
--disable-libssp \
--disable-libgomp
make 
make install
  • glibcのコアができたので,それを使ってgccを作る

  • 注意:glibcのコンパイルを行った後は,gccのコンパイル前に一度${CROSS}/${PPC64_TARGET}/libを削除すること

    • gccはconfigure時に${CROSS}/lib内のglibcを${CROSS}/${PPC64_TARGET}/libにコピーする
    • このコピーを行うかどうかは,${CROSS}/${PPC64_TARGET}のディレクトリが存在しているかどうかに依存している.
    • このため,glibcをコンパイルしても,${CROSS}/${PPC64_TARGET}/libを消しておかないと,コピーが行われず,新しいglibcがgccのコンパイルに使用されない

8. フルglibcの構築

  • 基本的に6と同じ
  • make時のgnulib=-lgccをはずしてmake

9. GCCの作成

7.1 gmp,mpfrの導入

  • gfortranのために必要

  • 双方はホスト側の環境に入れる必要がある

    • クロスコンパイラ内部で使用するためであり,ターゲットでリンクするためではない
  • gmp

../configure \
--prefix=${CROSS_HOST_LIB} \
make
make install
  • mpfr
../configure \
--prefix=${CROSS_HOST_LIB} \
--with-gmp=${CROSS_HOST_LIB} \
make
make install

8.2 gccのmake

CFLAGS="-O2 -static" \
../configure \
--prefix=${CROSS} \
--enable-languages=c,c++,fortran \
--target=${PPC64_TARGET} \
--enable-threads=posix \
--with-headers=${CROSS}/include \
--with-libs=${CROSS}/lib \
--with-gmp-include=${CROSS_HOST_LIB}/include \
--with-gmp-lib=${CROSS_HOST_LIB}/lib \
--with-mpfr-include=${CROSS_HOST_LIB}/include \
--with-mpfr-lib=${CROSS_HOST_LIB}/lib \
--disable-multilib \
--disable-biarch \
make 
make install
  • 最初のCFLAGS(-static)は,fortranのconfigureでうまくgmpをロードしてくれないため
    • システムにgmp,mpfrをインストールしてしまえば多分大丈夫
  • g++でhypotの二重定義エラーが出たら,以下のフラグを追加する
ac_cv_func_hypot=no \
glibcxx_cv_func_hypot_use=no \

使用プログラムのバージョンおよび備考

20070924

  • binutils-2.18
  • gcc-4.2.1
  • glibc-2.6.1
  • gmp-4.2.1
  • mpfr-2.2.1
  • kernel-headers-2.6.18-1.2798.fc6.ppc64.rpm

20080323

  • binutils-2.18
  • gcc-4.2.3
  • glibc-2.7
  • gmp-4.2.1
  • mpfr-2.2.1
  • kernel-headers-2.6.18-1.2798.fc6.ppc64.rpm

(文責:しおや)

Clone this wiki locally