原文地址:http://blog.csdn.net/chehlcy/article/details/5456118(本人經過整理修改,並且對可能出現的問題給出解決方案)
製作交叉編譯工具鏈是件麻煩的事情,因為交叉編譯ntfsprogs不得已從頭做了一遍,現在把流程總結在這裡,供以後參考。
原料:binutils,gcc,linux kernel,uclibc
我所用的版本為:
binutils-2.16
gcc-3.4.3
linux-2.6.14
uClibc-0.9.28
基本流程:
1.編譯binutils
2.編譯不含庫的gcc
3.配置編譯linux kenerl
4.編譯uclibc
5.重新編譯gcc得到完整工具鏈。
詳細步驟:
註:以下指令碼都是手工再次錄入,非copy自原系統,可能存在錄入錯誤
1.binutils的編譯
沒有什麼懸念,編譯指令碼如下:
#。/bin/sh
./configure --target=arm-linux --prefix=/opt/tools --program-prefix=arm-linux-
make
make install
即可在/opt/tools 下產生arm-linux-ar arm-linux-ld等必須工具
2.編譯不含庫的gcc
該步驟必須小心配置,因為編譯gcc某些功能模組時本身需要C庫的支援,只有把這些有依賴的模組屏蔽掉該步驟才能順利編譯,該步驟編譯指令碼如下:
具體可以參見:http://blog.csdn.net/dragon101788/article/details/17559215第四節
#。/bin/sh
./configure --target=arm-linux /
--prefix=/opt/tools /
--program-prefix=arm-linux- /
--disable-shared /
--disable-threads /
--enable-languages="c" /
--with-newlib
make
make install
部分書籍說要修改t-linux檔案,本人測試只要加上--with-newlib即可避免。
3.配置編譯linux kernel
具體可以參見:http://blog.csdn.net/dragon101788/article/details/17559215第五節
該步驟是為了得到C庫中的系統標頭檔,在編譯uClibc的時候會指定kernel src的位置,這一步雖然只需配置好核心並將include/asm 連結到asm-arm即可,但為了順便測試第2步編譯的gcc,不妨完整的編譯核心。具體配置取決於所使用的核心,此步驟無需羅嗦。
4.配置編譯uClibc
在該步驟中需要指定kernel src的位置,個人嘗試必須指定為絕對路徑,相對路徑編譯過程會出錯,配置過程中需根據系統需要對uClibc進行配置,有時還會出現部分模組編譯不通過,此時則需要做相應配置調整。該步驟完成後可產生完整工具鏈所需的標頭檔和庫檔案。
menuconfig設定:
arget Architecture (arm) --->
Target Architecture Features and Options --->
Target ABI (EABI) --->
Target Processor Type (Generic Arm) --->
*** Using ELF file format ***
Target Processor Endianness (Little Endian) --->
[*] Target CPU has a memory management unit (MMU)
[*] Do you want to utilize the MMU?
[*] Enable floating point number support
[*] Target CPU has a floating point unit (FPU)
[ ] Enable full C99 math library support
[ ] Enable C99 Floating-point environment
(${PREFIX}/${TARGET}/include) Linux kernel header location
Library Installation Options --->
($(RUNTIME_PREFIX)lib) Shared library loader path
(/${TARGET}/uClibc) uClibc runtime library directory :註:此項如若填寫,每次編譯時間會從指定目錄尋找ulibc.so,如若沒有填寫,從預設載入路徑,推薦留空
(/uClibc-dev) uClibc development environment directory :註:此項如若填寫,每次編譯時間會從指定目錄尋找ulibc.so,如若沒有填寫,從預設載入路徑,推薦留空
修改.config中的交叉編譯路徑 或者修改環境變數CROSS=
CROSS_COMPILER_PREFIX="arm-linux-gnueabi-"
安裝時使用命令
make PREFIX=${PWD}/hu/ install
編譯完成安裝之後將hu目錄下所有檔案拷貝到${PREFIX}/${TARGET}目錄
註:如果menu時使用目錄有填寫的話安裝時會出現在配置目錄
編譯中可能會遇到的問題:
問題1:
libc/sysdeps/linux/mips/crt1.S: Assembler messages:
libc/sysdeps/linux/mips/crt1.S:117: Warning: No .cprestore pseudo-op used in PIC code
AS lib/crti.o
AS lib/crtn.o
/tmp/cc5bCHrL.s: Assembler messages:
/tmp/cc5bCHrL.s: Error: .size expression for _init does not evaluate to a constant
/tmp/cc5bCHrL.s: Error: .size expression for _fini does not evaluate to a constant
make: *** [lib/crtn.o] Error 1
解決方案:
Got the thing resolved as said in the patch by removing the lines
.size _init, .-_init
.size _fini, .-_fini
from uClibc-0.9.31/libc/sysdeps/linux/arm/crtn.S
在uClibc-0.9.31/libc/sysdeps/linux/arm/crtn.S檔案中,@注掉這兩行
問題2:
錯誤:651: note: previous declaration of ‘getline’ was here
error: conflicting types for ‘getline’
651: note: previous declaration of ‘getline’ was here
pattern.c: In function ‘getline’:
解決:getline和系統定義的getline()函數衝突。把名字改一下就好了。
5.重新編譯GCC
此步驟是為了在已經擁有C庫的基礎上開啟第一遍編譯gcc時限定的功能,包括動態連結支援,線程支援等,以及C庫的整合。
編譯指令碼如下:
#。/bin/sh
./configure --target=arm-linux /
--prefix=/opt/tools /
--program-prefix=arm-linux- /
--enable-languages="c" /
--with-headers=../uClibc-0.9.28/build/include / #註:此處加上編譯出現問題
--with-libs=../uClibc-0.9.28/build/lib / #註:此處加上編譯出現問題
--with-sysroot='${exec_prefix}/xxx' #將xxx替換成prefix的路徑,參照http://blog.csdn.net/dragon101788/article/details/17509987sysroot與specs
make
make install
可能會出現問題:
/home/dragon/usr/arm/dragon-4.8.2/arm-uclibc-linux-gnueabi/bin/ld: cannot find /lib/libc.so.0
/home/dragon/usr/arm/dragon-4.8.2/arm-uclibc-linux-gnueabi/bin/ld: cannot find /lib/uclibc_nonshared.a
/home/dragon/usr/arm/dragon-4.8.2/arm-uclibc-linux-gnueabi/bin/ld: cannot find /lib/ld-uClibc.so.0
collect2: error: ld returned 1 exit status
這進過研究這是uclibc連結中指向了錯誤的根目錄下/lib/libc.so.0
實際是$PREFIX/$TARGET/lib/libc.so的指向,libc.so其實是一個文字檔指向這編譯時間連結的位置,當編譯器移動位置時出現同樣的問題,後期可以通過修改這個檔案來移動目錄,ulibc編譯器目錄移動時指定一個絕對路徑
其中--with-headers指定剛才編譯產生的uClibc的標頭檔,--with-libs指定uClibc的庫檔案,本例中只支援c程式的編譯。
不出意外的話,一個arm-linux的交叉編譯工具鏈就完成了,在這個流程順利通過的基礎上,可以再配置的其它參數以達到效能最優。不過,第一次編譯工具鏈幾乎不可能一次成功。