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

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 文件不存在。搜索,没有发现有用信息,所以,准备通过加深对它的了解来解决这个问题。搜到以下内容:

. Crt ,是 C RunTime 的缩写
. 这是 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./../../../../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. (Ubuntu/Linaro 4.6.-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.

再次编译 arm toolchains的更多相关文章

  1. mac上编译 arm linux gnueabi交叉编译工具链toolchain

    crosstool-ng 编译和安装 交叉编译工具下载: git clone git@github.com:secularbird/crosstool-ng.git   切换到mac编译分支 git ...

  2. DM8168 OpenCV尝试与评估(编译ARM版OpenCV)

     交叉编译opencv2.3.1,并在DM8168 cortex A8中执行图像处理. 开发环境: PC:ubuntu12.04LTS.Intel Core 2 Duo CPU  E7200@2. ...

  3. win10下ndk编译arm可执行体

    编译参考文章 http://blog.csdn.net/john_1984/article/details/12622215 一.编写soLoader主文件 soLoader.c内容: #includ ...

  4. 从头编译ARM交叉编译环境

    首先Cygwin需安装基本的命令 例如make binutils gcc 还有diffutils 没有他会报找不到cmp命令 这些都可以在setup.exe中找到 编译gcc时,需要注意一个原则:不要 ...

  5. VS2005混合编译ARM汇编代码-转

    原文地址:http://blog.csdn.net/annelcf/article/details/5468093 公司HW team有人希望可以给他们写一个在WinCE上,单独读写DDR的工具,以方 ...

  6. ARMCC和GCC编译ARM代码的软浮点和硬浮点问题 【转】

    转自:http://houh-1984.blog.163.com/blog/static/31127834201211112129167/ 本文介绍了ARM代码编译时的软浮点(soft-float)和 ...

  7. ARMCC和GCC编译ARM代码的软浮点和硬浮点问题【转】

    转自:https://blog.csdn.net/hunanchenxingyu/article/details/47003279 本文介绍了ARM代码编译时的软浮点(soft-float)和硬浮点( ...

  8. 编译 arm 版的qt

    因为项目需要,我们需要在开发板上使用QT开发平台,因此需要编译一个arm版的QT. 在网上找了一些资料,费了几天时间,终于成功了. 第一步,准备源码 先下载QT 源码,在http://qt-proje ...

  9. ubuntu 14 编译ARM g2o-20160424

    1. 安装eigen sudo apt-get install libeigen3-dev sudo apt-get install libsuitesparse-dev sudo apt-get i ...

随机推荐

  1. 【周年庆】china-pub 14周年庆感恩回馈四波狂热来袭

    活动主题:china-pub 14周年庆感恩回馈四波狂热来袭活动说明:[第1波]电子书免费抢!10万好书 65折封顶!              活动规则:              1.活动期间内凡 ...

  2. MySQL Test Suite使用

    MySQL Test Suite使用 MySQL自动测试套件(The MySQL Test Suite)用于对MySQL程序进行测试,包括各种功能与存储引擎.包含于MySQL与MariaDB版本代码中 ...

  3. 再有人问你volatile是什么,把这篇文章也发给他

    在上一篇文章中,我们围绕volatile关键字做了很多阐述,主要介绍了volatile的用法.原理以及特性.在上一篇文章中,我提到过:volatile只能保证可见性和有序性,无法保证原子性.关于这部分 ...

  4. 部署Percona XtraDB Cluster高可用和多Master集群

    http://www.it165.net/admin/html/201401/2306.html http://www.oschina.net/p/percona-xtradb-cluster/ ht ...

  5. Android图片载入框架最全解析(一),Glide的基本使用方法

    转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/53759439 本文同步发表于我的微信公众号.扫一扫文章底部的二维码或在微信搜索 郭 ...

  6. Swift3.0:照片选择

    一.介绍 图片选择或者拍照功能: 1.选择相册中的图片或是拍照,都是通过UIImagePickerController控制器实例化一个对象,然后通过self.presentViewController ...

  7. 【deep learning学习笔记】注释yusugomori的DA代码 --- dA.cpp -- 训练

    说实话,具体的训练公式,我没有自己推导,姑且认为他写的代码是对的.总体上看,用bp的方法.特殊之处,在于输入层和输出层是完完全全的“同一层”. void dA::get_corrupted_input ...

  8. 1、Python简史

    Python简史 什么是Python 一种解释型的.面向对象的.带有动态语义的高级程序设计语言 Python编程 是一种使你在编程时能够保持自己风格的程序设计语言,你不用费什么劲就可以实现你想要的功能 ...

  9. iOS开发-KVC和KVO的理解

    KVC和KVO看起来很专业,其实用起来还是比较简单的,KVC(Key-value coding)可以理解为键值对编码,如果对象的基本类型,那么键值对编码实际上和get,set方法没有区别,如果是属性是 ...

  10. Idea 自动导入包的*设置99

    作者:Intopass 链接:https://www.zhihu.com/question/35806024/answer/64530300 来源:知乎 著作权归作者所有.商业转载请联系作者获得授权, ...