Qt for HarmonyOS/user development guide/deveco cmake guide cross compile
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
- DevEco Studio is installed, and the OHOS SDK (including native toolchain, CMake, Ninja) is configured properly.
- 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
- 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)
- 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)
- Open the project root directory with DevEco Studio: ohostemplateforqtapplication
- Confirm that the correct product / target (e.g., default) and ABI (e.g., arm64-v8a) are selected
- Click Build / Run (or execute hvigor task), the compileNative will be triggered during the Native build phase
- 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>/