Qt for HarmonyOS/user development/deveco cmake guide cross compile zh

From Qt Wiki
Jump to navigation Jump to search

DevEco Studio 使用 CMake 开发 Qt 应用(交叉编译)

本文以 Qt 官方 Qt Widgets 示例 calculator(位于 qtbase/examples/widgets/widgets/calculator)为例,说明如何在 DevEco Studio 中通过 CMake 编译并运行一个 Qt 应用(HarmonyOS Stage 工程 + Native C++)。


1. 前置条件

  1. 已安装 DevEco Studio,并配置好 OHOS SDK(包含 `native` 工具链、CMake、Ninja)。
  2. 已准备好 Qt for HarmonyOS 的交叉编译安装目录(Qt 前缀目录),并确认其中存在:lib/cmake/Qt5/Qt5Config.cmake
  3. 已准备好鸿蒙模板工程,可参考:[1](https://wiki.qt.io/Qt_for_HarmonyOS_Source_Code_zh#HarmonyOS%E5%BA%94%E7%94%A8%E6%A8%A1%E6%9D%BF)
  4. 已准备好运行 Qt 所需的运行时库(至少包括 libqohos.so 以及 Qt 依赖库)。

工程内示例路径:

  • Qt for HarmonyOS 交叉编译安装目录(示例):
 /Users/dev/Qt/5.12.12/ohos-arm64-v8a-clang
  • Qt 运行时库放置目录:
 entry/libs/arm64-v8a/

2. 鸿蒙模板工程结构速览(calculator)

2.1 C++(Qt 应用本体)

  • entry/src/main/cpp/main.cpp:Qt 应用入口 main()
  • entry/src/main/cpp/calculator.cpp / calculator.h:Calculator UI 与逻辑
  • entry/src/main/cpp/button.cpp / button.h:按钮控件
  • entry/src/main/cpp/CMakeLists.txt:CMake 构建脚本(生成 libcalculator.so)

2.2 ArkTS 胶水代码

  • entry/src/main/ets/common/QtAppConstants.ets:配置要加载的 Qt 应用库名
 export const APP_LIBRARY_NAME = 'libcalculator.so';

3. 在 DevEco Studio 中配置 CMake

3.1 指定 CMakeLists 和 Qt 前缀目录

编辑模块级 entry/build-profile.json5,配置 externalNativeOptions:

{
  "buildOption": {
    "externalNativeOptions": {
      "path": "./src/main/cpp/CMakeLists.txt",
      "arguments": "-DCMAKE_PREFIX_PATH=/Users/dev/Qt/5.12.12/ohos-arm64-v8a-clang",
      "abiFilters": ["arm64-v8a"]
    }
  }
}

说明:

  • path:指向本模块的 CMake 入口文件
  • arguments:关键参数 -DCMAKE_PREFIX_PATH,必须指向 Qt 的安装前缀目录
  • abiFilters:需与目标设备 ABI 匹配,否则可能导致库无法加载或打包失败

4. CMakeLists.txt 怎么写

4.1 查找 Qt(find_package)

工程中的 entry/src/main/cpp/CMakeLists.txt 使用如下方式查找 Qt:

  • find_package(QT NAMES Qt5 Qt6 REQUIRED COMPONENTS Core)
  • find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core Widgets)

在交叉编译场景下,需要注意 OHOS SDK 的 toolchain 默认设置了:

set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)

该设置位于:

DevEco-Studio/Contents/sdk/default/openharmony/native/build/cmake/ohos.toolchain.cmake

当该模式为 ONLY 时,如果 Qt 安装在 sysroot 之外(通常如此),即使传入 CMAKE_PREFIX_PATH, find_package(Qt5) 也可能找不到 Qt5Config.cmake。

因此需要在查找 Qt 前临时放宽策略:

  • 在 find_package() Qt 前设置:
 set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE BOTH)
  • Qt 找到后立即恢复原值,避免影响其它依赖
