zoukankan      html  css  js  c++  java
  • Armlinux GCC 交叉编译工具

    http://blog.csdn.net/ruixj/archive/2009/05/30/4225886.aspx

    Armlinux GCC 交叉编译工具可以通过以下方式获取:

    1. 通过现有GNU tools 编译GNU tools源码来获取交叉编译工具。这种方法需要对GNU tools各个源码之间的版本匹配。

    2.使用Dan Kegel开发的cross-tool脚本来编译源码。 现在这个脚本是0.43版本,2006后没有新的版本出来。

    3.在http://ftp.arm.linux.org.uk/pub/armlinux/toolchain/下载已经编译好的tools chains.

    4.http://www.handhelds.org/download/projects/toolchain/ 下载已经编译好的tool chains.

    5.http://www.denx.de/en/Software/WebHome 下载已经编译好的tool chains,他称之为ELDK.

       同时这家公司还是U-boot的开发者。

    6. http://blog.csdn.net/chenzhixin/archive/2007/01/12/1481442.aspx 通过LFS介绍的方法进行编译。

    <1>binutils: 目前(2009.05.31 )最新版本是GNU binutils is 2.19.1.

       要点:

    If you have GNU make, we recommend building in a different directory:
        mkdir objdir
        cd objdir
        ../binutils-XXX/configure [options]
        make
        make install
    This relies on the VPATH feature of GNU make.

    <2>gcc : 目前(2009.05.31 )最新版本是GCC-4.4.0

             From INSTALL in the gcc-4.4.0.tar.gz.

             从GCC-4.3起,安装GCC将依赖于GMP-4.1以上版本和MPFR-2.3.2以上版本。如果将这两个软件包分别解压到GCC源码树的根目录下, 并分别命名为"gmp"和"mpfr",那么GCC的编译程序将自动将两者与GCC一起编译。建议尽可能使用最新的GMP和MPFR版本。

    <3>linux kernel : 目前(2009.05.31 )最新版本是2.6.29。 从armlinux 网站可以得知,2.6.0以后的内核不需要到     armlinux网站上下载patch. 只需要在linux kernel org 上下载即可。

    <4>glibc: 目前(2009.05.31 )最新版本是2.10,可以使用git进行下载。2.9之前包括2.9可以使用http下载到tar包。

             相应的ports包为Glibc-ports-2.9(为了支持ARM).

    for compile: please see the readme and INSTALL in the tar glibc-2.9.tar.gz

    要点: 1. glibc2.4以上的版本需要2.6.16以上的LINUX内核版本。          FROM README

             2.推荐使用gcc 3.2以上的编译器来编译glibc.                             FROM FAQ

             3. 推荐使用GNU make version 3.79 or newer.                     FROM  FAQ

             4. For Linux or Hurd, you want binutils 2.13 or higher.      FROM  FAQ

             5. make 过程用到的其他软件:

                   * GNU gettext.

    * Perl 5 is needed if you wish to test an installation of GNU libc
      as the primary C library.

    +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

    宿主机的安装和配置:

    1.从http://fedoraproject.org/zh_CN/get-fedora下载

    可安装的Live CD 版本为fedora10

    2. 在vmware6.0中将live cd 安装到硬盘

    3. 此时 fedora中的开发工具并没有安装

       3.1安装yum软件管理工具

       3.2 yum install  gcc glibc-devel

            在Fedora中安装g++,使用命令:
            $ yum install gcc-c++
            yum install ncurses
             yum install ncurses-devel
             yum install ncurses-devel

       3.2 打开http://www.linuxfromscratch.org/lfs/view/development/chapter03/packages.html

        逐个安装上面网页中的各个软件。

    下载上面介绍的软件包

    <1>binutils-2.19.1.tar.bz2
    <2>linux-2.6.29.4.tar.bz2

    <3> GCC
    gcc-4.4.0.tar.gz
    gmp-4.3.1.tar.bz2
    mpfr-2.4.1.tar.gz

    <4>Glibc
    glibc-2.9.tar.bz2
    glibc-ports-2.9.tar.bz2
    glibc-2.9-arm_setjmp_fix-1.patch
    glibc-2.9-cross_hacks-2.patch
    glibc-2.9-libgcc_eh-1.patch
    glibc-2.9-localedef_segfault-1.patch
    glibc-2.9-nptl_lowlevellock-1.patch

    编译步骤

    step1: 创建目录和设定环境变量

    mkdir -p /opt/package/cross-tools/source

    mkdir -p /opt/package/cross-tools/build

    mkdir -p /opt/cross-tools

    export HOST=i686-pc-linux-gnu

    export TARGET=arm-rui-linux-gnueabi

    export PREFIX=/opt/cross-tools

    step2:将下载的软件包放到source目录中

    step3:编译binutils:

    cd /opt/package/cross-tools/source

    tar -jvxf binutils-2.19.1.tar.bz2

    cd /opt/package/cross-tools/build

    mkdir build-binutils

    cd build-binutils

    $../../source/ binutils-2.19.1/configure \
            --target=${TARGET} \
            --prefix=${PREFIX} \
            --disable-nls \
            --disable-werror \
            --disable-multilib \
            --enable-shared 

    make configure-host

    make

    make install

    选项详解

    --target=${TARGET}

    这个选项是跟--host一起表示编译生成的可执行文件运行在HOST上面,但这些可执行文件服务的对象是TARGET,也就是说用这些可执行文件连接和汇编出来的程序运行在TARGET上面。这里,默认就会使用主机的GCC编译器, 因此我们省略了--host选项。

    --prefix=${RESULT_DIR}

    告诉配置脚本当运行 make install 时把编译好的东西安装在RESULT_DIR目录。

    --disable-nls

    这里nls的意思是本地语言支持(Native Language Support)。可以禁止, 但是使能这一项也没问题。

    --disable-werror

    意思是禁止把警告当成错误。如果不加这一项,编译器会严格检查语法错误,出现警告也会停止编译,这样要想编译通过就很难了。所以禁止了werror,这样编译就可顺利完成。

    --disable-multilib

    禁止编译适用于多重目标体系的库。纯32位系统或纯64位系统都是NON-Multilib,但是如果有x64的U,想要既可以运行64bit的程序又可以运行32bit的程序,就得安装Multilib。

    --enable-shared

    编译出共享链接库。

    make configure-host

    检查主机环境以确保所有必须的工具都已经安装。这一个命令也可以去掉,不是必须的。

    编译和安装的结果

    这次是利用主系统(i386)的GCC工具链来完成编译的,编译出来的程序也是运行在i386上的 。编译得到的工具主要包括:

    · ld - GNU连接器the GNU linker.

    · as - GNU汇编器the GNU assembler.

    · addr2line - 把地址转换成文件名和所在的行数

    · ar - A utility for creating, modifying and extracting from archives.

    · c++filt - Filter to demangle encoded C++ symbols.

    · dlltool - Creates files for building and using DLLs.

    · gold - A new, faster, ELF only linker, still in beta test.

    · gprof - Displays profiling information.

    · nlmconv - Converts object code into an NLM.

    · nm - Lists symbols from object files.

    · objcopy - Copys and translates object files.

    · objdump - Displays information from object files.

    · ranlib - Generates an index to the contents of an archive.

    · readelf - Displays information from any ELF format object file.

    · size - Lists the section sizes of an object or archive file.

    · strings - Lists printable strings from files.

    · strip - Discards symbols.

    step4:制作linux内核头文件

        cd /opt/package/cross-tools/source

         tar -jvxf linux-2.6.29.4.tar.bz2

        make  \

          ARCH=arm  \

           CROSS_COMPILE=${TARGET}-  \

           INSTALL_HDR_PATH=${PREFIX}\${ TARGET}   \

           headers_install

    指定ARCH=arm表示拷贝对应于ARM体系结构的头文件。虽然其中指定了 CROSS_COMPILE, 而此时交叉编译器还没有生成,这没有关系,因为根本不会用到交叉编译器。

    step5: 编译静态gcc

    cd /opt/package/cross-tools/source

    tar -xzvf gcc-4.4.0.tar.gz

    tar -jvxf gmp-4.3.1.tar.bz2

    mv gmp-4.3.1 ./gcc-4.4.0/gmp

    tar -xzvf mpfr-2.4.1.tar.gz

    mv mpfr-2.4.1.tar.gz

    cd /opt/package/cross-tools/build

    mkdir build-gcc

    cd build-gcc

    ../../source/gcc-4.4.0/configure --build=${HOST} --host=${HOST} \

    --target=${TARGET} --prefix=${PREFIX} --without-headers \

    --with-newlib --with-float=soft --with-cpu=arm920t --with-tune=arm9tdmi \

    --with-gnu-as --with-gnu-ld --disable-nls --disable-decimal-float \

    --disable-libgomp --disable-multilib --disable-libmudflap --disable-libssp \

    --disable-shared --disable-threads --disable-libmudflap --disable-libstdcxx-pch \

    --disable-libffi --enable-languages=c

    make && make install

    step6:编译glibc

    export PATH= ${PREFIX /bin}:$PATH

    cd /opt/package/cross-tools/source

    tar -jxvf glibc-2.9.tar.bz2

    tar -jxvf glibc-ports-2.9.tar.bz2

    mv glibc-ports-2.9 ./glibc-2.9/ports

    cd glibc-2.9


    The Glibc build will expect to find libgcc_eh , but this library is not installed when GCC is built without "--enable-shared". As a result, the Glibc build will fail. The following patch will force Glibc to check for the existance of libgcc_eh and try to link to it only if it exists:

    patch -Np1 -i ../glibc-2.9-libgcc_eh-1.patch

    The following patch fixes an issue that can cause localdef to segfault:

    patch -Np1 -i ../glibc-2.9-localedef_segfault-1.patch

    The following patch builds zic-native , localedef-native , and rpcgen-native . zic-native is used to generate the zoneinfo, localedef-native is used to generate the locale archive, and rpcgen-native is used to generate part of librpcsvc.a . All of these programs would normally not be available when cross-compiling:

    patch -Np1 -i ../glibc-2.9-cross_hacks-2.patch

    The following patch adds a missing hidden alias for __sigsetjmp:

    patch -Np1 -i ../glibc-2.9-arm_setjmp_fix-1.patch

    The following patch adds a missing include that fixes a compilation error on arm.

    patch -Np1 -i ../glibc-2.9-nptl_lowlevellock-1.patch

    cd /opt/package/cross-tools/build

    mkdir build-glibc

    cd build-glibc

    为了使Glibc 支持NPTL ,需要在Glibc 编译目录下建立config.cache 文件并写入:

    cat > config.cache << EOF

    libc_cv_forced_unwind=yes

    libc_cv_c_cleanup=yes

    libc_cv_arm_tls=yes

    libc_cv_gnu89_inline=yes

    EOF

    BUILD_CC=gcc CC=${TARGET}-gcc AR=${TARGET}-ar RANLIB=${TARGET}-ranlib ../../source/glibc-2.9/configure --build=${HOST}  --host=${TARGET} --target=${TARGET} --prefix="/usr"  --with-headers=${PREFIX}/${TARGET}/include --with-binutils=${PREFIX}/bin  --with-tls  --with-__thread   --enable-sim  --enable-nptl --enable-add-ons  --enable-kernel=2.6.0   --disable-profile  --without-gd  --without-cvs  --cache-file=config.cache

    make

    make install_root=${PREFIX}/${TARGET} prefix="" install

    选项详解

    BUILD_CC="gcc"

    Glibc在编译过程中需要先创建一些工具,这些工具需要用主机上的GCC来编译。

    CC=${TARGET}-gcc

    告诉Glibc使用我们在上一步为ARM目标平台创建的交叉编译器GCC来编译C库。

    AR=${TARGET}-ar \

    告诉Glibc使用我们在上一步为ARM目标平台创建的ar来汇编C库。

    RANLIB=${TARGET}-ranlib

    告诉Glibc使用我们在上一步为ARM目标平台创建的ranlib

    -with-headers=${TARGET_PREFIX}/include \

       --with-binutils=${RESULT_DIR}/bin

    This tells Glibc to use the Binutils that are specific to our target architecture.

       --with-tls

    This tells Glibc to use Thread Local Storage.

       --with-__thread

    This tells Glibc to use use the __thread for libc and libpthread builds.

       --enable-sim \

       --enable-nptl \

       --enable-add-ons

    This tells Glibc to utilize all add-ons that are available.

       --enable-kernel=2.6.0 \

       --disable-profile

    This builds the libraries without profiling information. Omit this option if profiling on the temporary tools is necessary.

       --without-gd \

       --without-cvs \

       --cache-file=config.cache

    This tells Glibc to utilize a premade cache file.

    对 libc.so 的修正·

    vi $PREFIX /${TARGET}/lib/libc.so

    去掉绝对路径,修改后的内容如下:

    /* GNU ld script

        Use the shared library, but some functions are only in

        the static library, so try that secondarily. */

    OUTPUT_FORMAT(elf32-littlearm)

    GROUP ( libc.so.6 libc_nonshared.a AS_NEEDED ( ld-linux.so.3 ) )

    step7 编译完整的gcc

    cd /opt/package/cross-tools/build/build-gcc

    rm -rf *

    ../../source/gcc-4.4.0/configure --build=${HOST}  --host=${HOST}  --target=${TARGET} --prefix=${PREFIX} --with-float=soft  --with-cpu=arm920t  --with-tune=arm9tdmi  --enable-languages=c,c++  --enable-threads=posix  --enable-c99  --enable-long-long  --enable-shared  --enable-__cxa_atexit  --enable-nls  --disable-libgomp

    make

    make install

    选项详解

    -enable-languages=c,c++

    This option ensures that only the C and C++ compilers are built.

    --enable-__cxa_atexit

    This option allows use of __cxa_atexit, rather than atexit, to register C++ destructors for local statics and global objects and is essential for fully standards-compliant handling of destructors. It also affects the C++ ABI and therefore results in C++ shared libraries and C++ programs that are interoperable with other Linux distributions.

    --enable-c99

    Enable C99 support for C programs.

    --enable-long-long

    Enables long long support in the compiler.

    --enable-threads=posix

    This enables C++ exception handling for multi-threaded code.

    --enable-nls \

    --disable-libgomp

    如果不加这一项会出现如下错误:

    configure: error: Pthreads are required to build libgomp
    make[1]: *** [configure-target-libgomp] 错误 1
    make[1]: 正在离开目录 `/home/hongwang/mktoolchain/build/gcc-4.4.0-2'
    make: *** [all] 错误 2
    没有找到好的解决办法,只能在configure 里增加 --disable-libgomp

    为什么要编译两次 GCC

    第一遍只编译一个支持c 的gcc ,原因是要编译出一个支持交叉的c++ ,必须有一个编译好的用于目标体系平台的glibc ,而不是只有glibc 的头文件就可以的,好在编译glibc 有c 支持就够了,所以编译glibc 也成了第一遍的gcc 唯一的理由和作用。工具链中gcc 的第一次和第二次编译都是由主系统的gcc 和binutils 来完成的(之前没有提及binutils ,只是为了理解方便,但实际上编译后是少不了链接过程的,这个过程是要binutils 来完成的)。到目前为止只有在编译glibc 的时候用到了交叉版本的binutils ,其它部分的链接都是由主系统的binutils 来完成的。

    step8 测试交叉编译工具链

    到此为止,已经介绍完了用分步构建的方法建立交叉编译工具链。下面通过一个简单的程序测试刚刚建立的交叉编译工具链看是否能够正常工作。写一个最简单的hello.c源文件,内容如下:

    #include <stdio.h>

    int main( )

    {

         printf(“Hello,world!\n”);

         return 0;

    }

    通 过以下命令进行编译,编译后生成名为hello的可执行文件,通过file命令可以查看文件的类型。当显示以下信息时表明交叉工具链正常安装了,通过编译 生成了ARM体系可执行的文件。注意,通过该交叉编译链编译的可执行文件只能在ARM体系下执行,不能在基于X86的普通PC上执行。

    # arm-rui-linux-gcc –o hello hello.c

    # file hello

    hello: ELF 32-bit LSB executable, ARM, version 1 (ARM), for GNU/Linux 2.4.3,

    dynamically linked (uses shared libs), not stripped


    参考文章:
      http://hi.baidu.com/mynana/blog/item/479eb25183ec2210377abee0.html
    http://cross-lfs.org/view/clfs-sysroot/arm/cross-tools/linux-headers.html
    http://blog.csdn.net/chenzhixin/archive/2007/01/12/1481442.aspx
  • 相关阅读:
    存储用户当前的地理坐标,不要用string ,直接用float即可。string无法保持数据,原因暂不明
    让百度地图只再应用程序启动时,仅取一次用户坐标信息
    ygm900常用网站
    重置一个画面大小的方法
    代码的世界中,一个逻辑套着另外一个逻辑,如何让每一种逻辑在代码中都有迹可循?
    Multiview Applications(多个xib之前的切换) view controller和xib文件是如何关联在一起的 (手动关联 view controller和xib文件)
    一键让应用程序适配 iphone5
    UISCrollView 与 UIPageControl 之间产生联系,就靠这句代码pageControl0.currentPage = page;
    集中“验证”的思想
    静听夜雨
  • 原文地址:https://www.cnblogs.com/leaven/p/1878074.html
Copyright © 2011-2022 走看看