本文转载自:https://blog.csdn.net/linczone/article/details/45894181

使用buildroot创建自己的交叉编译工具链

关键字:buildroot 交叉编译

Author: chad 
Mail: linczone@163.com

开发环境: deepin 14.03 + mini2440 (使用原厂linux2.6.29)

  曾经,很长一段时间我一直有个疑惑:为什么我用at91sam9260交叉编译工具链编译的程序只能在at91sam9260上运行,在mini2440上就不能运行?相反,用使用于mini2440的交叉编译工具链编译的程序在at91上也不能运行?mini2440与at91sam9260都是arm平台,同样使用linux系统,为何二进制程序不能通用呢?

  本文将解答这些疑惑。我们是不建议重复发明轮子的,但如果我们不自己发明一次,我们永远不知道轮子是怎么来的。

  进行嵌入式Linux开发的第一步是创建交叉编译工具链,在过去很长的一段时间里,构建一套交叉编译工具链对于嵌入式开发者来说简直是一场恶梦,因为他们得手动跟踪各种源码包(及其更新包)之间的依赖关系。直到buildroot的出现改变了这一事实。

  Buildroot是一个Makefiles和patches的命令集,它可以非常简单的为你的目标系统产生一个交叉编译工具链和根文件系统,整个创建过程就如同编译Linux内核一般。

1、下载buildroot

直接从官网下载最新的源码包:http://buildroot.net/downloads/

2、安装依赖库、软件包

下文摘自buildroot官网操作说明

1. Build tools:

gcc (version 2.95 or any later)
g++ (version 2.95 or any later)
python (version 2.6 or 2.7) 2. dependencies packages: 下面的自己根据需要安装
ncurses5 ;menuconfig 使用
qt4 ;xconfig 使用
glib2, gtk2 and glade2 ;gconfig 使用
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

3、 解压buildroot压缩包

4、 进入源码目录,make menuconfig配置

配着之前看看下s3c2440数据手册摘录: 
 
接下来简单解释几个比较重要的选项:

Target Architecture      --->     用于选择目标的架构,我这里选择ARM (little endian)(s3c2440可以运行在小端模式和大端模式,默认是小端模式)
Target Architecture Variant ---> 内核类型(arm920t)
Target ABI (EABI) ---> 目标使用的应用程序二进制接口,其中有两个选择
①EABI(Embedded ABI) 我们选EABI.
②OABI(Old ABI) Build options ---> 主要是一些编译时用到的选项,比如dl的路径,下载代码包使用的路径,同时运行多个编译的上限,是否使能编译器缓冲区等等,这里按照默认就行了. Toolchain ---> 工具链选项
Toolchain type (Buildroottoolchain) ---> 工具链类型,这里我们没使用外部Buildroot,默认 . *** Kernel Header Options ***
Kernel Headers (Linux 3.18.x kernel headers) --->
C library (glibc) ---> 有uclibc/glibc等选项,此处我选择glibc,后面会解释原因
glibc version (2.20) --->
*** Binutils Options ***
Binutils Version (binutils 2.24) --->
() Additional binutils options
*** GCC Options ***
GCC compiler Version (gcc 4.8.x) --->
() Additional gcc options
[*] Enable C++ support
[ ] Enable compiler OpenMP support
[ ] Enable libmudflap support
[ ] Enable graphite support
[ ] Build cross gdb for the host
[ ] Purge unwanted locales
() Generate locale data
[ ] Copy gconv libraries
[*] Enable MMU support
() Target Optimizations
() Target linker options
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

5、保存退出,生成.config 文件

6、编译

$make

这里不能使用make-jN,因为Buildroot不支持top-levelparallel make , 反之 , 使用BR2_JLEVEL选项来告诉Buildroot运行编译每一个package使用make -JN.

使用make命令之后会执行下面几个步骤:
①下载源文件(所要求的)
②配置,编译和安装cross-compiling toolchain(如果使用内部工具链),或者输出一个toolchain(如果一个外部工具链使用)
③构建/安装杯选择的目标包
④构建内核镜像(如果有选择)
⑤构建启动代码镜像(如果有选择)
⑥创建根文件系统(如果有选择)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

7、输出文件介绍

