0%

macOS下使用CLion远程开发调试Linux上的QtGUI程序

在macOS下使用CLion集成开发环境,配合macOS的X11环境XQuartz, 实现在macOS下编码,调试.在远程Linux主机上编译,运行Qt程序. 通过SSH的X11转发功能在macOS上显示程序界面.

由于需要开发Linux下的GUI程序,但是又不喜欢使用Linux的桌面环境, 适逢CLion2018.3新增远程开发功能,尝试了一下,嗯,可以远程构建并调试QtGUI程序.

开发环境
macOS 10.14.1 , XQuartz 2.7.11, CLion 2018.3, Qt5.9.7
Ubuntu Server 18.04 , gcc/g++ 7.3.0, gdb 8.1, Qt 5.9.5, cmake 3.10

实现原理

CLion在2018.3版中新增了远程开发功能(这个功能都被呼吁好几年了,现在终于补上了).虽然按照官方说明就可以开发一般的控制台程序了,但是还不能直接开发GUI程序.
因为CLion与目标系统间的连接,并没有进行X11转发,所以理论上只需要配置好X11转发通道,再提供一个X11 Server,就能显示GUI程序了.
首先macOS下有XQuartz程序,这样X11 Server有了.
然后在macOS下的控制台,使用ssh程序登录目标Linux系统(带 -X 选项),这样就有了X11转发通道.
最后在CLion中配置项目,在启动目标Linux系统上的程序时,提供X11 Server的地址(程序通过环境变量DISPLAY获取X11 Server地址),这样就可以成功启动并调试目标程序啦.

准备开发环境

macOS

  1. 安装CLion 2018.3
    CLion 的 远程构建 功能是2018.3版本新加入的, 远程调试 功能比较早就实现了, 不过这次没有使用老版本的远程调试功能.
  2. 安装XQuartz
    最新版本是2.7.11, 2016年10月29日发布的, 好几年都没更新了.
  3. 安装Qt
    主要是需要使用 Qt Designer 工具, 不使用工具,手写 ui 文件也可以.

Ubuntu

  1. 安装构建工具
    1
    sudo apt install gcc g++ gdb cmake
  2. 安装Qt
    1
    sudo apt install qtbase5-dev qt5-default qtdeclarative5-dev qttools5-dev

创建项目

  1. 首先建立一个C++项目,使用C++11标准.

  2. 新建 qttest.h, qttest.cpp 文件.
    qttest.h

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    #ifndef QT_TEST_H
    #define QT_TEST_H

    #include <QWidget>
    #include "ui_qttest.h"

    class qttest : public QWidget
    {
    Q_OBJECT
    public:
    qttest(QWidget *parent = 0);
    ~qttest();
    private:
    Ui::qttest_ui ui;
    };

    #endif // QT_TEST_H

    qttest.cpp

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    #include "qttest.h"

    qttest::qttest(QWidget *parent) : QWidget(parent)
    {
    ui.setupUi(this);
    }

    qttest::~qttest()
    {

    }
  3. 使用 Qt Designer 程序新建 qttest.ui文件,注意窗口对象的名称需要与 qttest.h 中ui对象的类型名一致

  4. 改写 main.cpp 文件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    #include "qttest.h"
    #include <QtWidgets/QApplication>

    int main(int argc, char *argv[])
    {
    QApplication a(argc, argv);
    qttest w;
    w.show();
    return a.exec();
    }
  5. 编辑 CMakeLists.txt 文件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    cmake_minimum_required(VERSION 3.10)
    set(CMAKE_CXX_STANDARD 11)

    # 自动将当前源代码和构建目录添加到包含路径
    set(CMAKE_INCLUDE_CURRENT_DIR ON)
    # 指示CMake在需要时自动运行moc
    set(CMAKE_AUTOMOC ON)

    # 兼容macOS下构建
    if(APPLE)
    message("apple\n")
    set(CMAKE_PREFIX_PATH /Users/tang/Qt/5.9.7/clang_64)
    set(QLIBDIR "/Users/tang/Qt/5.9.7/clang_64/lib" )
    endif(APPLE)

    project(qttest)

    # 查找QtWidgets包
    find_package(Qt5Widgets)

    #从ui文件创建cpp代码
    qt5_wrap_ui(ui_qttest.h qttest.ui)

    add_executable(qttest main.cpp qttest.cpp qttest.ui)
    target_link_libraries( qttest Qt5::Widgets )

配置CLion

  1. 进入 Preferences/Build,Execution,Deployment/Toolchains 页面
  2. 选择 Remote Host 选项
  3. 增加一个工具链并配置目标系统登录选项 Credentials
  4. 然后配置工具链路径,配置完成后如图所示
  5. 进入 Preferences/Build,Execution,Deployment/CMake 页面
  6. 添加一个配置, Toolchain 选项要选择之前配置的远程工具链
  7. 在macOS启动XQuartz程序,然后在终端下使用 ssh -X ubuntu@192.168.56.101 命令登录Ubuntu系统
  8. 登陆后,使用 echo $DISPLAY 命令查看 X11 服务器的转发地址,我的地址为 “localhost:10.0”
  9. 在CLion下,进入项目配置页面
  10. 编辑 Environment variables ,新增 DISPLAY 变量

编译并运行程序

配置都完成后,就可以编译程序了. 编译完成后的运行效果如图

如果程序启动失败,控制台输出

1
2
3
4
qt.qpa.screen: QXcbConnection: Could not connect to display localhost:10.0
Could not connect to any X display.

Process finished with exit code 1

那是因为X11 Server 连接已经断开,使用 ssh -X ubuntu@192.168.56.101 命令重新登录Ubuntu即可解决.