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.8.1.

  3. 安装Qt 主要是需要使用 Qt Designer 工具, 不使用工具,手写 ui 文件也可以.

Ubuntu

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

创建项目

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

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

    // qttest.h
    #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  
    #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 文件

    #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 文件

    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 变量

编译并运行程序

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


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

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即可解决.