Chinaunix首页 | 论坛 | 博客
  • 博客访问: 410062
  • 博文数量: 82
  • 博客积分: 2600
  • 博客等级: 少校
  • 技术积分: 961
  • 用 户 组: 普通用户
  • 注册时间: 2010-03-08 21:44
文章分类
文章存档

2013年(2)

2012年(56)

2010年(24)

我的朋友

分类:

2012-04-29 10:49:50

前些日子,为自己的ARM11开发版做了一套交叉编译工具,整理与此,以备后用!


交叉编译工具链是一套在宿主机上生成目标机目标代码的编译链接工具集。
由上可知:

1. 交叉编译工具链是一套编译链接工具。
2. 交叉编译工具链运行于宿主机.
3. 交叉编译工具链生成的是目标机的目标代码,而非宿主机的目标代码。


一套完整的编译工具不仅仅有编译链接工具,还需相应的C库支持。所以,
交叉编译工具链的制作主要由三个步骤构成:

1. 制作一套简单的交叉编译工具。
    利用本地工具(gcc, binutils 等), 生成一套简单的交叉编译工具,此工
    具只能编译纯净(不涉及C库)的C源码。
2. 制作一套用于目标机的C库。
    借用第一步生成的编译工具(gcc)与本地工具(binutils 等),生成与目标
    机匹配的C库。
3. 制作一套完整的交叉编译工具。
    借用本地工具(gcc, binutils 等),结合步骤2生成的C库。生成一套完整的
    交叉编译工具链。


在以上三个步骤开始前,还有一步准备工作:环境搭建--相关目录的创建,源码准备,
相关本地工具的安装等。

本地环境:

        Linux 3.0.0-16-generic #29-Ubuntu SMP Tue Feb 14 12:49:42 UTC 2012 i686 i686 i386 GNU/Linux


目录结构:

    TOP_DIR--|-BUILD_DIR   制作Toolchain的工作目录
         |-UTILS_DIR   Host端相关工具的安装目录
         |-SOURCE_DIR  源码目录
         |-SYSROOT_DIR 根目录

源码版本:
    binutils-2.22
    gcc-4.7.0
    glibc-2.15
    glibc-ports-2.15
    linux-3.2.12

    gmp-5.0.4
    mpfr-3.1.0
    mpc-0.9
    m4-1.4.16
    autoconf-2.68
    gettext-0.18.1.1
    gawk-4.0.1
    ncurses-5.9
    texinfo-4.13

一.环境搭建

    //定制变量
    BUILD_PLAT="$(gcc -dumpmachine)"
    TARGET_PLAT="arm-efeng-linux-gnueabi"

    TOP_DIR="${HOME}/arm_toolchain_build"
    BUILD_DIR="${TOP_DIR}/build"
    UTILS_DIR="${TOP_DIR}/utils"
    SOURCE_DIR="${TOP_DIR}/source"
    SYSROOT_DIR="${TOP_DIR}/sysroot"

    //创建目录
    mkdir -p ${BUILD_DIR} ${UTILS_DIR} ${SOURCE_DIR} ${SYSROOT_DIR}

    //安装工具
    把所有相关的源码都解压到SOURCE_DIR目录下。
    把除gcc, glibc, glibc-ports, linux 之外的所需工具编译安装到UTILS_DIR
    目录下。例如: binutils.

    cd ${BUILD_DIR}
    mkdir binutils-2.22
    cd binutils-2.22
    ${SOURCE_DIR}/binutils-2.22/configure --prefix=${UTILS_DIR} || exit 1
    make && make install

    //导出环境
    export PATH=${PATH}:${SYSROOT_DIR}/usr/bin
    echo $PATH >> ${HOME}/.bashrc
    export PATH=${UTILS_DIR}/bin:${PATH}

二. 第一次编译GCC.
    cd ${BUILD_DIR}
    //gcc 编译时会查找/usr/include目录,若目录不存在会报错并终止编译。
    mkdir gcc-4.7.0_1 ${SYSROOT_DIR}/usr/include
    cd gcc-4.7.0_1

    CFLAGS='-Dinhibit_libc' \
    ${SOURCE_DIR}/${GCC_PKG}/configure \
        --prefix=/usr \
        --build=${BUILD_PLAT} \
        --host=${BUILD_PLAT} \
         --target=${TARGET_PLAT} \
        --with-sysroot=${SYSROOT_DIR} \
        --with-gmp=${UTILS_DIR} \
        --with-mpfr=${UTILS_DIR} \
        --with-mpc=${UTILS_DIR} \
        --without-headers \
        --disable-libgomp \
        --disable-libmudflap \
        --disable-libssp \
        --disable-multilib \
        --disable-libquadmath \
        --disable-threads \
        --disable-shared \
        --enable-languages=c \
        || exit 1
    
    make && make DESTDIR=${SYSROOT} install

