You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Qt 6.5+ Ubuntu 22.04 CMake部署:QML运行时缺失求助

问题:Qt 6.5.3 QML应用Deb打包后运行缺失模块

在Ubuntu 22.04使用官方Qt SDK 6.5.3开发QML应用,按CMake部署流程打包deb后,运行时出现以下错误:

2025-02-17T20:13:24.034 [I] Application: Loading entry point qrc:/qt/qml/noteahead/view/qml/Main.qml
QQmlApplicationEngine failed to load component
qrc:/qt/qml/noteahead/view/qml/Main.qml:20:1: module "QtQuick.Dialogs" is not installed
qrc:/qt/qml/noteahead/view/qml/Main.qml:19:1: module "QtQuick.Controls.Universal" is not installed
qrc:/qt/qml/noteahead/view/qml/Main.qml:18:1: module "QtQuick.Controls" is not installed
qrc:/qt/qml/noteahead/view/qml/Main.qml:17:1: module "QtQuick" is not installed

Ubuntu 22.04仓库仅在24.10及以后版本提供Qt 6.5+包,不想手动添加系统依赖,当前CMakeLists.txt配置如下:

qt_add_qml_module(${BINARY_NAME}
    URI ${URI}
    QML_FILES ${QML_SOURCE_FILES}
    RESOURCES ${SVG_SOURCE_FILES}
)

target_compile_definitions(${BINARY_NAME} PRIVATE $<$<$<OR:$<CONFIG:Debug>,$<CONFIG:RelWithDebInfo>>:QT_QML_DEBUG>)
target_compile_definitions(${BINARY_NAME} PRIVATE QML_ROOT_DIR="${QML_ROOT_DIR}")
target_compile_definitions(${BINARY_NAME} PRIVATE QML_ENTRY_POINT="${MAIN}")
target_link_libraries(${BINARY_NAME} PRIVATE Qt6::Core Qt6::Quick rtmidi SimpleLogger Argengine)

install(TARGETS ${BINARY_NAME}
    RUNTIME DESTINATION bin
)

# Install the executable into "${CMAKE_INSTALL_PREFIX}/bin".
install(TARGETS ${BINARY_NAME}
    BUNDLE DESTINATION .
    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)

# Generate the deployment script for the target Noteahead.
qt_generate_deploy_app_script(
    TARGET ${BINARY_NAME}
    OUTPUT_SCRIPT deploy_script
    NO_UNSUPPORTED_PLATFORM_ERROR
)

# Call the deployment script during "cmake --install".
install(SCRIPT ${deploy_script})

# Set up CPack for Debian packaging
set(CPACK_PACKAGE_NAME "noteahead")
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Noteahead MIDI Tracker")
set(CPACK_PACKAGE_INSTALL_DIRECTORY ${CPACK_PACKAGE_NAME})
set(CPACK_VERBATIM_VARIABLES ON)
set(CPACK_PACKAGING_INSTALL_PREFIX "/opt/noteahead")
set(CPACK_DEBIAN_PACKAGE_DEPENDS libc6 libstdc++6 libgcc-s1 libasound2 librtmidi6)
include(CPack)

解决方案

1. 明确链接所有依赖的QML模块

Qt部署脚本需要识别目标依赖的QML模块,需在target_link_libraries中添加对应CMake目标:

target_link_libraries(${BINARY_NAME} PRIVATE 
    Qt6::Core 
    Qt6::Quick 
    Qt6::QuickControls2 
    Qt6::QuickDialogs 
    Qt6::QuickControlsUniversal
    rtmidi 
    SimpleLogger 
    Argengine
)

这些目标对应代码中用到的QtQuick.Controls、QtQuick.Dialogs等模块,只有明确链接,部署脚本才会打包对应的QML运行时文件。

2. 优化部署脚本生成参数

添加--qmldir参数帮助脚本扫描QML源码目录,确保捕获所有依赖模块:

qt_generate_deploy_app_script(
    TARGET ${BINARY_NAME}
    OUTPUT_SCRIPT deploy_script
    NO_UNSUPPORTED_PLATFORM_ERROR
    EXTRA_ARGS --qmldir ${CMAKE_SOURCE_DIR}/path/to/your/qml/source
)

替换${CMAKE_SOURCE_DIR}/path/to/your/qml/source为实际QML源码根目录。

3. 移除重复的安装指令

当前配置中有两段重复的install(TARGETS),保留一段即可避免冲突:

install(TARGETS ${BINARY_NAME}
    BUNDLE DESTINATION .
    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)

4. 验证部署结果

执行cmake --install后,检查安装目录(如/opt/noteahead)下是否生成qml目录,其中应包含QtQuick、QtQuick.Controls等子目录,这些就是打包的QML模块文件。

5. 手动设置QML导入路径(可选)

若仍存在模块找不到的问题,可在应用启动代码中添加导入路径配置:

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QDir>

int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);

    QQmlApplicationEngine engine;
    // 指向安装目录下的qml文件夹
    QString qmlPath = QCoreApplication::applicationDirPath() + "/../qml";
    engine.addImportPath(qmlPath);

    const QUrl url(u"qrc:/qt/qml/noteahead/view/qml/Main.qml"_qs);
    QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
                     &app, [url](QObject *obj, const QUrl &objUrl) {
        if (!obj && url == objUrl)
            QCoreApplication::exit(-1);
    }, Qt::QueuedConnection);
    engine.load(url);

    return app.exec();
}

内容的提问来源于stack exchange,提问作者juzzlin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 06:57:32