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

rba*_*dar 5 linux deployment arm qt-creator raspberry-pi2

我只是经历了地狱般的设置我的 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(我在下面提到这个,因为另一个选项 - using qmake- 也可用并且更容易使用,但对于我的项目cmake是强制性的)。

这里的关键词当然是交叉编译远程部署

  1. 获取交叉编译的工具链- 主要用于 arm-linux-gnueabihf-g++,这是交叉编译所必需的(我不想使用CodeSourcery g++)。文章指出armhf适用于 RPi2,这就是我特别选择这个编译器的原因

  2. 配置 Qt Creator 第 1 部分 - 添加 Linux 设备、开发工具包和编译器- 基本上在这里您告诉 Qt Creator 您的目标平台,在这种情况下,RPi2 被认为是通用 Linux 设备,并添加 ARM 编译器并生成开发套件,我称之为RPi2 套件

添加ARM编译器

创建开发套件

  1. 配置 Qt Creator 第 2 部分 - 更改 CMake 项目的构建、运行和部署配置

    • 构建配置正在添加新创建的工具包(参见 2)):

在此处输入图片说明

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

在此处输入图片说明

  • 部署配置只是在CMake项目的根文件夹中添加一个QtCreatorDeployment.txt

        sftp://192.168.1.102/
        build/RPiCrossCompileRemoteTest:home/pi/Projects
    
    Run Code Online (Sandbox Code Playgroud)

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

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

在此处输入图片说明

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

在此处输入图片说明

最后这里是我使用的代码:

#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;
}
Run Code Online (Sandbox Code Playgroud)

连同CMakeLists.txt

project(RPiCrossCompileRemoteTest)
cmake_minimum_required(VERSION 2.8)
aux_source_directory(. SRC_LIST)
add_executable(${PROJECT_NAME} ${SRC_LIST})
Run Code Online (Sandbox Code Playgroud)

一切都好吗?错误的!这是我无法弄清楚我遗漏了什么或做错了什么的地方 - 当我构建我的项目时,生成的二进制文件适用于我的笔记本架构。这是命令的输出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
Run Code Online (Sandbox Code Playgroud)

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

我还通过手动编译我的 main 并生成二进制文件来检查是否由于某种原因我选择了错误的编译器:

:~$ arm-linux-gnueabihf-g++ main.cpp -o RPiCrossCompileRemoteTest_Manual
Run Code Online (Sandbox Code Playgroud)

我得到了一个不错的 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
Run Code Online (Sandbox Code Playgroud)

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

非常感谢帮助!

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

rba*_*dar 5

好的,我让编译工作了。问题出在 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++)
Run Code Online (Sandbox Code Playgroud)

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

sftp://192.168.1.102/home/pi/Projects/
Run Code Online (Sandbox Code Playgroud)

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

/home/pi/Projects/
Run Code Online (Sandbox Code Playgroud)

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

在此处输入图片说明

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

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

  • 当你在你的项目上运行 `cmake`(也可以在 Qt Creator 中运行)时,你需要传递 `-DCMAKE_TOOLCHAIN_FILE=&lt;toolchain-file&gt;.cmake`。在该文件中,您可以设置根文件系统、Qt 的交叉编译版本(如果有的话)、交叉编译标志、环境设置、链接设置等。但是这与 `QtCreatorDeployment.txt` 无关,并且是纯粹的‘cmake’魔法。 (2认同)