二、buildroot 构建交叉编译工具链

2.1 介绍

2.1.1 工具链简介

一个编译工具链模块是允许为系统编译代码的一组工具。它由一个编译器(在我们的例子中是 gcc)、像汇编器和链接器这样的二进制 utils(一般是 binutils)和一个C标准库(例如 GNU Libc, uClibc-ng)组成。

一个交叉编译工具链是可有在主机上运行的,但是编译出来的二进制文件只能运行在目标板或机器上。在我们的宿主机上也有工具链,它只能编译适用于我们的宿主机,编译出来的程序也只能运行在我们的宿主机上。

当前我们要使用 buildroot 编译出来一个交叉编译工具链,适用于我们的目标板。

目标板是 S3C2440,它是 ARM 架构的,arm920t 的核心。

2.1.2 buildroot 的工具链工具

buildroot 提供了两种建立交叉编译工具链的方式:

  • 内部工具链后端,在配置接口中称为 Buildroot 工具链。
  • 外部工具链后端,在配置接口中称为外部工具链。

使用工具链菜单中的工具链类型选项来选择这两种解决方案。一旦选择了一个解决方案,就会出现许多配置选项。

在 根目录下使用 make menuconfig,Toolchain--->Toolchain type

 

2.1.3 内部工具链

内部工具链是 Buildroot 在为目标嵌入式系统构建用户空间应用程序和库之前,自行构建的交叉编译工具链。

此交叉编译工具链支持几种 C 库:uClibc-ng, glibc 和 musl。

一旦选择这个类型的工具链后,大量的选项将出现。最重要的选项如下:

  • 更改构建工具链需要的内核头文件版本。
    • 在构建交叉编译工具链的过程中,C 库也在被构建。这个库提供了用户空间应用程序和 Linux 内核之间的接口。为了知道如何与 Linux 内核“对话”,C 库需要访问Linux内核头文件(即来自内核的.h文件),它定义了用户空间与内核之间的接口(系统调用、数据结构等)。
    • 由于此接口是向后兼容的,因此用于构建工具链的 Linux 内核头的版本不需要与我们打算在嵌入式系统上运行的 Linux 内核的版本完全匹配。它们只需要有一个与我们要运行的 Linux 内核版本相同或更老的版本。
    • 如果我们使用的内核头文件比我们在嵌入式系统上运行的 Linux 内核更新,那么C 库可能使用的接口不是我们的 Linux 内核提供的。
  • 更改 GCC 编译器、binutils 和 C 库的版本
  • 选择编译器选项(只有使用 uClibc 的时候需要)
    • 工具链是否应该有 RPC 支持(主要用于 NFS)、宽字符支持、语言环境支持(用于国际化)、c++ 支持或线程支持。
    • 根据我们选择的选项,Buildroot 菜单中可见的用户空间应用程序和库的数量将会改变:许多应用程序和库需要启用某些工具链选项。
    • 当需要某个工具链选项来启用那些包时,大多数包都会显示注释。如果需要,可以通过运行 make uClibc -menuconfig 进一步优化 uClibc 配置。
    • 但是请注意,Buildroot中 的所有包都是根据内置的默认 uClibc 配置进行测试的:如果通过删除 uClibc 的特性而偏离了这个配置,那么一些包可能不再构建。 

值得注意的是,每当修改其中一个选项时,就必须重新构建整个工具链和系统。

这种方式也有好处:与 Buildroot 有很好的集成并且快速,只构建必要的内容

缺点是:make clean 后需要重新构建工具链,这需要时间。如果我们试图减少构建时间,可以考虑使用外部工具链。

2.1.4 外部工具链

 

 外部工具链允许使用现有的预先构建的交叉编译工具链。

Buildroot知道许多著名的交叉编译工具链(来自用于 ARM 的 Linaro、用于 ARM 的 Sourcery CodeBench、x86-64、PowerPC 和 MIPS),并且能够自动下载它们,或者指向一个定制的工具链,可以下载,也可以在本地安装。

