close

先聲明,這不是教學,只是將個人見聞記錄下來,希望對其他人有用,也希望有高手能針對錯誤的地方 給予指正,沒有經驗的人應該先去找個真正的教學來看。

這裡以 MinGW 4.5 建置其他 GCC 4.x toolchain 為範例,GCC 3.x 雖然步驟差不多,但有些小地方應 該要修改。我選的 target 是 arm-elf,因為我對這個比較熟,其他目標有的需要 target system header 比較麻煩。

msys 需求
* 基本必備安裝
* Autotools 及其所有相依套件
* flex 和 bison

MinGW 需求
* 基本必備安裝
* gmp、mpc、mpfr、pthread 這四者的 dll 和 dev 套件。

這裡所使用的 source 版本:
* binutils-2.20.1
* newlib-1.18.0
* gcc-core-4.2.2
* gcc-g++-4.2.2

並非任何版本的 binutils + gcc + lib 搭配都保證可以建起來,也不是每個版本的 MinGW 都會得到幸 福快樂的結局,遇到障礙要想辦法手工排除。

有網友對於該用 msys-gcc 還是 mingw build 有疑問,我的建議是只要用 mingw build 就好。msys gcc 產出的東西就只能依賴 msys 執行,而 mingw 建出來的東西既可以在 msys 下用,也可以當一般的 windows 程式。

我將原始碼放在 msys 的 /home/gcc-src,而目的在 /cross-gcc/arm-elf。以下是建置用的 shell:

binutils


TARGET_NAME=arm-elf
INS_DIR=/cross-gcc/$TARGET_NAME
SRC_DIR=/home/gcc-src/binutils-2.20.1

export CFLAGS='-O2 -pipe'
export CXXFLAGS='-O2 -pipe'
export LDFLAGS='-s'

mkdir -p working/binutils
cd working/binutils

${SRC_DIR}/configure --prefix=$INS_DIR --target=$TARGET_NAME \
    --with-sysroot=$INS_DIR \
    --disable-nls --disable-shared --disable-threads \
    --enable-interwork --enable-multilib \
    2>&1 | tee _configure.log

make all 2>&1 | tee _make.log
make install 2>&1 | tee _install.log

gcc first pass


TARGET_NAME=arm-elf
SRC_DIR=../../gcc-4.2.2
INS_DIR=/cross-gcc/$TARGET_NAME

export PATH=${PATH}:/cross-gcc/arm-elf/bin

export CFLAGS='-O2 -pipe'
export CXXFLAGS='-O2 -pipe'
export LDFLAGS='-s'

mkdir -p working/gcc; cd working/gcc

$SRC_DIR/configure --target=$TARGET_NAME --prefix=$INS_DIR  \
    --enable-languages=c --enable-interwork --enable-multilib \
    --disable-nls --disable-shared --disable-threads --disable-win32-registry \
    --disable-libmudflap --disable-libssp --disable-libgomp \
    --with-newlib \
    --with-sysroot=$INS_DIR \
    2>&1 | tee _configure.log

make all-gcc | tee _make.log 2>&1
make install-gcc | tee _install.log 2>&1

newlib


TARGET_NAME=arm-elf
SRC_DIR=/home/gcc-src/newlib-1.18.0
INS_DIR=/cross-gcc/$TARGET_NAME

export PATH=${PATH}:/cross-gcc/arm-elf/bin

export CFLAGS='-O2 -pipe'
export CXXFLAGS='-O2 -pipe'

mkdir -p working/newlib
cd working/newlib

$SRC_DIR/configure --target=$TARGET_NAME --prefix=$INS_DIR \
    2>&1 | tee _configure.log

make all 2>&1 | tee _make.log
make install 2>&1 | tee _install.log

gcc second pass 和 first pass 差不多,可以加上其他所需的語言,然後 make all、make install即可。

障礙排除:

1. 通常遇到的都是找不到檔案,這點請根據錯誤訊息判斷哪個檔案該出現在哪裡,找出來然後手工複製 到正確的地方。

2. 找不到檔案有一個比較特別的 case 發生在 libstd c++ v3 幾個 header 上,因為名字太長以及 tar 的 bug 所以會解出錯誤的檔名。這件事會不會發生和你用來解壓source的軟體有很大的關係。(別問我 是哪幾個檔案,我也忘了)

3. 如果遇到 cc1.exe out of memory allocating..... 的訊息,請看看工作資料夾裡面有沒有叫做 insn-modes.h 和 insn-modes.c 的檔案,然後看一下檔案大小。我沒記錯的話 arm 是 2GB 而 mips 是 3GB,檔案裡面大多的字元是無用的空格..... 正常的話這兩個檔案大小都只有數十 kb,但有時候會因為某個有點奇怪的理由變成超級怪獸。

解法之一是用軟體工具將不必要的空格給消掉,然後繼續 make。另一個解法是,由於這是由 genmodes.exe 自動產生的 code,所以找一下 gcc 資料夾下的 genmodes.c,把 tagged_printf 改成:


#define tagged_printf(FMT, ARG, TAG) do { \
    int count_ = printf (" " FMT ",", ARG); \
} while (0)


4. 如果 configure 錯誤或更改 configure 選項,請先將舊工作資料夾砍掉再重新 configure。一般來說 make的小錯誤可以不必重新 configure 直接重 make 即可,make 會自動跳過不必更新的檔案。

arrow
arrow
    全站熱搜
    創作者介紹
    創作者 novus 的頭像
    novus

    novus log

    novus 發表在 痞客邦 留言(1) 人氣()