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

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. Java 如何实现在线预览文档及修改(Office文件)

    测试地址: https://sms.idxkj.cn 用户名:aa 密码:123456

  2. SharePoint 2016 站点注册工作流服务报错

    前言 安装完SharePoint 2016工作流环境,本来以为万事大吉了,结果给站点注册的时候报错了.搜了很多文章,发现后面要加上-Force参数. 错误截图 使用的为站点注册工作流服务的PowerS ...

  3. spring boot 之@JsonView 简单介绍

    @JsonView是jackson json中的一个注解,spring webmvc也支持这个注解. 这个注解的作用就是控制输入输出后的json. 假设我们有一个用户类,其中包含用户名和密码,一般情况 ...

  4. 我们的生活第二季/全集This Is Us迅雷下载

    NBC剧集<我们这一天>宣布一次性续订2.3季,这部Dan Fogelman打造的大热剧是这个秋季档收视人数第二的广播网剧情剧.新续订的两季还是每季18集. NBC的叫好叫座剧<我们 ...

  5. Docker存出载入镜像

    镜像的存出和载入 如果你的生产环境不能连通互联网,而你又希望从互联网上获取镜像.你就需要借助 docker save命令,可以将镜像导出为 tar 文件.使用 docker load 命令,可以将ta ...

  6. LaTeX使用技巧

    使用LaTex的方法: (1)推荐一个手写公式.自动生成LaTex的网站——Web Equation. (2)如果会LaTex,可以直接用在线LaTex编辑 (3)从mathtype转换: 首先打开文 ...

  7. endnote插入参考文献后的对齐方式和缩进空格

    原文链接 https://jingyan.baidu.com/article/63acb44a3f0f6161fcc17ed0.html 1 2 3 4 5 6 7 分步阅读 1.endnote 导入 ...

  8. Invalid Host header 的解决方案

    composer 显示:Invalid Host header的解决方案 I have tried this workaround: Edit the following line in node_m ...

  9. CSS 强制换行和禁止换行强制换行 和禁止换行样式

    强制换行 1.word-break: break-all;       只对英文起作用,以字母作为换行依据. 2.word-wrap: break-word;   只对英文起作用,以单词作为换行依据. ...

  10. 用SLF4j/Logback打印日志-1

    在 浅谈后端日志系统 中已经写了很多日志方面的零散的非技术的东西.本篇更像一份入门说明,讲解一下SLF4j/Logback.SLF4J是一套抽象的日志API接口,logback它是的底层实现,所以在这 ...