zoukankan      html  css  js  c++  java
  • 再次编译 arm toolchains

    为什么说再呢,因为已经好多次了。每次失败,都再从失败的地方开始。今天这篇呢,主要是记录今天的进展。

    1. 编译要分三步走

    之前学习的时候就有印象,要三步走。但是因为没有实践过,所以,忘差不多了。所谓三步走,大概是这样的:

    1) 编译一个不需要 c 库的,静态编译的 gcc。

    2) 用上面做好的 gcc 编译 c 库。

    3) 使用做好的 c 库,编译完整的 gcc。

    所以,之前蹦哒蹦,过程都没搞清楚,就想一步把 gcc 给整出来。异想天开。所以,第一步,需要进行的,是编译“裸体”版本的 gcc。

    ../gcc-linaro-4.8-2014.04/configure --target=arm-linux-eabihf --prefix=/tmp/toolchains/ --without-headers --enable-languages=c --disable-threads --disable-shared -disable-decimal-float

    2. 针对 TARGET,编译并安装 binutils

    第一个重大进展,之前的可执行程序格式错误问题,得到解决。核心原因,并不是什么 gmp 没装。我觉的,这个完全就是给新手设置的一个障碍。第一个问题的症结,没有指定 binutils !

    之前也没有概念,要先编译 binutils 再编译 gcc。好吧,编译 binutils 挺顺利。

    ./configure --target=$TARGET --prefix=$PREFIX

    然后,make&&make install-strip

    TARGET 和 PREFIX 是提前做好的环境变量。 一个是工具链的前缀 arm-linux-eabihf ;一个是安装目录,我这里设置的是 /tmp/toolchains/ 。

    然后,我的编译配置就升级成了这样:

    ../gcc-linaro-4.8-2014.04/configure --target=arm-linux-eabihf --prefix=/tmp/toolchains/ --without-headers --enable-languages=c --disable-threads --disable-shared -disable-decimal-float --with-build-time-tools=/tmp/toolchains/arm-linux-eabihf/bin/

    嗯,带上它,就再也没有提醒过我,格式检查不对了。

    3. 编译并安装 linux-header

    因为大家说,linux-header 是在编译 libc 的时候才需要,所以并没有把 linux-header 当回事。随便放了个地方。

    按上面的配置编译 gcc,编译到一半,发现提示很多类型没定义,头文件找不到!这完全不能忍!然后看到了它在编译的时候,include 了这样一个目录:

    /tmp/toolchains/arm-linux-eabihf/include

    难道这就是 linux-header 该在的地方?不管了,先把它装这里再说:

    make ARCH=arm INSTALL_HDR_PATH=$TARGET_PREFIX headers_install

    TARGET_PREFIX 就是上面的 /tmp/toolchains/arm-linux-eabihf/ 。

    安装完,看到这里已经有 include 目录了。继续,再看看,还有啥毛病。

    ps:

    A. 2.6 以前的内核头文件,直接拷贝来就可以用的。但是 2.6 之后的内核头文件,需要用 make 来生成,它之抛出来一些可以给用户空间用的头文件,并不是全部。这样更加安全。

    B. 理论上来讲,使用哪个版本内核头文件编译的工具,就只能配合相应的内核使用,但是,事实上,内核的 ABI 并不是经常变动的(更确切说是,由 linux-header 描述的部分,很少变动),即使变动也是细小变动,所以,内核版本相近的话,使用通常是没有问题的。差的多,可能就有问题了,最近一次,内核版本 4.1 ,工具是用 2.6 的 header 制作的,制作了文件系统后,系统运行时,tslib 提示,input 的 versioncode 不一致;好在变化不大,手动修改 versioncode,编译成功,使用也暂时没出大问题。

    4. 关闭两个编译选项

    继续是上面头文件没有的问题,根据别人的经验,是因为没有 libc 的缘故,所以,需要关闭两个编译选项,也就是,在上面的 configure 选项中加上下面两条:

    --disable-libmudflap --disable-libssp

    重新配置,并再次尝试编译。感觉胜利的曙光就在前方,已经不自觉嘿嘿笑出了声。毕竟这是离胜利最近的一次了。

    ...

    坐等片刻,就真的编译好了 :)

    5. 编译 glibc

    选择的 glibc ,configure 的时候,它告诉我,需要至少 linux3.2 以上的头文件,所以,把之前用的 2. 6 的头文件给换掉了。

    使用的配置如下:

    CC=$newTools/arm-linux-eabihf-gcc AR=$newTools/arm-linux-eabihf-gcc-ar RANLIB=$newTools/arm-linux-eabihf-gcc-ranlib ../glibc-2.24/configure --host=arm-linux --prefix=/tmp/toolchains/arm-linux-eabihf/ --enable-add-ons --with-headers=/tmp/toolchains/arm-linux-eabihf/include --cache-file=config.cache --disable-profile

     编译提示是 crt0.o 文件不存在。搜索,没有发现有用信息,所以,准备通过加深对它的了解来解决这个问题。搜到以下内容:

    1. Crt ,是 C RunTime 的缩写
    2. 这是 ld 做链接的时候,固定的几个进口出口程序。是 libc 的入口。

     翻了几个编译器,在 toolchains/lib/gcc/arm-linux-eabihf/xxx-xxx 目录下,crt 的命名都不一样。我看到了下面这段。这是为什么?和工具的版本有关?

    Android bionic,这个C runtime library设计并不是功能特别强大,并且有些gnu glic中的函数没有实现,这是移植时会碰到的问题.而且,这个C runtime library也并没有采用crt0.o,crt1.o,crti.o crtn.o,crtbegin.o crtend.o,而是采用了android自己的crtbegin_dynamic.o, crtbegin_static.o 和crtend_android.o。crt1.o是crt0.o的后续演进版本,crt1.o中会非常重要的.init段和.fini段以及_start函数的入口..init段和.fini段实际上是靠crti.o以及crtn.o来实现的. 

    不过,又学到一招:

    $./arm-linux-eabihf-gcc -print-prog-name=ld
    /tmp/toolchains/lib/gcc/arm-linux-eabihf/5.2.1/../../../../arm-linux-eabihf/bin/ld

     在另外一个博客上,看到,使用 gcc -v hello.c ,可以看到 ld 的一些详细信息。用这个方法,从手上 arm-linux-gcc 看出:

    /opt/toolschain/4.4.3/bin/../libexec/gcc/arm-none-linux-gnueabi/4.4.3/collect2 --sysroot=/opt/toolschain/4.4.3/bin/../arm-none-linux-gnueabi//sys-root --eh-frame-hdr -dynamic-linker /lib/ld-linux.so.3 -X -m armelf_linux_eabi /opt/toolschain/4.4.3/bin/../arm-none-linux-gnueabi//sys-root/usr/lib/crt1.o /opt/toolschain/4.4.3/bin/../arm-none-linux-gnueabi//sys-root/usr/lib/crti.o /opt/toolschain/4.4.3/bin/../lib/gcc/arm-none-linux-gnueabi/4.4.3/crtbegin.o -L/opt/toolschain/4.4.3/bin/../lib/gcc/arm-none-linux-gnueabi/4.4.3 -L/opt/toolschain/4.4.3/bin/../lib/gcc -L/opt/toolschain/4.4.3/bin/../lib/gcc/arm-none-linux-gnueabi/4.4.3/../../../../arm-none-linux-gnueabi/lib -L/opt/toolschain/4.4.3/bin/../arm-none-linux-gnueabi//sys-root/lib -L/opt/toolschain/4.4.3/bin/../arm-none-linux-gnueabi//sys-root/usr/lib /tmp/ccgtP1Ex.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /opt/toolschain/4.4.3/bin/../lib/gcc/arm-none-linux-gnueabi/4.4.3/crtend.o /opt/toolschain/4.4.3/bin/../arm-none-linux-gnueabi//sys-root/usr/lib/crtn.o

     但是,从这里看, crtbegin.o 和 crtend.o 在编译器的默认安装目录下,而 crti.o , crtn.o , crt1.o 都是在 libc 的安装目录下啊。

     这个坑弃了,这里的编译错误,是因为 host=arm-linux 与前面的编译器前缀不一致,导致在编译过程中使用了错误的工具集导致的。但是,这个问题解决了,还会有另一个问题,还有后面很多问题...我尝试了另外一条顺一点的路线,先从那条路线多走走再回来找这里问题。所以这里就弃了。

    附录:

    1. <building embedded linux system> 的作者推荐了网站 www.cross-lfs.org ,但是过去是空的。搜索的时候,发现另外一个 lfs(linux-from-scratch)网站,可以作为参考。有空可以做个中文版的。网址:http://www.linuxfromscratch.org/

    小技巧1,使用 readelf 来查看工具信息:

    echo 'main(){}' > dummy.c
    gcc dummy.c
    readelf -l a.out | grep ': /tools'

     小技巧2,查看 ld 的搜索路径:

    ld --verbose|grep SEARCH

     小技巧3,查看 include 目录:

    $ g++ -E -x c++ - -v
    Using built-in specs.
    COLLECT_GCC=g++
    COLLECT_LTO_WRAPPER=/usr/lib/gcc/i686-linux-gnu/4.6/lto-wrapper
    Target: i686-linux-gnu
    Configured with: ../src/configure -v --with-pkgversion='Ubuntu/Linaro 4.6.3-1ubuntu5' --with-bugurl=file:///usr/share/doc/gcc-4.6/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.6 --enable-shared --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.6 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --enable-plugin --enable-objc-gc --enable-targets=all --disable-werror --with-arch-32=i686 --with-tune=generic --enable-checking=release --build=i686-linux-gnu --host=i686-linux-gnu --target=i686-linux-gnu
    Thread model: posix
    gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5) 
    COLLECT_GCC_OPTIONS='-E' '-v' '-shared-libgcc' '-mtune=generic' '-march=i686'
     /usr/lib/gcc/i686-linux-gnu/4.6/cc1plus -E -quiet -v -imultilib . -imultiarch i386-linux-gnu -D_GNU_SOURCE - -mtune=generic -march=i686 -fstack-protector
    ignoring nonexistent directory "/usr/local/include/i386-linux-gnu"
    ignoring nonexistent directory "/usr/lib/gcc/i686-linux-gnu/4.6/../../../../i686-linux-gnu/include"
    #include "..." search starts here:
    #include <...> search starts here:
     /usr/include/c++/4.6
     /usr/include/c++/4.6/i686-linux-gnu/.
     /usr/include/c++/4.6/backward
     /usr/lib/gcc/i686-linux-gnu/4.6/include
     /usr/local/include
     /usr/lib/gcc/i686-linux-gnu/4.6/include-fixed
     /usr/include/i386-linux-gnu
     /usr/include
    End of search list.
  • 相关阅读:
    开源TinyXML 最简单的新手教程
    2014第14周一开发问题记
    2014第13周日
    140329
    2014第13周五
    2014第13周四Webservice概念问题记
    2014第13周三
    2014第13周二
    2014第13周一
    2014第12周日
  • 原文地址:https://www.cnblogs.com/pied/p/6585699.html
Copyright © 2011-2022 走看看