自己动手创建交叉工具链

自己动手创建交叉工具链
首先,制作交叉工具链的目的是为了给我的手机--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

自己动手创建交叉工具链_第1张图片

你可能感兴趣的:(自己动手创建交叉工具链)