我们有三种方式使用一个外部工具链:

  • 使用预定义的外部工具链配置文件,并让 Buildroot 下载、提取和安装工具链。Buildroot 已经知道一些 CodeSourcery 和 Linaro 工具链。从可用的工具链中选择工具链配置文件。这绝对是最简单的解决方案。
  • 使用预定义的外部工具链配置文件,但不是让 Buildroot 下载和提取工具链,我们可以告诉 Buildroot 我们的工具链已经安装在系统的哪个位置。只需通过可用的工具链选择工具链配置文件,自动取消选择下载工具链,并用交叉编译工具链的路径填充工具链路径
  • 使用一个完全的自定义的外部交叉编译工具链。
    • 这对于使用crosstool-NG或使用Buildroot本身生成的工具链特别有用。
    • 要做到这些,首先要在 Toolchain 配置选项中选择 Custom toolchain
    • 我们需要填写 Toolchain path, Toolchain prefix 和 External toolchain C library 选项
    • 接着需要必须告诉 Buildroot 我们的外部工具链支持什么。如果外部工具链使用 glibc 库,只需要知道工具链是否支持 c++ 以及它是否有内置的 RPC 支持。如果外部工具链使用 uClibc 库,那么您必须告诉 Buildroot 它是否支持 RPC、宽字符、语言环境、程序调用、线程和c++。
    • 在执行的开始,Buildroot 会告诉我们所选选项是否与工具链配置匹配。

如果想为自己的项目生成一个定制的工具链,它可以在 Buildroot中 使用外部工具链,建议使用 Buildroot 或 crosstool-NG 来构建它。

  • 这种构建工具链的方式的好处是:
    • 允许使用众所周知且经过良好测试的交叉编译工具链。
    • 避免交叉编译工具链的构建时间,这在嵌入式Linux系统的总体构建时间中通常非常重要。
  • 坏处是:
    • 如果预先构建的外部工具链有错误,可能很难从工具链供应商那里得到修复,除非使用Buildroot或Crosstool-NG自己构建外部工具链。

2.2 构建工具链

2.2.1 使用 buildrtoo 构建外部工具链

内置的内部工具链选项可以用来创建外部工具链。下面是构建内部工具链并将其打包以供Buildroot自身(或其他项目)重用的一系列步骤。

make menuconfig 进入配置菜单

 

Target options 选择 CPU 架构:

 

 

 ToolChain 中选择配置交叉编译工具链的一系列选项:

  • Toolchain type:选择 Buildroot toolchain
  • custom toolchain vendor name:buildroot 构建的交叉编译工具链的名字是 <arch>-<vendor>-<os>-<libc>,这个选项对应 vendor 名字,配置成 s3c24x0,那么我们生成的工具链是 arm-s3c24x0-linux-glibc
  • C library:选择 glibc
  • Kernel Headers:内核头文件,选择手动指定,或者选择里面提供的内核版本,我这里选择手动指定 Manually specified Linux version
  • linux version:Linux 版本,填入 4.4.174
  • Custom kernel headers series:自定义内核头文件系列,选择 4.4.x
  • Install glibc utilities:启用这个选项将为目标编译和安装 getconf、ldconfig、ldd 和 locale glibc实用程序。按需要选择
  • Binutils Version:binutils 版本,保持默认
  • Additional binutils options:额外的 binutils 选项,保持为空
  • GCC compiler Version:GCC 编译器版本,选择为 gcc 8.x
  • Additional gcc options:额外的 GCC 选项,保持默认为空就好,如果需要,就自己填写
  • 语言支持:可以支持 C++ ,Fortran,支持 C++即可
  • Enable compiler link-time-optimization support:此选项支持gcc中的链接时间优化(LTO)。
  • Enable compiler OpenMP support:为编译器启用 OpenMP 支持。主要是在编译时采用并行处理
  • Enable graphite support:此选项启用编译器中的石墨优化。这个选项看不懂
  • Build cross gdb for the host:构建一个运行在主机上的交叉 gdb,并调试运行在目标机上的程序。它需要在目标上安装'gdbserver',即 BR2_PACKAGE_GDB_SERVER(Target packages-> Debugging, profiling and benchmark-> gdb )
    • TUI support:此选项为gdb启用终端用户界面(TUI)
    • Python support:此选项支持交叉 gdb 中的 Python 支持。
    • Simulator support:此选项启用了交叉 gdb 中的模拟器支持。
    • GDB debugger Version:版本选择 gdb 8.2.x
  • Copy gconv libraries:gconv 库用于在不同字符集之间进行转换。如果需要存储和/或显示不同的字符集,请使用'y'。
    • Gconv libraries to copy:设置为要复制的gconv库列表。为空以复制所有gconv库。只指定库的基本名称,忽略。so扩展。如:IBM850 ISO8859-15 UNICODE。注意,gconv 库占用 8 M(在 ARM 上)。
  • Extra toolchain libraries to be copied to target:如果工具链提供了需要复制到目标文件系统的额外库,请在这里输入它们,以空格作为分割符分割。如 "libasan liblsan libtsan libubsan"
  • Enable MMU support: MMU 支持
  • Target Optimizations:为目标主机构建时使用的优化。注意:gcc优化级别是在构建选项中定义的。一般不会选择
  • Target linker options:为目标构建时要传递给链接器的额外选项。
  • Register toolchain within Eclipse Buildroot plug-in:这个选项告诉 Buildroot 生成必要的配置文件,通过 Eclipse Buildroot 插件使工具链出现在 Eclipse 中。