输出文件全部在output/目录下:

  • images/ — 存放编译后产生的所有镜像文件( 内核镜像 , 加载引导镜像 和 根文件系统镜像)
  • build/ — 存放所有的组件除了构建交叉编译工具链的组件 , 在这个目录里面每一个功能对应一个子目录存放他们各自的组件.
  • staging/ — 包含一个类似于根文件系统等级层次的层级 . 这个目录包含了 安装的交叉编译工具链 和 所有被选择用于目标板的所有用户空间包.
  • target/ — 包含了根文件系统,但不能用于你的开发板的
  • host/ — 包含了我们需要的交叉编译工具集

我们可以在host/usr/bin/里面看到很多我们需要的二进制文件,如下所示: 
# cd host/usr/bin/ 

8、修改环境变量

在/etc/profile文件里加入:

# vim/etc/profile
添加上: exportPATH=$PATH:/home/chad/works/binutils/buildroot-2015.02/output/host/usr/bin
保存之后,执行以下命令使其生效:
# source/etc/profile
  • 1
  • 2
  • 3
  • 4

9、测试arm-linux-gcc

打印出版本号说明编译成功: 

10、hello.c测试

编写一个hello.c程序,使用arm-linux-gcc编译并下载到开发板进行测试。 

按照上文的配置,程序运行肯定是正常的。 
但是如果上面选择的是uclibc,duang!程序运行就会出错!

C library (uclibc)  --->  有uclibc/glibc等选项,此处如果选择uclibc
  • 1

如果我们用hexdump 查看hello的二进制文件,会发现如下信息:

#hexdump -C hello
  • 1

 

然后我们用同样的方法查看能正确执行的二进制程序的信息,随便打开一个信息如下: 

发现区别没?mini2440默认调用的是glibc库,而不是uclibc库。

需要注意的是,buildroot编译效率很低,一次编译完成后,如果你想修改某些东西,则必须重新全部编译!!也即先make clean 再 make。


如何重新编译软件包?

  经过第一次完整编译后,如果我们需要对源码包重新配置,我们不能直接在buildroot上的根目录下直接make,buildroot是不知道你已经对源码进行重新配置,它只会将第一次编译出来的文件,再次打包成根文件系统镜像文件。不过,我们可以通过以下两个方法修改源码的配置。

  1. 直接删除源码包,例如我们要重新编译openssh,那么可以直接删除output/build/openssh-vesion 文件夹,那么当你make的时候,他就会自动从dl文件夹下,解压缩源码包,并重新安装
  2. 也是以openssh为例子,如果我们不想重新编译,只想重新配置,也就是./configure, 
    我们可以直接删除 output/build/openssh-version 目录下的 .stamp_configured 
    如果你只是想重新安装可以删除.stamp_target_install 
    重新make可以删除.stamp_built

总结:

为什么针对mini2440的交叉编译工具链与针对at91sam9260的交叉编译工具链不通用?

看下我们前面制作交叉编译工具链都指定了那些重要参数:

Target Architecture ---> 目标的架构,s3c2440 与 at9260 都是arm,这个相同
Target Architecture Variant ---> 内核类型(s3c2440[arm920t] 而 at91sam9260[arm926EJ-S],但是配置时选择arm926t),此处不同
Target ABI (EABI) ---> 目标使用的应用程序二进制接口,此处不同
①EABI(Embedded ABI) mini2440的选择。
②OABI(Old ABI) at91sam9260的选择 Kernel Headers (Linux 3.18.x kernel headers) ---> 此处差别影响不大
C library (glibc) ---> 都选择的是glibc
glibc version (2.20) ---> 版本不一样
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

至此,我想两个平台的交叉编译工具链不可通用的原因应该已经很清楚了。

—————–2015-05-21