if(CMAKE_CROSSCOMPILING)
set(_saved_root_path_mode_package "${CMAKE_FIND_ROOT_PATH_MODE_PACKAGE}")
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE BOTH)
endif()

find_package(QT NAMES Qt5 Qt6 REQUIRED COMPONENTS Core)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core Widgets)

if(CMAKE_CROSSCOMPILING)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE "${_saved_root_path_mode_package}")
unset(_saved_root_path_mode_package)
endif()

4.2 生成库名需与 ArkTS 配置一致

当前示例中:

  • CMake:
 * add_library(calculator SHARED ...)
 * 生成 libcalculator.so
  • ArkTS:
 在QtAppConstants.ets 中:
   APP_LIBRARY_NAME = 'libcalculator.so'

若修改 CMake target 名称(如 myapp),请同步修改:

  • QtAppConstants.ets 中的 APP_LIBRARY_NAME

4.3 CMakeLists.txt 完整示例(calculator)

以下示例可直接用于模板工程 entry/src/main/cpp/CMakeLists.txt:

cmake_minimum_required(VERSION 3.5)
project(ohosQtTemplate)

set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)

# OHOS toolchains commonly set CMAKE_FIND_ROOT_PATH_MODE_PACKAGE=ONLY for
# cross-compiling, which prevents CMake from finding Qt via CMAKE_PREFIX_PATH
# when Qt is installed outside the sysroot.

if(CMAKE_CROSSCOMPILING)
set(_saved_root_path_mode_package "${CMAKE_FIND_ROOT_PATH_MODE_PACKAGE}")
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE BOTH)
endif()

find_package(QT NAMES Qt5 Qt6 REQUIRED COMPONENTS Core)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core Widgets)

if(CMAKE_CROSSCOMPILING)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE "${_saved_root_path_mode_package}")
unset(_saved_root_path_mode_package)
endif()

set(NATIVERENDER_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR})

include_directories(
${NATIVERENDER_ROOT_PATH}
${NATIVERENDER_ROOT_PATH}/include
)

set(PROJECT_SOURCES
main.cpp
button.cpp
calculator.cpp
)

add_library(calculator SHARED
${PROJECT_SOURCES}
)

target_link_libraries(calculator
PRIVATE
Qt${QT_VERSION_MAJOR}::Core
Qt${QT_VERSION_MAJOR}::Widgets
)

5. 构建与运行(DevEco Studio)

  1. 使用 DevEco Studio 打开工程根目录:ohostemplateforqtapplication
  2. 确认已选择正确的 product / target(如 default)和 ABI(如 arm64-v8a)
  3. 点击 Build / Run(或执行 hvigor 任务),Native 构建阶段会触发 `compileNative`
  4. 安装到设备或模拟器后启动应用,Qt UI 会由 QAbilityStage 拉起并显示

6. 运行时库(Qt / 插件)如何放置

Native .so 需放置在 OHOS 约定目录:

  • entry/libs/<abi>/

至少需要保证以下库被打包进 HAP:

  • Qt OHOS QPA:libqohos.so
  • Qt 依赖库:libQt5Core.so、libQt5Gui.so、libQt5Widgets.so 等
  • 应用库:libcalculator.so

判断依赖缺失的方法: 运行时日志中通常会出现:

  • dlopen failed
  • cannot locate symbol
  • cannot load ...so

7. 将 Calculator 替换为你的 Qt 应用

最小操作步骤:

1. 将你的 Qt 源码放入 entry/src/main/cpp/(或子目录)

2. 修改 entry/src/main/cpp/CMakeLists.txt:

  • 更新 PROJECT_SOURCES
  • find_package() 增加所需模块(如 Network、Quick)

3. 保证生成库名与 APP_LIBRARY_NAME 一致

4. 将所需 Qt 运行时 .so / 插件复制到 entry/libs/<abi>/