Jump to content

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

From Qt Wiki
Revision as of 07:19, 29 January 2026 by Shawn Luo (talk | contribs) (Created page with " '''English''' 中文 = Developing Qt Applications with CMake in DevEco Studio (Cross Compilation) = This document uses the official Qt Qt Widgets example '''calculator''' (located at qtbase/examples/widgets/widgets/calculator) to illustrate how to compile and run a Qt application (HarmonyOS Stage Project + Native C++) via '''CMake''' in '''DevEco Studio'''. == 1. Prerequisites == # '''D...")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

English 中文

Developing Qt Applications with CMake in DevEco Studio (Cross Compilation)

This document uses the official Qt Qt Widgets example calculator (located at qtbase/examples/widgets/widgets/calculator) to illustrate how to compile and run a Qt application (HarmonyOS Stage Project + Native C++) via CMake in DevEco Studio.


1. Prerequisites

  1. DevEco Studio is installed, and the OHOS SDK (including native toolchain, CMake, Ninja) is configured properly.
  2. The cross-compiled installation directory (Qt prefix directory) of Qt for HarmonyOS is prepared, and confirm that the file exists: lib/cmake/Qt5/Qt5Config.cmake
  3. The HarmonyOS template project is prepared, refer to: [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. The runtime libraries required for running Qt are prepared (at least including libqohos.so and Qt dependency libraries).

Example paths in the project:

  • Qt for HarmonyOS cross-compiled installation directory (example):
 /Users/dev/Qt/5.12.12/ohos-arm64-v8a-clang
  • Qt runtime library placement directory:
 entry/libs/arm64-v8a/

2. Quick Overview of HarmonyOS Template Project Structure (calculator)

2.1 C++ (Qt Application Body)

  • entry/src/main/cpp/main.cpp: Qt application entry main()
  • entry/src/main/cpp/calculator.cpp / calculator.h: Calculator UI and logic
  • entry/src/main/cpp/button.cpp / button.h: Button widget
  • entry/src/main/cpp/CMakeLists.txt: CMake build script (generates libcalculator.so)

2.2 ArkTS Glue Code

  • entry/src/main/ets/common/QtAppConstants.ets: Configure the name of the Qt application library to be loaded
 export const APP_LIBRARY_NAME = 'libcalculator.so';

3. Configure CMake in DevEco Studio

3.1 Specify CMakeLists and Qt Prefix Directory

Edit the module-level entry/build-profile.json5 and configure 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"]
    }
  }
}

Explanation:

  • path: Points to the CMake entry file of this module
  • arguments: Key parameter -DCMAKE_PREFIX_PATH, must point to the Qt installation prefix directory
  • abiFilters: Must match the target device ABI, otherwise it may cause library loading failure or packaging failure

4. How to Write CMakeLists.txt

4.1 Find Qt (find_package)

The entry/src/main/cpp/CMakeLists.txt in the project finds Qt in the following way:

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

In cross-compilation scenarios, note that the OHOS SDK toolchain sets the following by default:

set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)

This setting is located at:

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

When this mode is ONLY, if Qt is installed outside the sysroot (usually the case), even if CMAKE_PREFIX_PATH is passed in, find_package(Qt5) may fail to find Qt5Config.cmake.

Therefore, it is necessary to temporarily relax the policy before finding Qt:

  • Set before find_package() Qt:
 set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE BOTH)
  • Restore the original value immediately after Qt is found to avoid affecting other dependencies
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 Generated Library Name Must Match ArkTS Configuration

In the current example:

  • CMake:
 add_library(calculator SHARED ...)
 Generates libcalculator.so
  • ArkTS: In QtAppConstants.ets:
   APP_LIBRARY_NAME = 'libcalculator.so'

If you modify the CMake target name (e.g., myapp), please modify it synchronously:

  • APP_LIBRARY_NAME in QtAppConstants.ets

4.3 Complete Example of CMakeLists.txt (calculator)

The following example can be directly used in the template project 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. Build and Run (DevEco Studio)

  1. Open the project root directory with DevEco Studio: ohostemplateforqtapplication
  2. Confirm that the correct product / target (e.g., default) and ABI (e.g., arm64-v8a) are selected
  3. Click Build / Run (or execute hvigor task), the compileNative will be triggered during the Native build phase
  4. After installing to the device or emulator and starting the application, the Qt UI will be pulled up and displayed by QAbilityStage

6. How to Place Runtime Libraries (Qt / Plugins)

Native .so files need to be placed in the directory specified by OHOS:

  • entry/libs/<abi>/

At least ensure the following libraries are packaged into the HAP:

  • Qt OHOS QPA: libqohos.so
  • Qt dependency libraries: libQt5Core.so, libQt5Gui.so, libQt5Widgets.so, etc.
  • Application library: libcalculator.so

Method to judge missing dependencies: Runtime logs usually show:

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

7. Replace Calculator with Your Qt Application

Minimum operation steps:

1. Put your Qt source code into entry/src/main/cpp/ (or subdirectory)

2. Modify entry/src/main/cpp/CMakeLists.txt:

  • Update PROJECT_SOURCES
  • Add required modules to find_package() (e.g., Network, Quick)

3. Ensure the generated library name is consistent with APP_LIBRARY_NAME

4. Copy the required Qt runtime .so / plugins to entry/libs/<abi>/