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

Qt Creator proper setup for cross-compilation and remote deployment for the Raspberry Pi 2 - producing binaries for wrong architecture

我刚刚费尽心机地设置了我的 Qt Creator、Raspberry Pi 和 Debian 8(用于我的笔记本),并最终成功地配置了所有内容。或者我是这么想的。以下是对我到目前为止所做工作的描述,以便 Whosebug 上的一些聪明人可能会看到我做过(或没做过)的愚蠢行为:D)。

我正在使用以下平台:

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

这里的关键字是课程交叉编译远程部署

  1. Getting the toolchain for the cross-compilation - 主要用于 arm-linux-gnueabihf-g++,这是交叉编译所必需的(我不想使用 CodeSourcery g++).文章指出 armhf 适用于 RPi2,这就是我特别选择此编译器的原因

  2. Configure Qt Creator Part 1 - Adding a Linux device, a development kit and compiler - 基本上在这里你告诉 Qt Creator 你的目标平台在这种情况下是 RPi2 被认为是通用 Linux 设备并添加 ARM 编译器加上生成一个开发工具包,我称之为 RPi2 Kit:

  1. Configure Qt Creator Part 2 - Changing build, run and deployment configuration for the CMake project:

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

项目将使用 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;
}

连同 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 连接成功并且 text 文件写入 RPi2 没有任何问题),运行 二进制文件(通过 Qt Creator 或终端)也不会我的笔记本。然而,我注意到的另一件事是,出于某种原因,SFTP 没有上传我的二进制文件。是的,二进制文件的架构不正确,我无法在我的 RPi2 上执行它,但仍然应该上传它,对吗?

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

:~$ 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:请注意,我还没有设置我的调试器。这是我计划在了解基础知识和 运行ning 并阅读更多有关远程调试的信息后下一步要做的事情。

好的,我已经开始编译了。问题出在 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 中的显示方式:

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

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

正如我刚刚通过自己的尝试根据这个问题配置 QtCreator 部署一样(它具有最详细的描述性说明),我想向任何管理到的人指出以下选项读到这里 post。

不需要使用Cmake自动部署交叉编译的tragets。 Qmake 允许基于 .pro 文件中的 INSTALLS 变量的相同甚至更好的本地方式。可以找到更多详细信息 here