首先,制作交叉工具鏈的目的是為了給我的手機--MOTO ROKR E2編譯程序。
然后,順便學習一下嵌入式軟件的開發
先說一下,搞這個需要很大的耐心。
我用的硬件是Sempron3100+, 512MB內存, 編譯環境是windowsXP + vmware5.5 + gentoo,
在CUI下,花了大概20個小時才編譯完(我從晚上八點一直弄到第二天下午四點
)。
1. 準備源碼:
binuitls-2.17
gcc-4.1.1
glibc-2.5
glibc-ports-2.5
以上都可以在gnu.org的ftp上下載
默認glibc不支持其它處理器, glibc-ports是支持其它處理器架構的補丁
另外還有kernel,我使用最新的2.19.1(kernel用于提供編譯頭文件)
2. 準備補丁:
這個可以在cross-lfs.org上面根據它的指南下載,我使用了下面的補丁:
Binutils Branch Update
Binutils Posix Patch
GCC Cross Search Paths Patch
GCC PR20425 Patch
GCC Posix Patch
Glibc Branch Update
Glibc Cross-Compiling Hacks Patch
Glibc Disable linking with libgcc_eh.a
Glibc Localedef Segfault
準備編譯環境,我直接使用的debian(sid)并且所有包都是最新狀態,另外需要安裝texinfo, gawk(注意mawk編譯glibc header時會有問題), bison, flex
4. 準備環境變量.我寫了一個pre.sh,所有相關內容都放里面
set +h #關閉bash的hash功能,hash功能用來記憶系統中所有可執行文件來避免查找path. 編譯時可能會增加新的同名可執行程序在其它目錄下
umask 022
export CLFS_HOST="$(echo $MACHTYPE | sed "s/$(echo $MACHTYPE | cut -d- -f2)/cross/")"
export CLFS_TARGET="arm-unknown-linux-gnu"
export CLFS=/home/lizl/arm
export LC_ALL=POSIX # 舊的libc2.2.4以下在LOCALE為其它時chroot回來可能會有異常
export PATH=$CLFS/bin:$PATH
# CFLAGS和CXXFLAGS對編譯時可能會有影響
unset CFLAGS
unset CXXFLAGS
5. 準備環境.執行source pre.sh后執行下面的操作:
install -dv ${CLFS} #創建目標目錄
install -dv ${CLFS}/include
install -dv ${CLFS}/usr/include
另外最好使用其它用戶身份去進行編譯的操作, 因為root可能會對系統造成破壞.建議創建一個clfs用戶和組專門操作(我是直接使用的root):
groupadd clfs #增加組
useradd -s /bin/bash -g clfs -m -k /dev/null clfs #創建用戶
passwd clfs #給用戶指定口令
chown -Rv clfs ${CLFS} #修改輸出目錄的權限
CLFS建議clfs帳號登錄時, 最好不要被系統中其它環境變量影響, 所以它在clfs帳號的~/.bash_profile里面寫入下面內容:
exec env -i HOME=${HOME} TERM=${TERM} PS1='\u:\w\$ ' /bin/bash
因為我是root, 沒有修改.
su - clfs #切換到clfs用戶執行操作
開始創建一些目錄. 這里我沒有創建, 因為我只需要gcc, binutils和glibc這三個
6. 編譯binutils:
下載binutils-2.17并解壓.
下載補丁:
注意安裝gcc bison flex texinfo
不然編譯過程會出錯
我編譯時報的錯是 missing makeinfo
然后安裝了texinfo還是不行
后面檢查makefile才發現bison等都沒有安裝
patch -Np1 -i ../patch/binutils-2.17-posix-1.patch
patch -Np1 -i ../patch/binutils-2.17-branch_update-1.patch
binutils建議編譯時在其它目錄編譯,所以我們創建binutils-build并在里面執行操作
mkdir -v ../binutils-build
cd ../binutils-build
如果你在binutils-2.17執行操作的話,那后面的make configure-host時可能會報錯
我因為報錯然后重做了一下干凈的解壓目錄重執行
開始配置
../binutils-2.17/configure --prefix=${CLFS} \
--host=${CLFS_HOST} --target=${CLFS_TARGET} --with-sysroot=${CLFS} \
--disable-nls --enable-shared --disable-multilib
檢查看主機上的運行條件是不是符合
make configure-host
編譯并安裝:
make
make install
cp -v ../binutils-2.17/include/libiberty.h ${CLFS}/usr/include
7. 安裝內核頭文件:
clfs中是直接復制目錄, 我則是先make menuconfig然后修改一此事配置后才復制的
clfs中操作:
install -dv ${CLFS}/usr/include
cp -av include/{asm-generic,linux,mtd,scsi,sound} ${CLFS}/usr/include
cp -av include/asm-arm ${CLFS}/usr/include/asm
我的操作:
make ARCH=arm CROSS_COMPILE=arm-linux- menuconfig
在menuconfig里面load一個別人的2410的配置然后退出并保存
cp -av include/{asm-generic,linux} ${CLFS}/usr/include
cp -av include/asm-arm ${CLFS}/usr/include/asm
8. 安裝glibc的頭文件.
先把3.4的依賴去掉
cd glibc-2.5
cp configure{,.orig}
sed -e 's/3.4/3.[0-9]/g' configure.orig > configure
然后解壓glibc-ports
tar -jxvf ../glibc-ports-2.5.tar.bz2
mv -v glibc-ports-2.5 ports
注意是解壓到當前目錄(glibc-2.5)下,不然執行后面的configure時會報cpu不支持
然后開始準備編譯目錄, 同上, 我們也在其它目錄下進行編譯
mkdir -v ../glibc-build
cd ../glibc-build
為打開NPTL支持進行如下操作:
echo "libc_cv_forced_unwind=yes" > config.cache
echo "libc_cv_c_cleanup=yes" >> config.cache
echo "libc_cv_arm_tls=yes" >> config.cache
然后把安裝路徑指定一下:
echo "install_root=${CLFS}" > configparms
再執行下面的編譯:
CC=gcc ../glibc-2.5/configure --prefix=/usr --host=${CLFS_TARGET} --build=${CLFS_HOST} --with-headers=${CLFS}/usr/include --cache-file=config.cache
make install-headers
由于awk語法兼容原因,如果安裝mawk的話上面的步驟會出錯, 安裝gawk則不會
有一些文件還沒有被自動復制過去, 需要手工復制:
install -dv ${CLFS}/usr/include/bits
cp -v bits/stdio_lim.h ${CLFS}/usr/include/bits
touch ${CLFS}/usr/include/gnu/stubs.h
cp -v ../glibc-2.5/ports/sysdeps/unix/sysv/linux/arm/nptl/bits/pthreadtypes.h \
${CLFS}/usr/include/bits
9. 安裝gcc第一次,這次是為了編譯交叉版本的glibc和gcc,先打補丁
patch -Np1 -i ../patch/gcc-4.1.1-posix-1.patch
patch -Np1 -i ../patch/gcc-4.1.1-cross_search_paths-1.patch
然后同樣創建編譯目錄并在里面進行編譯:
mkdir -v ../gcc-build
cd ../gcc-build
../gcc-4.1.1/configure --prefix=${CLFS} --host=${CLFS_HOST} --target=${CLFS_TARGET} --disable-multilib --with-sysroot=${CLFS} --disable-nls --disable-shared --enable-languages=c
make all-gcc
make install-gcc
10. 安裝glibc
在前面安裝glibc的頭時已經做了一些事情,如把port解壓. 現在做的先是給glibc打補丁:
cd glibc-2.5
patch -Np1 -i ../patch/glibc-2.5-libgcc_eh-2.patch
patch -Np1 -i ../patch/glibc-2.5-localedef_segfault-1.patch
patch -Np1 -i ../patch/glibc-2.5-cross_hacks-2.patch
patch -Np1 -i ../patch/glibc-2.5-branch_update-1.patch
然后創建編譯目錄并開始編譯:
cd ../glibc-build
rm -rf *
為支持NPTL做如下操作:
echo "libc_cv_forced_unwind=yes" > config.cache
echo "libc_cv_c_cleanup=yes" >> config.cache
指明安裝目錄:
echo "install_root=${CLFS}" > configparms
開始編譯:
BUILD_CC="gcc" CC="${CLFS_TARGET}-gcc" AR="${CLFS_TARGET}-ar" RANLIB="${CLFS_TARGET}-ranlib" ../glibc-2.5/configure --prefix=/usr --libexecdir=/usr/lib/glibc --host=${CLFS_TARGET} --build=${CLFS_HOST} --disable-profile --enable-add-ons --with-tls --enable-kernel=2.6.0 --with-__thread --with-binutils=${CLFS}/bin --with-headers=${CLFS}/usr/include --cache-file=config.cache
由于使用的是2.6.19的內核, 內核中使用了新的netlink接口, 把一些宏去掉了
參考maillist可知這些定義已經不在內核中使用, 但是應該還在用戶空間使用
CLFS中對最新內核的支持現在只到2.6.18.2
所以用2.6.19的需要自己修改一下:
修改目錄和文件為:
glibc-2.5/sysdeps/unix/sysv/linux# grep IFA * -l
check_pf.c
if_index.c
ifaddrs.c
在上面的文件中增加如下內容:
#include <linux/if_addr.h>
#define IFLA_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ifinfomsg))))
#define IFLA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct ifinfomsg))
#define IFA_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ifaddrmsg))))
#define IFA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct ifaddrmsg))
然后執行下面操作
make
make install
下面安裝locale, 如果想安裝全部locale的話可以執行下面的命令(時間比較長, 可能有半小時):
make localedata/install-locales
而如果你不想全裝, 只想裝某些locale那clfs推薦按下面命令執行:
mkdir -pv ${CLFS}/usr/lib/locale
export I18NPATH=${PWD}/localedata
export GCONV_PATH=${PWD}/iconvdata
export LOCALEDEF="${PWD}/locale/localedef-native --alias-file=../intl/locale.alias"
cd ../glibc-2.5/localedata
${LOCALEDEF} -i locales/de_DE -f charmaps/ISO-8859-1 --prefix=${CLFS} de_DE
${LOCALEDEF} -i locales/de_DE@euro -f charmaps/ISO-8859-15 --prefix=${CLFS} de_DE@euro
${LOCALEDEF} -i locales/en_HK -f charmaps/ISO-8859-1 --prefix=${CLFS} en_HK
${LOCALEDEF} -i locales/en_PH -f charmaps/ISO-8859-1 --prefix=${CLFS} en_PH
${LOCALEDEF} -i locales/en_US -f charmaps/ISO-8859-1 --prefix=${CLFS} en_US
${LOCALEDEF} -i locales/es_MX -f charmaps/ISO-8859-1 --prefix=${CLFS} es_MX
${LOCALEDEF} -i locales/fa_IR -f charmaps/UTF-8 --prefix=${CLFS} fa_IR
${LOCALEDEF} -i locales/fr_FR -f charmaps/ISO-8859-1 --prefix=${CLFS} fr_FR
${LOCALEDEF} -i locales/fr_FR@euro -f charmaps/ISO-8859-15 --prefix=${CLFS} fr_FR@euro
${LOCALEDEF} -i locales/it_IT -f charmaps/ISO-8859-1 --prefix=${CLFS} it_IT
${LOCALEDEF} -i locales/ja_JP -f charmaps/EUC-JP --prefix=${CLFS} ja_JP
unset I18NPATH GCONV_PATH LOCALEDEF
個人認為如果不想全裝, 直接修改一下localedata/Makefile,把不需要的locale去掉后再執行第一種方法可能更簡單. 這里我執行的是第一種方法.
11. 配置glibc運行信息
如果不配置的話glibc也會有默認配置, 但是在網絡環境下可能不正常. 所以需要配置一下.
用如下命令創建文件/etc/nsswitch.conf,當然直接編輯更快(直接編輯時把后面的EOF去掉):
cat > ${CLFS}/etc/nsswitch.conf << "EOF"
# Begin /etc/nsswitch.conf
passwd: files
group: files
shadow: files
hosts: files dns
networks: files
protocols: files
services: files
ethers: files
rpc: files
# End /etc/nsswitch.conf
EOF
然后用下面命令配置一下時區:
TZDIR="${CLFS}/usr/share/zoneinfo" ${CLFS}/usr/bin/tzselect
回答一些問題后, 使用下面命令保存timezone:
cp -v --remove-destination ${clfs}/usr/share/zoneinfo/[xxx] \
${clfs}/etc/localtime
[xxx]就是上面的結果.
我的結果是:
TZ='Asia/Shanghai'; export TZ
所以命令是:
cp -v --remove-destination ${clfs}/usr/share/zoneinfo/'Asia/Shanghai' ${clfs}/etc/localtime
12. 配置動態裝載器(如果你有庫文件放在/lib和/usr/lib外的其它目錄的話)
動態裝載器(/lib/ld-linux.so.2) 在/lib和/usr/lib目錄下查找程序需要的動態庫.
如果動態庫所在目錄不上上面兩個目錄下, 那需要把它的目錄寫到/etc/ld.so.conf中.
一般/usr/local/lib和/opt/lib目錄也需要查找.
如果你有動態庫放在這兩個目錄下的話, 做如下操作(我沒有所以不做):
cat > ${CLFS}/etc/ld.so.conf << "EOF"
# Begin /etc/ld.so.conf
/usr/local/lib
/opt/lib
# End /etc/ld.so.conf
EOF
13. 編譯gcc. 前面已經編譯過一次. 前面的編譯是為了創建交叉版本的glibc, 現在則是創建交叉版本的gcc.
先打補丁
cd gcc-4.1.1
patch -Np1 -i ../patch/gcc-4.1.1-posix-1.patch
patch -Np1 -i ../patch/gcc-4.1.1-PR20425-1.patch
patch -Np1 -i ../patch/gcc-4.1.1-cross_search_paths-1.patch
第一個和每三個前面都已經打過了, 所以這里只需要再打第二個就可以了
然后創建編譯目錄:
mkdir -v ../gcc-build
cd ../gcc-build
../gcc-4.1.1/configure --prefix=${CLFS} \
--host=${CLFS_HOST} --target=${CLFS_TARGET} --disable-multilib \
--with-sysroot=${CLFS} --disable-nls --enable-shared \
--enable-languages=c,c++ --enable-__cxa_atexit \
--enable-c99 --enable-long-long --enable-threads=posix
make
make install
14. 交叉編譯工具鏈已經做好,現在就小試一下牛刀,馬上來個Hello World
posted on 2008-02-10 16:18
幽幽 閱讀(1976)
評論(0) 編輯 收藏 引用 所屬分類:
Linux