使用buildroot创建自己的交叉编译工具链【转】的更多相关文章

  1. Linux 安装交叉编译工具链

    交叉编译工具链下载地址: 链接:http://pan.baidu.com/s/1dE7P9rb 密码:300i 声明:下面每一步中的“pwd”指令都是为了看清楚当前的目录,没有其他实际意义. 系统:u ...

  2. Linux ARM交叉编译工具链制作过程【转】

    本文转载自:http://www.cnblogs.com/Charles-Zhang-Blog/archive/2013/02/21/2920999.html 一.下载源文件 源代码文件及其版本与下载 ...

  3. arm-linux交叉编译工具链的制作(基于S3C2440)【转】

    本文转载自:http://eric-gao.iteye.com/blog/2160622 制作arm-linux交叉编译工具链一般通过crosstool工具或者crosstool-NG,前者使用方便, ...

  4. 构建嵌入式Linux交叉编译工具链

    开源交叉编译工具链制作方法汇总: 1) 使用crosstool/crosstool-ng生成 2) 使用buildroot生成 ARM交叉编译工具链说明: 1) arm-linux-gcc是一个集合命 ...

  5. CROSSTOOL-NG建立交叉编译工具链

    CROSSTOOL-NG建立交叉编译工具链 因为考试和学习的原因我已经一段时间没有玩我的JZ2440,现在终于考完试了,我再次找出了我的JZ2440.我之前学习的时候使用的是韦东山老师提供的开发工具, ...

  6. Crosstool-ng制作交叉编译工具链

    Crosstool-ng制作交叉编译工具链 交叉编译器可以用现成的,比如CodeSourcery制作的交叉编译器,也可以自己制作,一般是用kernel+gcc+glibc+binutils的源码包来编 ...

  7. 【转】ARM交叉编译工具链

    原文网址:http://www.veryarm.com/cross-tools 为什么要用交叉编译器? 交叉编译通俗地讲就是在一种平台上编译出能运行在体系结构不同的另一种平台上的程序,比如在PC平台( ...

  8. ARM交叉编译工具链分类说明

    转载整理自:http://www.veryarm.com/cross-tools 从授权上,ARM交叉编译工具链分为免费授权版和付费授权版. 免费版目前有三大主流工具商提供,第一是GNU(提供源码,自 ...

  9. Ubuntu16.04下的2009q3交叉编译工具链的搭建

    环境搭建:    1.下载arm-2009q3.tar.bz2源码.  百度云链接  密码: rbui    2.将arm-2009q3.tar.bz2拷贝到/usr/local/arm(没有该目录就 ...

随机推荐

  1. java-通过 HashMap、HashSet 的源码分析其 Hash 存储机制

    通过 HashMap.HashSet 的源码分析其 Hash 存储机制 集合和引用 就像引用类型的数组一样,当我们把 Java 对象放入数组之时,并非真正的把 Java 对象放入数组中.仅仅是把对象的 ...

  2. iOS开发之--蓝牙开发实战

    转载自:http://www.cnblogs.com/zyjzyj/p/6029968.html ,感谢英杰 前言 最近一直在开发关于蓝牙的功能,本来是不想写这一篇文章,因为网上关于ios蓝牙开发的文 ...

  3. cxGrid 循环选择条目

    Delphi DevExpress CxGrid 循环选择条目 整理出来的,直接复制粘贴即可使用 以下是从网络上复制粘帖到的,实践证明,利用以下代码进行获取选择行是错误的. 当我们利用 CxGrid进 ...

  4. Codeforces Round #207 (Div. 1) B (gcd的巧妙运用)

    比赛的时候不知道怎么写... 太弱了. 看了别人的代码,觉得这个是个经典的知识点吧. gcd的巧妙运用 自己想的时候苦苦思考怎么用dp求解. 无奈字符串太长而想不出好的算法. 其实在把a和b字符串都分 ...

  5. iOS设置导航栏透明度

    As I support Colin's answer, I want to give you an additional hint to customize the appearance of an ...

  6. mongoDB-----针对某个或多个文档只需要部分更新可使用原子的更新修改器

    update() db.collection.update( <query>, <update>, { upsert: <boolean>, multi: < ...

  7. 并发编程6 锁&进程&队列

    1.进程的其他方法 2.验证进程空间隔离和守护进程 3.孤儿进程和僵尸进程 4.锁 for循环加join数据共享 5.进程队列的简单应用 6.通过队列实现进程间的通信 7.生产者消费者模型及Queue ...

  8. 微信公众号 openId 支付 php中file_get_contents与curl性能比较分析

    w http://www.jb51.net/article/57238.htm

  9. Java 常用工具类之 String 类

    String 类的特点: 字符串对象一旦被初始化就不会被改变. //以下代码的区别: String s = "abc"; // 在常量池中创建一个字符串对象, 池中没有就建立, 池 ...

  10. mongoose连接数据库的两种形式

    不废话,直接 ---------------------- .如果你的应用程序只使用一个数据库, 应该使用 mongoose.connect. 如果您需要创建额外的连接,使用 mongoose.cre ...