System configuration 中需要禁用掉系统初始化选项和 /bin/sh:

  • Init system:选择 none
  • /bin/sh :设置为 none

Target packages 中要禁用 busybox:

  • busybox:选项设为空

Build options 中,需要设置一下源的路径,在执行构建的过程中,需要从不同的源地址下载各种不同的包,由于国内的和谐,所以需要更改为国内镜像:

  • Mirrors and Download locations
    • Kernel.org mirror:https://mirrors.tuna.tsinghua.edu.cn/kernel
    • GNU Software mirror:https://mirrors.tuna.tsinghua.edu.cn/gnu

Filesystem images 中禁用 tar the root filesystem

配置完成后,保存退出,然后执行命令 make sdk,编译完成后,如下:

 SDK 的压缩包存放再 $(O)/images 下,如果指定了 $(O),就是指定的目录,未指定则是根目录下output 目录。压缩包名为 arm-s3c24x0-linux-gnueabi_sdk-buildroot.tar.gz:

 保存这个 tarball,因为它现在是一个工具链,我们可以在其他 Buildroot 项目中重用它作为外部工具链。

在 buildroot 下建立自己的工作源码目录 source,虽然可以按 buildroot 的架构去添加包之类的,但是太过麻烦,每次只有在编译后,才能去看源码,在开发中,更多的是便开发边修改边编译。

mkdir source
cd source
cp ../output/images/arm-s3c24x0-linux-gnueabi_sdk-buildroot.tar.gz ./
mkdir toolchain
mv arm-s3c24x0-linux-gnueabi_sdk-buildroot.tar.gz ./toolchain
cd toolchain
tar -zxvf arm-s3c24x0-linux-gnueabi_sdk-buildroot.tar.gz
rm -rf arm-s3c24x0-linux-gnueabi_sdk-buildroot.tar.gz

现在要单独保存一下 toolchain 的配置文件:

  • 若是之前未使用 xxx_defconfig 生成的 .config 配置文件,根目录下执行 make savedefconfig 会在当前根目录下生成一个 defconfig 文件
  • 若是使用的 xxx_defconfig 生成的 .config,则执行 make update-defconfig 会自动更新 xxx_defconfig 文件
  • 生成 defconfig 后,保存到根目录下的 configs 文件夹下, cp defconfig configs/s3c24x0ToolSDK_defconfig,在自己的 source 中也保存一份 cp defconfig source/s3c24x0ToolSDK_defconfig

保存后,执行一下 make clean,同时修改一下根目录下的 Makefile,在执行 make distclean 的时候,不要删除 dl 目录,当然如果每次都想重新下载源码包的另说,不用改。

 

 1070 行中,带 dl 的删除掉即可。

同时若是使用的 git 托管代码,需要修改 .gitignore,将 dl 那一行删除即可。

修改完成后,执行一下 make distclean,后面需要针对自己的工程进行配置,我们可以直接使用我们编译出来的工具链,作为外部工具链使用。

make menuconfig 进入配置。

  • Target options 中的配置与交叉编译工具链的配置相同
  • Toolchain 中,
    • 将 Toolchain type 改为 External toolchain,
    • Toolchain 选择成 Custom toolchain
    • Toolchain origin 改为 Pre-installed toolchain
    • Toolchain path 填写为我们的路径:$(TOPDIR)/source/ arm-s3c24x0-linux-gnueabi_sdk-buildroot.tar.gz
    • External toolchain gcc version:改为我们编译的版本 8.x
    • External toolchain kernel headers series:头文件改为 4.4.x
    • External toolchain C library:改为 glibc
    •  Toolchain has SSP support?:勾选上
      • Toolchain has SSP strong support?:选上
    • Toolchain has RPC support?:勾选上
    • Toolchain has C++ support:勾选上
    • 其他的选项都保持和编译工具链的时候一致。

使用外部工具链比较坑的是,执行 make 的时候,工具链又被编译了一遍。这个问题再看看

指定 make savedefconfig 保存配置:

  mv defconfig configs/s3c24x0_defconfig

执行 make distclean,上传至 gitee 或是 github。

gitee 工程地址:https://gitee.com/cocosleep/project

posted @ 2020-06-14 18:08  游戏进行中  阅读(4927)  评论(0编辑  收藏  举报