linux - Qt Creator 为 Raspberry Pi 2 进行交叉编译和远程部署的正确设置 - 为错误的架构生成二进制文件

标签 linux deployment arm qt-creator raspberry-pi2

我只是经历了 hell 般的设置我的 Qt Creator、Raspberry Pi 和 Debian 8(用于我的笔记本),最后设法配置了所有东西。或者我是这么想的。下面是对我到目前为止所做的工作的描述,以便 Stackoverflow 上的一些聪明人可能会看到我做过(或没有做过:D)的一些愚蠢的事情。

我正在使用以下平台:

  • 运行最新 Raspbian 的 Raspberry Pi 2 - 我想在其中运行代码的目标平台
  • 64 位 Debian 8 Jessie - 我想在其中开发代码的开发平台

  • 在我的笔记本 (Debian) 和 RPi2 (Raspbian) 之间启动并运行 SSH 后,我开始四处寻找如何设置我最喜欢的 C/C++ IDE 的教程。 Qt Creator 用于开发 RPi2 的应用程序。项目工具是cmake (我在下面提到这一点,因为另一个选项 - 使用 qmake - 也可用并且更容易使用,但对于我的项目 cmake 是强制性的)。

    这里的关键词是类(class)交叉编译远程部署 .
  • Getting the toolchain for the cross-compilation - 主要用于 arm-linux-gnueabihf-g++,这是交叉编译所必需的(我不想使用 CodeSourcery g++ )。文章指出 armhf 用于 RPi2,这就是为什么我特别选择了这个编译器
  • Configure Qt Creator Part 1 - Adding a Linux device, a development kit and compiler - 基本上在这里你告诉 Qt Creator 你的目标平台,在这种情况下,RPi2 被认为是一个通用的 Linux 设备,并添加 ARM 编译器并生成一个开发工具包,我称之为 RPi2 套件 :

  • Adding the ARM compiler

    Creating a development kit
  • Configure Qt Creator Part 2 - Changing build, run and deployment configuration for the CMake project :
  • 构建配置正在添加新创建的工具包(请参阅
    2)):

  • enter image description here

    确认将使用 RPi2 套件构建项目:

    enter image description here
  • 部署配置就是简单的添加一个 QtCreatorDeployment.txt 在 CMake 项目的根文件夹中:
        sftp://192.168.1.102/
        build/RPiCrossCompileRemoteTest:home/pi/Projects
    

    第一行表示部署前缀,第二行描述可执行文件(在左侧)的相对本地(在我的笔记本上)路径和相对远程(在我的 RPi2 上)路径。 Qt Creator 的文档还添加了使用 CMakeLists.txt 自动执行此过程的步骤,但作为第一次尝试,我认为最好手动完成。如果需要,您也可以添加多个路径(在我的情况下我不这样做,因为我无法让单个路径工作-_-)。

    其他步骤涉及更改项目部署部分中的一些内容(在运行配置中找到) - 检查可用空间(我决定这样做,以防我开始构建大型应用程序并且空间用完比我管理的更快跟踪:3),通过 SFTP 上传文件,最后我添加了运行自定义远程命令,该命令只是将一些愚蠢的消息写入文本文件(在我的 RPi2 上!)作为日志:

  • enter image description here
  • 项目的运行配置也应该是轻而易举的。我唯一改变的是将项目的工作目录设置为 RPi2 上的远程位置:

  • enter image description here

    最后这里是我使用的代码:
    #include <fstream>
    #include <string>
    #include <iostream>
    
    int main()
    {
      std::cout << "Writing to remote system...";
    
      try
      {
        std::string input = "This is a cross-compilation and remote deployment test for Raspberry Pi using Qt Creator";
        std::ofstream out("remote_log.txt");
        out << input;
        out.close();
      }
      catch(std::exception e)
      {
        std::cout << "Failed" << std::endl;
        return 1;
      }
    
      std::cout << "Successful" << std::endl;
    
      return 0;
    }
    

    随着 CMakeLists.txt :
    project(RPiCrossCompileRemoteTest)
    cmake_minimum_required(VERSION 2.8)
    aux_source_directory(. SRC_LIST)
    add_executable(${PROJECT_NAME} ${SRC_LIST})
    

    一切都好吗?错误的!这是我无法弄清楚我遗漏了什么或做错了什么的地方 - 当我构建我的项目时,生成的二进制文件适用于我的笔记本架构。这是命令 file RPiCrossCompileRemoteTest 的输出:
    RPiCrossCompileRemoteTest: ELF 64-bit LSB executable, x86-64, version 1
    (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for
    GNU/Linux 2.6.32, BuildID[sha1]=73a819def72e496aab31127add9fb52df2ac2c47,
    not stripped
    

    是的,它说得很清楚 - x86-64。部署不会导致任何错误(SSH 连接成功, 文本 文件写入 RPi2 没有任何问题),也不会在我的笔记本上运行二进制文件(通过 Qt Creator 或终端)。然而,我注意到的另一件事是,出于某种原因,SFTP 没有上传我的二进制文件。是的,二进制文件的架构不正确,我将无法在我的 RPi2 上执行它,但它仍然应该上传对吗?

    我还通过手动编译我的主程序并生成二进制文件来检查是否由于某种原因我选择了错误的编译器:
    :~$ arm-linux-gnueabihf-g++ main.cpp -o RPiCrossCompileRemoteTest_Manual
    

    我得到了一个不错的 ARM 二进制文件,我可以在我的 RPi2 上复制和运行它。来自 file RPiCrossCompileRemoteTest_Manual 输出的额外确认还向我展示了:
    RPiCrossCompileRemoteTest_Manual: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV),
    dynamically linked, interpreter /lib/ld-linux-armhf.so.3, for GNU/Linux 
    2.6.32, BuildID[sha1]=8aca4ed570c44a51a820c6aa56e6257129e0c949, not stripped
    

    我不知道我做错了什么。我有一种感觉,我非常非常接近让这件事发挥作用,但唉!我几个小时的努力都白费了。

    非常感谢帮助!

    PS:请注意,我还没有设置调试器。这是我计划在启动和运行基础知识并阅读有关远程调试的更多信息后下一步要做的事情。

    最佳答案

    好的,我让编译工作了。问题出在 CMakeLists.txt 中。您必须指定目标系统和编译器。 Qt Creator 不会自动执行此操作,因为它会从 CMakeLists.txt 读取所有这些内容,尽管这让我想知道定义一个工具包(以及与之捆绑的编译器和调试器)有什么好处,如果您无论如何都要手动完成所有操作.可能这仅在您使用 Qt 项目时有效。将不得不检查它。无论如何,这里是扭转局面的路线:

    INCLUDE(CMakeForceCompiler)
    
    # Set OS and processor architecture
    set(CMAKE_SYSTEM_NAME Linux)
    set(CMAKE_SYSTEM_PROCESSOR arm)
    set(CMAKE_SYSTEM_VERSION 1)
    
    # Specify the compilers
    set(CMAKE_CXX_COMPILER arm-linux-gnueabihf-g++)
    

    至于通过 SFTP 上传的问题,似乎是 的文档。 QtCreatorDeployment.txt 以非常困惑的方式编写。我注意到它会自动附加项目的根路径。它的实际作用远非如此。它只是接管并在内部接管它。所以基本上我的部署配置文件中只剩下远程路径。我试过
    sftp://192.168.1.102/home/pi/Projects/
    

    它没有用。但是,如果您删除 sftp 和 IP 地址,它实际上可以工作,因为 Qt Creator 会自动从设备配置中提取 IP 地址部分。所以最后 QtCreatorDeployment.txt 只是这一行(如果需要,您可以添加多个):
    /home/pi/Projects/
    

    以下是它在 Qt Creator 中的显示方式:

    enter image description here
  • 这完全由 Qt Creator 自动完成。也许可以改变它,但在我的情况下它工作得很好
  • 这是从 中提取的内容QtCreatorDeployment.txt .它的显示方式令人困惑,因为人们希望远程设备的 IP 地址也能显示出来。由于设备配置,它仍然存在。

  • 就是这样!现在我可以将我的 ARM 二进制文件正确部署到远程系统。

    关于linux - Qt Creator 为 Raspberry Pi 2 进行交叉编译和远程部署的正确设置 - 为错误的架构生成二进制文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32027057/

    相关文章:

    c - select(2) 保证能够无阻塞地写入文件的数据量是多少

    c - pthread_cond_signal 导致死锁

    apache - 启动部署架构-在没有Apache的情况下运行Glassfish V3前奏

    linux - 多核处理器之间的区别

    c++ - 在 Arm 板上编译的 makefile 编译错误

    arm - 在 OMAP 4460 上进行多个 DMA 传输时,CPU 是否被阻塞?

    linux - 使用非 gcc 编译 linux 内核

    linux - 如何使用 awk 过滤文件并根据第二个字段 Linux 排序命令?

    .net - ClickOnce 部署 CheckForDetailedUpdate 抛出异常

    gradle - 将Gradle项目部署到Artifactory