精华内容
下载资源
问答
  • 交叉编译器

    2012-05-11 22:53:59
    交叉编译器制作——需要的组件及作用 在一种计算机环境(称为host machine)中运行的编译程序,能编译出在另外一种环境(称为target machine)下运行的代码,叫做交叉编译。实现这个交叉编译的一系列工具,包括C...

    交叉编译器制作——需要的组件及作用

    在一种计算机环境(称为host machine)中运行的编译程序,能编译出在另外一种环境(称为target machine)下运行的代码,叫做交叉编译。实现这个交叉编译的一系列工具,包括C函数库,内核文件,编译器,链接器,调试器,二进制工具……称为交叉编译工具链。
        实际上在进行嵌入式开发时,我们通常都会在主机上(host machine)使用开发板厂商提供的编译器,调试器。比如在windows上装环境调试51,61单片机,在Linux上用arm-gcc写arm开发板的程序……
        搭建交叉编译环境是一个非常繁琐并细致的过程。笔者就已嵌入式Linux交叉编译工具链的搭建为例,介绍下交叉编译工具的创建过程,和原理。
    主机(hostmachine),Fedora 9 Linux,  
    目标机(target machine),arm,mips,sh,ppc……
    一,首先介绍下交叉编译工具链的组成部分。
    1,编译器,汇编器。
        编译器是交叉编译工具链中最显眼的部分,因为平常我们与它打交道,写程序,编译成binary,下到开发板上。但是请注意,真正的编译器并不会把程序直接变成二进制文件,而是链接器在做这件事情。
        在Linux中,最常用的编译器就是传说中的gcc了,目前gcc已经到了4.4版本。编译器做的事情是把程序,翻译成目标机的汇编文件(.s),然后调用二进制工具的汇编器(as),变成目标文件(.o)。
        严格的说,汇编器as并不属于编译器gcc,它和链接器ld属于二进制工具(binutils -- binary utilies)。
    上一张图供大家理解(gcc.jpg)。
        什么是目标文件(.o)?目标文件本身是一种可链接的二进制文件,目前在System V系列系统中(Linux,Unix)常用的是ELF格式。简单的把.o画一下吧。
    2,链接器。
        链接器是把多个目标文件变成二进制文件。这个文件,可以是可执行文件,也可以是一个动态链接库,也可以是一个可重定位的目标文件(更大的.o)。链接成的文件也是ELF格式。
        链接的过程非常复杂,但原理却又简单,后面可以讨论。链接器在Linux中用的是ld,和as一样,在binutils程序包中。
        ELF定义比较复杂,主要是对于链接来说分了很多的section,对于运行来说逻辑上有一些segment。如果大家想了解一下ELF格式,其实是有利于对整个系统的理解和高级调试的。需要时进行讨论。
    3,内核文件。
        内核文件是指内核头文件。用途?实际上在编译程序(包括我们编译内核,甚至交叉编译工具链)的时候,通常要使用一些系统调用。内核头文件用于声明这些函数,以便链接器能够找到相应的程序入口。
        Linux中的内核头文件当然是在Linux Kernal 源码包里了,下载Linux Kernel后,即可安装头文件到某目录,供编译器及C库使用。请注意的是,内核头文件和二进制工具没有依赖关系。
        为什么要专门提出这一点?首先,有助于我们对交叉编译工具链各个环境的理解。其次,很多教材都是错的。原因:二进制工具,实际上是根据target machine的ABI接口对程序进行规范和抽象,并不关心到底程序在做什么。ABI=application binary interface,是system V系列系统汇编和硬件关系的接口标准。每个系列的处理器都有自己的ABI接口规范,ABI中定义了一些汇编使用规范和接口,如寄存器的使用,栈的组织,函数调用入口,数据对齐、格式,异常处理接口、信号规范等等等等。
    4,C函数库。
         无论是编译内核,还是日常的程序,甚至编译一个C++的编译器,都需要C语言函数库的支持。比如,我malloc一块内存,我要知道怎么malloc,Linux Kernel中不会提供一个内存管理的工具。其次C库是可以更换的,无论是静态链接库还是动态链接库。由于C库的接口标准同意,就可以对库而不是整个系统进行升级。
         在嵌入式系统中,使用的C语言库比较多。最强大,也最huge,最完善的莫过于GNU的glibc了,glibc也是标准的C语言库,目前已经到了version 2.9。另外,由于嵌入式系统的灵活性,不可能将如此大的一个c库移植到一个系统中,就衍生了很多轻量级的c库,如uClibc,newlib。
         请注意,由于编译器是根据C语言库创建出来的,所以编译器是依赖于C库的。比如ARM中的gcc,我们一般看到两种,一种是arm-linux-*,一种是arm-linux-*。区别就在于,arm-linux-*一般是根据glibc创建出来的,只能够和glibc的库使用(你使用glibc 2.8 2.9的动、静态连接库没有关系,而不能使用别的c库),但不能使用,而arm-elf-*一般使用 uClibc或者使用redhat专门为嵌入式系统的开发的C库newlib。
         请注意C库有个C库的头文件需要安装,依赖于内核头文件。
    5,调试器(可选)。
         调试器可以看作是补充的工具,当然,前提是你介于牛A和牛C之间。在编程中经常遇到这样那样的问题,有个调试器自然是最方便不过的了。目前支持各种环境的调试器最强的莫过于GDB了,GNU的gcc或许还对于某个平台优化的不好(例如x86环境下gcc编译出来的程序效率就不如intel自家的c++ complier),GDB在嵌入式上强大到一统江湖……
         但调试器并不只包括GDB,还有二进制工具中的objdump,address2line,readelf等。GDB依赖于内核头文件和C库。
        请注意在程序编译时必须加入一些调试信息,才能够使用调试器。常用的调试信息格式有stabs/stabs+, coff/xcoff/xcoff+, dwarf/dwarf+,怎么把这些信息加到程序中可以在gcc里面通过-g选项打开,一般貌似也用不到太深入的……需要用到时候在讨论吧。
    二,创建交叉编译工具链。
        创建交叉编译工具链有一些基本步骤。无论是Linux还是其他系统,原理是相通的。可以参考《构建嵌入式操作系统》
        可以参考youbest的CLFS2.0原理分析,CLFS也是一个著名的crosstoolhttp://www.linuxsir.org/bbs/showthread.php?t=267672
        主要步骤是


    安装交叉编译内核头文件/安装交叉编译的binutils (不分先后)
    安装target machine c库头文件。
    通过内核、C头文件和binutils安装gcc的c交叉编译器(bootstrap gcc)
    编译交叉编译的c库
    通过c库,头文件,编译出gcc的c++编译器。
    安装gdb

        对于板子的不同,需要更改的地方是:C库中内存map,kernel header中的各中断,内存映射地址……这些难度较大,都能写一本书了。一般来说抄公版设计,应用标准的C库及kernel header(各平台会以补丁的形式发布)。用到时再讨论吧。

    展开全文
  • 交叉编译器制作——需要的组件及作用 在一种计算机环境(称为host machine)中运行的编译程序,能编译出在另外一种环境(称为target machine)下运行的代码,叫做交叉编译。实现这个交叉编译的一系列工具,包括...

    交叉编译器制作——需要的组件及作用

    在一种计算机环境(称为host machine)中运行的编译程序,能编译出在另外一种环境(称为target machine)下运行的代码,叫做交叉编译。实现这个交叉编译的一系列工具,包括C函数库,内核文件,编译器,链接器,调试器,二进制工具……称为交叉编译工具链
        实际上在进行嵌入式开发时,我们通常都会在主机上(host machine)使用开发板厂商提供的编译器,调试器。比如在windows上装环境调试51,61单片机,在Linux上用arm-gcc写arm开发板的程序……
        搭建交叉编译环境是一个非常繁琐并细致的过程。笔者就已嵌入式Linux交叉编译工具链的搭建为例,介绍下交叉编译工具的创建过程,和原理。

    主机(hostmachine),Fedora 9 Linux,  
    目标机(target machine),arm,mips,sh,ppc……

    一,首先介绍下交叉编译工具链的组成部分。

    1,编译器,汇编器。
        编译器是交叉编译工具链中最显眼的部分,因为平常我们与它打交道,写程序,编译成binary,下到开发板上。但是请注意,真正的编译器并不会把程序直接变成二进制文件,而是链接器在做这件事情。

        在Linux中,最常用的编译器就是传说中的gcc了,目前gcc已经到了4.4版本。编译器做的事情是把程序,翻译成目标机的汇编文件(.s),然后调用二进制工具的汇编器(as),变成目标文件(.o)。

        严格的说,汇编器as并不属于编译器gcc,它和链接器ld属于二进制工具(binutils -- binary utilies)。

    上一张图供大家理解(gcc.jpg)。

        什么是目标文件(.o)?目标文件本身是一种可链接的二进制文件,目前在System V系列系统中(Linux,Unix)常用的是ELF格式。简单的把.o画一下吧。


    2,链接器。
        链接器是把多个目标文件变成二进制文件。这个文件,可以是可执行文件,也可以是一个动态链接库,也可以是一个可重定位的目标文件(更大的.o)。链接成的文件也是ELF格式。

        链接的过程非常复杂,但原理却又简单,后面可以讨论。链接器在Linux中用的是ld,和as一样,在binutils程序包中。

        ELF定义比较复杂,主要是对于链接来说分了很多的section,对于运行来说逻辑上有一些segment。如果大家想了解一下ELF格式,其实是有利于对整个系统的理解和高级调试的。需要时进行讨论。

    3,内核文件。
        内核文件是指内核头文件。用途?实际上在编译程序(包括我们编译内核,甚至交叉编译工具链)的时候,通常要使用一些系统调用。内核头文件用于声明这些函数,以便链接器能够找到相应的程序入口。
        Linux中的内核头文件当然是在Linux Kernal 源码包里了,下载Linux Kernel后,即可安装头文件到某目录,供编译器及C库使用。请注意的是,内核头文件和二进制工具没有依赖关系。
        为什么要专门提出这一点?首先,有助于我们对交叉编译工具链各个环境的理解。其次,很多教材都是错的。原因:二进制工具,实际上是根据target machine的ABI接口对程序进行规范和抽象,并不关心到底程序在做什么。ABI=application binary interface,是system V系列系统汇编和硬件关系的接口标准。每个系列的处理器都有自己的ABI接口规范,ABI中定义了一些汇编使用规范和接口,如寄存器的使用,栈的组织,函数调用入口,数据对齐、格式,异常处理接口、信号规范等等等等。

    4,C函数库。
         无论是编译内核,还是日常的程序,甚至编译一个C++的编译器,都需要C语言函数库的支持。比如,我malloc一块内存,我要知道怎么malloc,Linux Kernel中不会提供一个内存管理的工具。其次C库是可以更换的,无论是静态链接库还是动态链接库。由于C库的接口标准同意,就可以对库而不是整个系统进行升级。

         在嵌入式系统中,使用的C语言库比较多。最强大,也最huge,最完善的莫过于GNU的glibc了,glibc也是标准的C语言库,目前已经到了version 2.9。另外,由于嵌入式系统的灵活性,不可能将如此大的一个c库移植到一个系统中,就衍生了很多轻量级的c库,如uClibc,newlib。

         请注意,由于编译器是根据C语言库创建出来的,所以编译器是依赖于C库的。比如ARM中的gcc,我们一般看到两种,一种是arm-linux-*,一种是arm-linux-*。区别就在于,arm-linux-*一般是根据glibc创建出来的,只能够和glibc的库使用(你使用glibc 2.8 2.9的动、静态连接库没有关系,而不能使用别的c库),但不能使用,而arm-elf-*一般使用 uClibc或者使用redhat专门为嵌入式系统的开发的C库newlib。

         请注意C库有个C库的头文件需要安装,依赖于内核头文件。


    5,调试器(可选)。
         调试器可以看作是补充的工具,当然,前提是你介于牛A和牛C之间。在编程中经常遇到这样那样的问题,有个调试器自然是最方便不过的了。目前支持各种环境的调试器最强的莫过于GDB了,GNU的gcc或许还对于某个平台优化的不好(例如x86环境下gcc编译出来的程序效率就不如intel自家的c++ complier),GDB在嵌入式上强大到一统江湖……

         但调试器并不只包括GDB,还有二进制工具中的objdump,address2line,readelf等。GDB依赖于内核头文件和C库。

        请注意在程序编译时必须加入一些调试信息,才能够使用调试器。常用的调试信息格式有stabs/stabs+, coff/xcoff/xcoff+, dwarf/dwarf+,怎么把这些信息加到程序中可以在gcc里面通过-g选项打开,一般貌似也用不到太深入的……需要用到时候在讨论吧。

    二,创建交叉编译工具链。

        创建交叉编译工具链有一些基本步骤。无论是Linux还是其他系统,原理是相通的。可以参考《构建嵌入式操作系统》
        可以参考youbest的CLFS2.0原理分析,CLFS也是一个著名的crosstoolhttp://www.linuxsir.org/bbs/showthread.php?t=267672
        主要步骤是

    • 安装交叉编译内核头文件/安装交叉编译的binutils (不分先后)
    • 安装target machine c库头文件。
    • 通过内核、C头文件和binutils安装gcc的c交叉编译器(bootstrap gcc)
    • 编译交叉编译的c库
    • 通过c库,头文件,编译出gcc的c++编译器。
    • 安装gdb

        对于板子的不同,需要更改的地方是:C库中内存map,kernel header中的各中断,内存映射地址……这些难度较大,都能写一本书了。一般来说抄公版设计,应用标准的C库及kernel header(各平台会以补丁的形式发布)。用到时再讨论吧。

     

    展开全文
  • 这应该意味着afaik,即使使用GNAT Community Edition,也不需要根据GPL许可结果,因为所有标准库文件都未链接或属于GCC例外。 GNAT FSF也应该起作用。 我尚未测试过对ARM-eabi和自定义运行时的支持。 此项目的开发...
  • 简述一下这个东西的作用:用来构造文件系统,我们还需要把开发板上的opt、lib、usr等目录覆盖上去,二者合成一个文件系统,用来提供给交叉编译时编译器寻找头文件.h和库文件.so等东西用的。这样才能提供一个基本与...

    写在最前面 呵呵。。

    编译成功,完美支持:EGLFS、 EGLFS GBM,EGL on X11暂时不支持,不过我不打算在X11上实现EGL。效果上图:

    后面几天我会更新这篇文章,详细说明整个编译过程遇到的坑。

    完美支持QML控件的程序

    支持QML程序

    运行的程序是Qt自带的automotive.pro例子程序。 

    Qt自带的例子程序(automotive)

     

      EGL .................................... yes
      OpenVG ................................. no
      OpenGL:
        Desktop OpenGL ....................... no
        OpenGL ES 2.0 ........................ yes
        OpenGL ES 3.0 ........................ yes
        OpenGL ES 3.1 ........................ yes
        OpenGL ES 3.2 ........................ yes
      Vulkan ................................. yes
      Session Management ..................... yes
    Features used by QPA backends:
      evdev .................................. yes
      libinput ............................... yes
      INTEGRITY HID .......................... no
      mtdev .................................. yes
      tslib .................................. yes
      xkbcommon .............................. yes
      X11 specific:
        XLib ................................. yes
        XCB Xlib ............................. yes
        EGL on X11 ........................... no
    QPA backends:
      DirectFB ............................... no
      EGLFS .................................. yes
      EGLFS details:
        EGLFS OpenWFD ........................ no
        EGLFS i.Mx6 .......................... no
        EGLFS i.Mx6 Wayland .................. no
        EGLFS RCAR ........................... no
        EGLFS EGLDevice ...................... no
        EGLFS GBM ............................ yes
        EGLFS VSP2 ........................... no
        EGLFS Mali ........................... no
        EGLFS Raspberry Pi ................... no
        EGLFS X11 ............................ no
      LinuxFB ................................ yes
      VNC .................................... yes
      XCB:
        Using system-provided XCB libraries .. yes
        XCB XKB .............................. yes
        XCB XInput ........................... no
        Native painting (experimental) ....... no
        GL integrations:
          GLX Plugin ......................... no
          EGL-X11 Plugin ..................... no

     

    写在前面

    这个教程将指导你如何在电脑的虚拟机上交叉编译Qt 5.14.1并安装到树莓派4B上面。这样你就可以在电脑上用Qt Creator设计和编译树莓派的应用,然后直接在树莓派上运行和调试。采用此方式开发出来的Qt窗口应用程序是为了在真正的嵌入式设备上运行的应用。应用程序可以不在X-server或桌面运行、应用程序使用eglfs接口直接调用OpenGL直接驱动GPU绘制窗口。eglfs是Qt的一个平台插件,使Qt程序可以利用OpenGL ES 画图而无需窗口系统。这种方式是在支持gpu的嵌入式设备主要采用的方式。一般需要gpu厂商提供egl和gles驱动模块。Qt可以利用eglfs插件实现直接画图(全屏),或者在有窗口管理系统(如wayland合成器weston或Qtwayland合成器)时通过窗口画图。前者只能全屏显示一个程序,后者可以实现多进程应用。

    OpenGL ES(OpenGL for Embeded System)是OpenGL(Open Graphics Library)的精简子集,是以手持和嵌入式设备为目标的高级3D图形API

    开发环境

    1.[树莓派端]

    树莓派型号:Raspberry Pi 4 Model B

    CPU: ARM Cortex-A72 1.5GHz 64为四核

    内存:2GB

    TF卡:16GB

    操作系统:2020-02-13-raspbian-buster-full (32位操作系统,因为树莓派官方只有32位操作系统)

    raspbian常用的有两个版本Stretch和Buster,Stretch版一般安装在在树莓派3B和3B+上,Buster版安装在最新的树莓派4B上。查询当前操作系统版本的命令是 uname -a

    uname -a

    在 Raspberry Pi 官方网站的下载有 desktop和 Lite 两种版本,主要分别在于Lite 没有预设安装 X-server 与相关的套件,因此无法用 startx 启动视窗管理员。因为也没有安装 Qt 和 GTK+ 的函式库,因此也无法执行相关的视窗程式。采用本文方式编译出来的窗口程序原理上是不序号X-server即可运行,实际上能不能运行在Lite版本上待我后续试验后告诉大家。
    2. [PC端]

    操作系统:Win7

    虚拟机版本:VMware® Workstation 15 Pro

    Linux版版本:Ubuntu 18.04.3 LTS   64位版


    准备工作

    1. 在命令行界面使用以下命令更新固件,更新完成后重启系统。

    sudo rpi-update
    reboot

    2. 确保树莓派上的SSH协议已经打开。后续Qt Creator需要通过SSH和树莓派通信。可以执行以下命令打开设置界面,选择Interfacing Options,选择ssh,选择yes然后finish。

    sudo raspi-config

    以下清单总结了交叉编译Qt 5.14.1的主要步骤,我们将在这篇文章中逐一介绍。[PI]表示在树莓派上操作,[PC]表示在电脑上操作。

        1. [PI] 安装开发包

        2. [PI] 准备目标文件夹

        3. [PI] 配置调试及运行环境

        4. [PC] 创建工作文件夹并设置工具链

        5. [PC] 创建和配置sysroot

        6. [PC] 下载Qt

        7. [PC] 配置Qt

        8. [PC] 编译、安装和部署Qt

        9. [PC]  配置Qt Creator实现交叉编译树莓派的应用

        10. [PI] 复制字体


     

    1. [PI] 安装开发包
    首先修改/etc/apt/sources.list(软件源配置文件)和 /etc/apt/sources.list.d/raspi.list(系统源配置文件)这两个文件,取消掉deb-src前面的注释。

    先备份文件原始文件
    sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak
    sudo cp /etc/apt/sources.list.d/raspi.list /etc/apt/sources.list.d/raspi.list.bak
    
    编辑文件
    sudo nano /etc/apt/sources.list
    sudo nano /etc/apt/sources.list.d/raspi.list

    编辑好的文件如下,注意版本号是buster (source.list文件格式说明)。

    # 编辑 `/etc/apt/sources.list` 文件,删除deb-src前的#号
    deb http://mirrors.tuna.tsinghua.edu.cn/raspbian/ buster main non-free contrib
    deb-src http://mirrors.tuna.tsinghua.edu.cn/raspbian/ buster main non-free contrib
     
    # 编辑 `/etc/apt/sources.list.d/raspi.list` 文件,,删除deb-src前的#号。
    deb http://mirrors.tuna.tsinghua.edu.cn/raspberrypi/ buster main ui
    

    下一步是使用apt-get命令更新和下载开发包。由于移动宽带的不给力和我是有钱人的原因,更新过程中我使用的是手机5G热点接入联网方式,整个更新过程大概消耗了约1.3G的流量,不过升级速度真的很快!真的很快!真的很快!重要的事情说三遍。有的教程说使用国内源的方式下载,我尝试了一下,更新和下载过程中有错误发生,不知道原因。国内源修改好的sources.list文件和raspi.list文件内容如下:

    #国内源更新sources.list文件和raspi.list文件修改内容
    # `/etc/apt/sources.list` 文件
    deb http://mirrors.tuna.tsinghua.edu.cn/raspbian/ buster main non-free contrib
    deb-src http://mirrors.tuna.tsinghua.edu.cn/raspbian/ buster main non-free contrib
     
    # `/etc/apt/sources.list.d/raspi.list` 文件
    deb http://mirrors.tuna.tsinghua.edu.cn/raspbian/raspbian/ buster main ui
    
    sudo apt-get update
    sudo apt-get upgrade
    sudo apt-get build-dep qt4-x11
    sudo apt-get build-dep libqt5gui5
    sudo apt-get install libudev-dev libinput-dev libts-dev libxcb-xinerama0-dev libxcb-xinerama0
    
    有些教程说需要安装以下软件
    sudo apt-get install libfontconfig1-dev libdbus-1-dev libfreetype6-dev libicu-dev libinput-dev libxkbcommon-dev libsqlite3-dev libssl-dev libpng-dev libjpeg-dev libglib2.0-dev libraspberrypi-dev libpq-dev libmariadbclient-dev bluez libbluetooth-dev build-essential

    2. [PI] 准备目标文件夹
    这步是在树莓派的pi用户下创建/usr/local/qt5pi文件夹,后面编译好的Qt库会从电脑部署到这个文件夹。

    sudo mkdir /usr/local/qt5pi
    sudo chown pi:pi /usr/local/qt5pi

    3. [PI] 配置调试及运行环境
    编译好的可执行文件会放在树莓派的/opt目录下,但默认的pi用户没有创建文件夹或文件的权限,需要在根目录执行:

    sudo chmod -R 777 /opt

    远程调试时需要安装gdbserver:

    sudo apt-get install gdbserver

    增加分辨率设置:

    sudo leafpad ~/.profile

    在其中增加:

    # physical display properties
    export QT_QPA_EGLFS_PHYSICAL_WIDTH=1920
    export QT_QPA_EGLFS_PHYSICAL_HEIGHT=1080

    然后执行:

    source .profile

     

    4. [PC] 创建工作文件夹并设置工具链
    在电脑上创建交叉编译工具链工作文件夹。

    mkdir ~/raspi
    mkdir ~/raspi/cross-compile-tool/
    cd ~/raspi

    linaro网站下载交叉编译工具链到~raspi目录下,包括gcc、runtime、sysroot三项。提示:用迅雷下,迅雷下的快!

    下载后解压,合并放在~/raspi/cross-compile-tool/目录下,tar命令详解

    sudo tar jxvf gcc-linaro-7.5.01-2019.12-x86_64_gnueabif.tar.xz
    sudo tar jxvf runtime-gcc-linaro-7.5.0-2019.12-arm-linux-gnueabihf.tar.xz
    sudo tar jxvf sysroot-glibc-linaro-2.25-2019.12-arm-linux-gnueabihf.tar.xz

    将交叉编译器路径写入PATH中(设置环境变量的方法和测试方法

    修改方式和内容如下:

    sudo nano /etc/profile
    
    #profile文件最后一行增加下面这行代码:
    export PATH=$PATH:~/raspi/cross-compile-tool/bin
    
    
    sudo nano /etc/sudoers
    #sudoers文件修改好的样子:

    刷新环境变量

    #刷新变量文件
    source /etc/profile
    
    #测试变量是否写入成功
    echo $PATH

    检查配置是否正常

    arm-linux-gnueabihf-g++  -v
    sudo arm-linux-gnueabihf-g++ -v

    编译一个小程序试试效果

    1、nano编辑一段代码:

    #include <stdio.h>
    int main(int argc, char **argv)
    {
        printf("Hello, you do it succeed!!!\n");
        return 0;
    }

    2、编译代码

    arm-linux-gnueabihf-g++ main.c
    

    3、 将编译输出文件a.out复制到目标机用户主目录下,增加运行权限,执行代码。

    sudo chmod ugo+x ./a.out
    ./a.out
    
    #运行输出:
    Hello, you do it succeed!!!

    为什么一定要sudo aarch64-linux-gnu-g++ -v 也有正常输出?因为在下面的编译过程中make中没有用到sudo,但是安装的时候要sudo make install,这一步的操作也需要交叉编译器,如果不正确配置,会出现make成功,而sudo make install失败的情况。

    如果输入sudo aarch64-linux-gnu-g++ -v,提示没有找到命令,而直接输入aarch64-linux-gnu-g++ -v可正常显示。解决方法是在sudos配置文件下把交叉编译器的bin路径也加在secure_path变量里面。

     

    5. [PC] 创建和配置sysroot 
    sysroot是树莓派上的文件在PC上的拷贝,编译过程中需要的头文件、库等会在这里查找,此文件夹创建在~/rasp目录下。

    cd ~/raspi/cross-compile-tool
    mkdir ./sysroot/opt

    我们可以使用rsync将树莓派rootfs目录下的/lib、/usr/include、usr/lib、/opt的目录同步到PC端的sysroot目录下。如果电脑上的sysroot文件夹发生任何变化,都会被自动同步到树莓派上。raspberrypi_ip代表树莓派的网络名或IP地址。

    rsync -avz pi@raspberrypi_ip:/lib sysroot
    rsync -avz pi@raspberrypi_ip:/usr/include sysroot/usr
    rsync -avz pi@raspberrypi_ip:/usr/lib sysroot/usr
    rsync -avz pi@raspberrypi_ip:/opt/vc sysroot/opt

    简述一下sysroot目录的作用:

    将sysroot-glibc-linaro-2.25-2019.12-arm-linux-gnueabihf.tar解压出来的目录与树莓派合成一个文件系统,用来提供给交叉编译时编译器寻找头文件.h和库文件.so。这样才能提供一个基本与目标开发板一致的环境,有了这个环境之后,编译时找头文件就不在笔记本(ubuntu)的环境找了,只在sysroot这个目录里面找。

    下一步,我们需要将sysroot中的符号链接调整为相对的,因为这个文件夹在电脑和树莓派上都会有。用wget工具将sysroot-relativelinks.py文件下载到 ~/raspi/cross-compile-tool目录下,增加可执行权限,并运行。

    wget https://raw.githubusercontent.com/riscv/riscv-poky/master/scripts/sysroot-relativelinks.py
    chmod +x sysroot-relativelinks.py
    ./sysroot-relativelinks.py sysroot

    到这里,这个交叉编译环境就基本OK了!

     6. [PC] 下载Qt
    下载Qt 源代码文件,我下载的是5.14.1,当然其他版本也可以。进入QT官网下载网站,进入对应QT版本的目录(例如:5.14),子版本目录(5.14.1),single目录下载对应的Qt源代码文件:qt-everywhere-src-5.14.1.tar.xz。另外下载对应版本的PC端安装包。

    安装包是用来给PC端装一个Qt,源码是用来编译一个 对应平台的Qt,即编译一个arm平台可用的Qt。

    #源代码下载路径:
    http://download.qt.io/archive/qt/5.14/5.14.1/single/qt-everywhere-src-5.14.1.tar.xz
    #安装包下载路径:
    http://download.qt.io/official_releases/qt/5.14/5.14.1/qt-opensource-linux-x64-5.14.1.run

     7. [PC] 配置Qt

    ~/rasp目录下解压缩Qt源代码文件,Qt源代码目录的qtbase/mkspecs文件夹下面放置着各种平台下的编译配置信息,本次需要编译的平台的文件夹是:~/rasp/qt-everywhere-src-5.14.1/qtbase/mkspecs/devices/linux-rasp-pi4-v3d-g++。编辑pi4平台下的qmake.conf文件。

    #Qt源码包下载到~/rasp目录下,并在这个目录下解压缩,修改qmake.conf配置文件
    tar xvf  qt-everywhere-src-5.14.1.tar.xz
    sudo nano ./qt-everywhere-src-5.14.1/qtbase/mkspecs/devices/linux-rasp-pi4-v3d-g++/qmake.conf

    qmake.conf的原始内容:

    # qmake configuration for the Raspberry Pi 4 (32-bit) using the Mesa V3D
    # graphics stack. (not the Broadcom stack)
    #
    # This supports accelerated OpenGL both for X11 and DRM/KMS.  Perhaps
    # Wayland too.
    #
    # Tested with a sysroot created from Raspbian Buster and a gcc 7.4
    # toolchain from Linaro.
    #
    # Example configure command line, assuming installation to
    # /usr/local/qt5pi on device and ~/rpi/qt5 on the host:
    #
    # ./configure -release -opengl es2 -device linux-rasp-pi4-v3d-g++ -device-option CROSS_COMPILE=~/rpi/gcc-linaro-7.4.1-2019.02-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf- \
    #   -sysroot ~/rpi/sysroot -opensource -confirm-license -make libs -prefix /usr/local/qt5pi -extprefix ~/rpi/qt5 -v
    #
    # Check the configure output carefully. EGLFS, EGLFS GBM, and EGL on X11
    # should all be 'yes'. Otherwise something is wrong.
    #
    # If getting linker errors like "undefined reference to `_dl_stack_flags'" check the
    # symlinks in the sysroot, they were probably not adjusted
    # correctly. F.ex. sysroot/usr/lib/arm-linux-gnueabihf/libpthread.so must point to
    # sysroot/lib/arm-linux-gnueabihf/libpthread.so.0. If it is a broken link instead, bad
    # things will happen.
    
    include(../common/linux_device_pre.conf)
    
    QMAKE_LIBS_EGL         += -lEGL
    QMAKE_LIBS_OPENGL_ES2  += -lGLESv2 -lEGL
    
    QMAKE_CFLAGS            = -march=armv8-a -mtune=cortex-a72 -mfpu=crypto-neon-fp-armv8
    QMAKE_CXXFLAGS          = $$QMAKE_CFLAGS
    
    DISTRO_OPTS            += hard-float
    DISTRO_OPTS            += deb-multi-arch
    
    EGLFS_DEVICE_INTEGRATION = eglfs_kms
    
    include(../common/linux_arm_device_post.conf)
    
    load(qt_config)

    就qmake.conf文件的注释有些需要重点说明一下

    qmake configuration for the Raspberry Pi 4 (32-bit) using the Mesa V3D graphics stack. (not the Broadcom stack)

    This supports accelerated OpenGL both for X11 and DRM/KMS.  Perhaps Wayland too.

    qmake成支持V3D graphics stack 栈而不是之前的Broadcom 栈。这样Qt程序可以同时在窗口管理系统X11和DRM/KMS上支持OpenGL加速。没准Wayland窗口管理系统也可以。

    Tested with a sysroot created from Raspbian Buster and a gcc 7.4  toolchain from Linaro.

    编译Qt源码用到的sysroot目录和gcc编译器的最低版本是7.4,我下载的是高版本的7.5.0。 树莓派官方指定的git下载目录https://github.com/raspberrypi/tools里面的版本太低,我记得应该是4.7.1吧。

    Check the configure output carefully. EGLFS, EGLFS GBM, and EGL on X11 should all be 'yes'. Otherwise something is wrong.

    完成配置后注意查看配置状态表上EGLFS, EGLFS GBM, 和 EGL on X11这几项是不是yes,否则编译会不成功。

    If getting linker errors like "undefined reference to `_dl_stack_flags'" check the  symlinks in the sysroot, they were probably not adjusted  correctly. F.ex. sysroot/usr/lib/arm-linux-gnueabihf/libpthread.so must point to sysroot/lib/arm-linux-gnueabihf/libpthread.so.0. If it is a broken link instead, bad things will happen.

    如果在make过程中出现 "undefined reference to `_dl_stack_flags'"错误,应该是sysroot目录下的libpthread.so库文件的软连接不对,用进入到文件目录下用 ls -l 命令查询一下,如果不是链接到“sysroot/lib/arm-linux-gnueabihf/libpthread.so.0.”需要用ln命令修复软链接: sudo ln -sf libpthread.so sysroot/lib/arm-linux-gnueabihf/libpthread.so.0.

    配置Qt库:

    进入Qt源代码文件夹的qtbase目录下运行./configure命令进行编译前配置。 因为./configure的配置参数很多,建议先阅读文章Qt源码编译configure配置参数

    简单来说./configure作用是根据不同的设置参数和选项明确目标平台信息、要编译的库、不编译的库等一些列选项,来编译出一个我们需要的arm目标平台版本的Qt。一些关键选项看下面这张表:

    -release 

    加上此选项编译程序Qt不会做出优化,往往在开发过程使用此选项,是默认选项

    -opengl es2 

    表示编译带opengl es2的Qt

    -device linux-rasp-pi4-v3d-g++

    选择的目标设备,目标设备的配置文件可在/qtbase/mkspec/device找到

    -device-option CROSS_COMPILE=
    ~/raspi/home/用户名/raspi/cross-compile-tool/bin/arm-linux-gnueabihf- 

    交叉编译器的路径,注意最后那里的arm-linux-gnueabihf- ,确实有一杠,不要以为打错了

    -sysroot ~/raspi//cross-compile-tool/sysroot 

    刚刚构建的树莓派文件系统的路径

    -opensource 

    以开源版本发布程序

    -confirm-license 

    自动确认许可证(使用开源或是商业)

    -make libs 

    在make时添加要构建的组件. (默认为:libs tools examples)

    -prefix /usr/local/qt5pi

    目标板的Qt程序安装目录,默认路径是/usr/local/Qt-版本号 (make完成后看看PC端对应目录下是否有qt5pi目录)

    -extprefix ~/raspi/qt5pi 

    指定Qt 交叉编译库存放位置。默认路径是SYSROOT/PREFIX。此目录最后需要同步rsysc到目标板的/usr/local/目录下。

    -hostprefix ~/raspi/qt5-host

    指定Qt 编译的可执行工具存放的位置,比如 qmake,默认路径与-extprefix参数一致。

    -no-use-gold-linker 

    不要使用GNU gold linker进行链接。对于 5.9.1 或更高版本的 Qt必须添加此选项,不然编译会报错

    -v 

    显示每个步骤的详细信息

    -no-gbm

    不要编译 GBM 的后端

    进入到源码的根目录下的qtbase目录输入如下命令,并运行./configure的完整指令,开始运行配置过程。

    cd  ~/rasp/qt-everywhere-src-5.14.1/qtbase
    ./configure -release -opengl es2 -device linux-rasp-pi4-v3d-g++ -device-option CROSS_COMPILE=~/raspi/cross-compile-tool/bin/arm-linux-gnueabihf- -sysroot ~/raspi/cross-compile-tool/sysroot -opensource -confirm-license -make libs -prefix /usr/local/qt5pi -extprefix ~/raspi/qt5pi -hostprefix ~/raspi/qt5pi-host -v 
    
    
    #qmake.conf注释中说这两项参数不需要
    -no-use-gold-linker -no-gbm

    8. [PC] 编译、安装和部署Qt
    这一步大概需要2小时。

    make -j4
    make install

    编译完成后使用rsync命令将Qt部署到树莓派上。我们只需同步~/raspi/qt5pi目录到到树莓派的/usr/local/qt5pi目录下。

    cd ~/rasp
    rsync -avz qt5pi pi@raspberrypi_ip:/usr/local

     

    展开全文
  • (基本调试操作,段错误如何调试) 今日任务完成情况 今日任务按计划完成1、学习了gcc的基本内容2、学习了交叉编译器及其作用3、源文件转变成可执行文件需要的步骤4、预处理需要做的工作5、学习了如何让编译器停止...
     

     

     

     

    今日学习任务:

    1、熟练使用文本编辑器 vim;(基本操作、配置、使用技巧)

    2、熟练使用编译器 gcc;(基本编译选项、静态库与动态库的制作与使用)

    3、了解调试器 gdb;(基本调试操作,段错误如何调试)

     

    今日任务完成情况

     

    今日任务按计划完成

    1、学习了gcc的基本内容

    2、学习了交叉编译器及其作用

    3、源文件转变成可执行文件需要的步骤

    4、预处理需要做的工作

    5、学习了如何让编译器停止在各个不同的阶段

    6、编译阶段需要做的工作

    7、-c、-o、-S等指令的作用

     

    今日开发中出现的问题汇总

     静态库、动态库的建立遇到问题

     

     

    今日未解决问题

    无 

     

    今日开发收获           学会了运用不同的指令在虚拟机环境下编写、编译程序等处理

     

     

    自我评价

     在询问同学后能够解决存在的问题,基本能够掌握老师在课上讲的内容

    (是否按开发规范完成既定任务,需要改进的地方,与他人合作效果等)

     

     

     

    其他

     

      一、 1  #include<stdio.h>
           2 int main()
           3 {
           4     printf("add = %d\n",add(6,3));
           5     printf("sub = %d\n",sub(6,3));
           6     return(0);
           7 }

           1  int add(int a, int b)
           2 {
           3     return a + b;
           4 }

      二、

    #include<stdio.h>

    int main()

    {

        int i;

        int j;

        int k = 1;

        for(i = 2;i <= 100;i ++ )

        {    

            for(j = 2;j <= i / 2;j ++ )

            {

                if(i % j == 0)

                {

                    k = 0;

                    break;

                }

            }

            if(k == 1)

            {

                printf("%d\n",i);

            }

            k = 1;

        }

        return 0;

    }

     

    展开全文
  • (六)yocto SDK的生成及eclipse配置

    千次阅读 2018-09-10 14:52:42
    一、SDK介绍 作用: ...SDK的另一个特性是只为任何给定的体系结构生成一组交叉编译器工具链二进制文件。 所有SDK都包含以下内容: 交叉开发工具链:此工具链包含编译器,调试器和各种其他工...
  • JNI:Java Native Interface 是为了方便java调用java和c等本地代码所封装的一层接口.专门用于和本地代码交互,...NDK还提供了交叉编译器,开发人员只需要通过简单地修改mk文件就可以生成特定的CPU平台的动态; 作用: 1.
  • 概述 ●该章节主要讲解的是ELF文件的结构。 ●静态的概念 ●动态(又叫共享)的概念,一般用于操作系统,普通应用程序作用不大。...因为链接是处在编译器、计算机体系结构和操作系统的交叉点...
  • 国嵌笔记。全集全集

    2017-08-31 17:35:48
    一. 安装交叉编译器 6 二. 安装驱动 6 三. 查看执行文件属性 6 四. 编译工具用法 6 五. Makefile基本规则 7 六. 链接脚本 8 七. Eclipse 在线调试 工具包为ARM-Tools.tar.gz 8 八. ARM工作模式 10 九. 寻址方式...
  • 第1篇 FMS320C6000优化编译器手册 第1章 介绍 1.1软件开发工具概述 1.2 C/C++编译器概述 1.3 CCS(Code Composer Studio)和编译器 第2章 使用C/C++编译器 2.1关于编译器 2.2执行C/C++编译器 2.3设置选项改变编译器...
  • C#微软培训教材(高清PDF)

    千次下载 热门讨论 2009-07-30 08:51:17
    C#--微软.NET的第一语言 本书着重介绍语言本身,比较少涉及应用,不错的入门书,从头讲起,不怕... C#语言在.NET 框架中的作用及其特性 1.1 Microsoft.NET 一场新的革命 1.1.1 什么是.NET 2000 年 6 月 ...
  • C#微软培训资料

    2014-01-22 14:10:17
    C#语言在.NET 框架中的作用及其特性 1.1 Microsoft.NET 一场新的革命 1.1.1 什么是.NET 2000 年 6 月 22 日 不论对 Microsoft 还是对整个 IT 业界都将成为值得纪念的一天 这一天 微软公司正式推出...
  • GExperts 1.32 For Delphi 7

    2011-11-08 09:22:45
    在一个比较复杂的项目开发中,各个文件之间的调用关系不是凭印象可以弄清楚的,现在有了这个分析工具,你可以查阅到某个文件调用了哪些单元、被哪些单元调用了,以及调用的单元又被别的哪些单元文件调用过的交叉列表...
  • Chikofsky在本书的序中特别指出:阅读别人写的代码或者自己以前写的代码实际上也是逆向工程在起作用。 第二类是从没有源代码的程序出发,生成对应的源程序、系统结构以及相关设计原理和算法思想的文档等,亦即本书...
  • Reversing:逆向工程揭密

    热门讨论 2010-06-21 17:27:22
    Chikofsky在本书的序中特别指出:阅读别人写的代码或者自己以前写的代码实际上也是逆向工程在起作用。 第二类是从没有源代码的程序出发,生成对应的源程序、系统结构以及相关设计原理和算法思想的文档等,亦即本书...
  • 它提供了一种新的函数声明的形式,允许在使用中对函数的定义进行交叉检查。它说明了一个标准和一个完成输入输出、内存管理和字符串操作等类似任务的函数集扩充。此标准明确地说明了原始定义没有指出的一些特性的...
  • 3.2.6 交叉参考 3.2.7 参考重命名 3.2.8 标签的用法 3.2.9 进制的转换 3.2.10 代码和数据转换 3.2.11 字符串 3.2.12 数组 3.2.13 结构体 3.2.14 枚举类型 3.2.15 堆栈变量 3.2.16 IDC脚本 3.2.17 FLIRT 3.2.18 插件 ...
  • 嵌入式课件

    2012-04-06 16:48:49
    10.1.1 Bootloader 的作用 10.1.2 Bootloader 的工作模式 10.1.3 Bootloader 的启动流程 10.2 S3C2410 平台下Linux的Bootloader 10.2.1 vivi 10.2.2 U-boot 10.3 其他常见的Bootloader 10.3.1 WinCE的Bootloader ...
  • 4、交叉编译器 arm-softfloat-linux-gnu-gcc-3.4.5 【实验步骤】 一、建立自己的平台类型 (1)解压文件 #tar jxvf u-boot-1.3.1.tar.bz2 (2)进入 U-Boot源码目录 #cd u-boot-1.3.1 (3)创建自己的开发板...
  • 5.5.1 Kerberos交叉领域支持 209 5.5.2 sysdba强身份验证 209 5.6 Oracle调用接口增强 210 5.6.1 设置坏数据包捕捉的信息级别 210 5.6.2 延迟或删除数据库连接 210 5.6.3 配置服务器连接尝试的最大次数 211 ...
  • dependencies = [] 是依赖第三方的配置,可以加新,但不要去修改原有第三方的版本号,不然可能会编译不过 1.4、配置AndroidManifest 添加权限: <uses-permission android:name="android.permission....
  •  通过提示及配置文件等来控制执行计划;  在程序中优化查询而无需改动代码。  作为Oracle SQL经典著作之一,本书为SQL开发人员指明了前行的方向,赋予了他们不断开拓的动力。 作者简介  KAREN MORTON 研究...
  •  通过提示及配置文件等来控制执行计划;  在程序中优化查询而无需改动代码。  作为Oracle SQL经典著作之一,本书为SQL开发人员指明了前行的方向,赋予了他们不断开拓的动力。 作者简介  KAREN MORTON 研究...

空空如也

空空如也

1 2
收藏数 27
精华内容 10
关键字:

交叉编译器库文件作用