首先,制作交叉工具链的目的是为了给我的手机--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
幽幽 阅读(1968)
评论(0) 编辑 收藏 引用 所属分类:
Linux