三. 编译GLIBC
    cd ${SOURCE_DIR}
    //下面的两个补丁用于解决编译过程中的错误,补丁附在文章的最后,请手动在
    //SOURCE_DIR下创建这两个文件,并把相应内容拷入。
    patch -p0 < glibc-2.15-libgcc_eh.patch
    patch -p0 < glibc-ports-2.15-__aeabi_read_tp.path
    //把glibc-ports-2.15 拷贝到glibc-2.15目录下,并命名为ports.
    mv ${SOURCE_DIR}/glibc-ports-2.15 ${SOURCE_DIR}/glibc-2.15/ports
    //glibc 的编译需要linux头文件, 先安装头文件。
    cd ${SOURCE_DIR}/linux-3.2.12
    make ARCH=arm INSTALL_HDR_PATH=${SYSROOT_DIR}/usr headers_install

    //创建glibc build 目录。    
    mkdir -p ${BUILD_DIR}/glibc-2.15
    cd ${BUILD_DIR}/glibc-2.15
    
    libc_cv_c_cleanup=yes \
    libc_cv_forced_unwind=yes \
    libc_cv_ctors_header=no \
    CC="${TARGET_PLAT}-gcc" \
    AR="${TARGET_PLAT}-ar" \
    RANLIB="${TARGET_PLAT}-ranlib" \
    ${SOURCE_DIR}/${GLIBC_PKG}/configure \
        --prefix=/usr \
        --build=${BUILD_PLAT} \
        --host=${TARGET_PLAT} \
        --disable-profile \
        --enable-add-ons \
        --enable-kernel=3.2.12 \
        --with-threads=posix \
        --with-binutils=${SYSROOT_DIR}/usr/bin \
        --with-headers=${SYSROOT_DIR}/usr/include \
        || exit 1
    
    make && make DESTDIR=${SYSROOT_DIR} install
    
四. 第二次编译GCC.
    mkdir -p ${BUILD_DIR}/gcc-4.7.0_2
    cd ${BUILD_DIR}/gcc-4.7.0_2
    
    target_cpu=arm1176zjf-s \
    ${SOURCE_DIR}/${GCC_PKG}/configure \
        --prefix=/usr \
        --build=${BUILD_PLAT} \
        --host=${BUILD_PLAT} \
         --target=${TARGET_PLAT} \
        --with-sysroot=${SYSROOT_DIR} \
        --with-gmp=${UTILS_DIR} \
        --with-mpfr=${UTILS_DIR} \
        --with-mpc=${UTILS_DIR} \
        --enable-languages=c,c++ \
        || exit 1
    
    make AS_FOR_TARGET=${TARGET_PLAT}-as LD_FOR_TARGET=${TARGET_PLAT}-ld \
    && make DESTDIR=${SYSROOT_DIR} install

附录:

glibc相关的两个补丁,“/////” 中的内容为补丁正文,。

glibc-2.15-libgcc_eh.patch
/////////////////////////////////////////////////////////////////////////////////////////    
--- glibc-2.15/Makeconfig    2012-01-01 20:16:32.000000000 +0800
+++ glibc-2.15/Makeconfig.new    2012-04-13 10:17:26.148701847 +0800
@@ -563,12 +563,12 @@
   libunwind = -lunwind
 endif
 ifneq ($(have-as-needed),yes)
- libgcc_eh := -lgcc_eh $(libunwind)
+ libgcc_eh :=  $(libunwind)
 else
  libgcc_eh := -Wl,--as-needed -lgcc_s$(libgcc_s_suffix) $(libunwind) -Wl,--no-as-needed
 endif
 gnulib := -lgcc $(libgcc_eh)
-static-gnulib := -lgcc -lgcc_eh $(libunwind)
+static-gnulib := -lgcc  $(libunwind)
 libc.so-gnulib := -lgcc
 endif
 ifeq ($(elf),yes)

/////////////////////////////////////////////////////////////////////////////////////////    

glibc-ports-2.15-__aeabi_read_tp.patch
/////////////////////////////////////////////////////////////////////////////////////////    
--- glibc-ports-2.15/sysdeps/arm/Makefile    2011-12-24 03:34:10.000000000 +0800
+++ glibc-ports-2.15/sysdeps/arm/Makefile.new    2012-04-13 10:31:24.076856942 +0800
@@ -7,3 +7,8 @@
 ifeq ($(subdir),csu)
 gen-as-const-headers += tlsdesc.sym
 endif
+
+### To pull in __aeabi_read_tp, needed for tls
+ifeq ($(subdir),malloc)
+$(objpfx)libmemusage.so: $(common-objpfx)libc_nonshared.a
+endif

/////////////////////////////////////////////////////////////////////////////////////////    

阅读(3435) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~