HarmonyOS 6.1 云应用客户端适配实战(一):环境搭建与编译系统

前言

随着 HarmonyOS 生态的快速发展,越来越多的应用需要从 Android 平台迁移到 HarmonyOS。本系列文章将以一个真实的云应用客户端项目为例,详细记录从 Android 到 HarmonyOS 6.1 的完整适配过程。

项目背景:

  • 原项目是一个基于 WebSocket 的云桌面/云应用客户端
  • 使用 C++ 实现核心功能(视频解码、网络通信、输入处理)
  • Android 端使用 JNI 封装,HarmonyOS 需要改用 N-API
  • 依赖多个第三方库:OpenSSL、FFmpeg、Protobuf、Poco、Boost 等

本文作为系列第一篇,重点介绍环境搭建和编译系统的适配工作。

一、开发环境准备

1.1 工具链安装

必需工具:

bash 复制代码
# HarmonyOS NDK(包含在 DevEco Studio 中)
路径:D:\Program Files\Huawei\DevEco Studio\sdk\default\openharmony\native

# CMake 3.16+
# Ninja 构建工具
# Python 3.x(用于构建脚本)

关键环境变量:

bash 复制代码
export OHOS_SDK_NATIVE=/path/to/ohos/native
export PATH=$OHOS_SDK_NATIVE/llvm/bin:$PATH

1.2 工具链特点

HarmonyOS NDK 使用的是 LLVM/Clang 工具链,与 Android NDK 类似,但有几个关键差异:

特性 Android NDK HarmonyOS NDK
编译器 Clang (Android 定制) Clang (OpenHarmony)
标准库 libc++ libc++
目标三元组 aarch64-linux-android aarch64-linux-ohos
系统根目录 sysroot sysroot

重点注意: 目标架构名称的差异会影响到第三方库的交叉编译。

二、CMake 配置适配

2.1 平台识别

首先需要在 CMakeLists.txt 中添加 HarmonyOS 平台的识别:

cmake 复制代码
# 检测 HarmonyOS 平台
if(CMAKE_SYSTEM_NAME STREQUAL "OHOS")
    set(OHOS_PLATFORM ON)
    add_definitions(-DOHOS -DOHOS_PLATFORM)
    message(STATUS "Building for HarmonyOS platform")
endif()

2.2 编译器和链接器配置

cmake 复制代码
if(OHOS_PLATFORM)
    # 设置编译器
    set(CMAKE_C_COMPILER "${OHOS_SDK_NATIVE}/llvm/bin/clang")
    set(CMAKE_CXX_COMPILER "${OHOS_SDK_NATIVE}/llvm/bin/clang++")
    
    # 设置 sysroot
    set(CMAKE_SYSROOT "${OHOS_SDK_NATIVE}/sysroot")
    
    # 目标架构
    set(CMAKE_SYSTEM_PROCESSOR aarch64)
    
    # 编译选项
    add_compile_options(
        --target=aarch64-linux-ohos
        --sysroot=${CMAKE_SYSROOT}
        -D__MUSL__
    )
    
    # 链接选项
    add_link_options(
        --target=aarch64-linux-ohos
        --sysroot=${CMAKE_SYSROOT}
    )
endif()

2.3 条件编译宏的使用

在代码中需要大量使用条件编译来区分平台:

cpp 复制代码
// 平台检测示例
#if defined(OHOS) || defined(OHOS_PLATFORM)
    // HarmonyOS 特定代码
    #include <native_window/external_window.h>
    #include <hilog/log.h>
#elif defined(__ANDROID__)
    // Android 特定代码
    #include <android/native_window.h>
    #include <android/log.h>
#elif defined(_WIN32)
    // Windows 特定代码
    #include <windows.h>
#endif

最佳实践:

  • 使用 #if defined(OHOS) || defined(OHOS_PLATFORM) 而不是 #ifdef OHOS
  • 在 CMake 中同时定义两个宏,确保兼容性
  • 关键分支点添加日志,便于排查条件编译错误

三、第三方库交叉编译

3.1 OpenSSL 编译

OpenSSL 是网络通信的基础库,编译步骤:

bash 复制代码
# 配置
./Configure linux-aarch64 \
    --prefix=/path/to/install \
    --cross-compile-prefix=aarch64-linux-ohos- \
    CC=clang \
    --sysroot=$OHOS_SDK_NATIVE/sysroot \
    no-shared \
    no-tests

# 编译
make -j8
make install

关键点:

  1. 使用 linux-aarch64 配置(没有专门的 ohos 配置)
  2. 必须指定 --cross-compile-prefix
  3. 建议编译静态库(no-shared

3.2 FFmpeg 编译

FFmpeg 是视频解码的核心库,配置较为复杂:

bash 复制代码
./configure \
    --prefix=/path/to/install \
    --enable-cross-compile \
    --cross-prefix=aarch64-linux-ohos- \
    --arch=aarch64 \
    --target-os=linux \
    --cc=clang \
    --cxx=clang++ \
    --sysroot=$OHOS_SDK_NATIVE/sysroot \
    --extra-cflags="--target=aarch64-linux-ohos" \
    --extra-ldflags="--target=aarch64-linux-ohos" \
    --disable-shared \
    --enable-static \
    --disable-programs \
    --disable-doc \
    --enable-decoder=h264 \
    --enable-decoder=hevc \
    --enable-parser=h264 \
    --enable-parser=hevc

make -j8
make install

重点配置说明:

  • --target-os=linux:HarmonyOS 内核基于 Linux,使用 linux 配置
  • --extra-cflags--extra-ldflags:必须显式指定目标三元组
  • 裁剪配置:只编译需要的解码器,减小体积

3.3 Protobuf 编译

Protobuf 用于消息序列化,需要注意宿主机和目标机的兼容性:

bash 复制代码
# 第一步:编译宿主机版本(用于生成代码)
mkdir build-host
cd build-host
cmake .. -DCMAKE_INSTALL_PREFIX=/path/to/protobuf-host
make -j8
make install

# 第二步:交叉编译目标版本
mkdir build-ohos
cd build-ohos
cmake .. \
    -DCMAKE_SYSTEM_NAME=OHOS \
    -DCMAKE_C_COMPILER=clang \
    -DCMAKE_CXX_COMPILER=clang++ \
    -DCMAKE_SYSROOT=$OHOS_SDK_NATIVE/sysroot \
    -DCMAKE_C_FLAGS="--target=aarch64-linux-ohos" \
    -DCMAKE_CXX_FLAGS="--target=aarch64-linux-ohos" \
    -Dprotobuf_BUILD_TESTS=OFF \
    -DCMAKE_INSTALL_PREFIX=/path/to/protobuf-ohos

make -j8
make install

为什么需要两个版本?

  • 宿主机版本的 protoc 用于在编译时生成 .pb.cc.pb.h 文件
  • 目标版本的 libprotobuf.a 用于链接到最终的 HarmonyOS 应用中

3.4 Poco 编译

Poco 是一个 C++ 网络库,用于 HTTP 和 WebSocket 通信:

bash 复制代码
mkdir build-ohos
cd build-ohos

cmake .. \
    -DCMAKE_SYSTEM_NAME=Linux \
    -DCMAKE_C_COMPILER=clang \
    -DCMAKE_CXX_COMPILER=clang++ \
    -DCMAKE_SYSROOT=$OHOS_SDK_NATIVE/sysroot \
    -DCMAKE_C_FLAGS="--target=aarch64-linux-ohos" \
    -DCMAKE_CXX_FLAGS="--target=aarch64-linux-ohos -std=c++17" \
    -DENABLE_NETSSL_WIN=OFF \
    -DENABLE_NETSSL=ON \
    -DENABLE_CRYPTO=ON \
    -DENABLE_TESTS=OFF \
    -DCMAKE_INSTALL_PREFIX=/path/to/poco-ohos

make -j8
make install

注意事项:

  • CMAKE_SYSTEM_NAME 使用 Linux 而不是 OHOS
  • 需要启用 ENABLE_NETSSLENABLE_CRYPTO 支持 HTTPS
  • 关闭测试以加快编译速度

四、主项目 CMake 配置

4.1 第三方库集成

cmake 复制代码
# 设置第三方库路径
set(THIRD_PARTY_DIR "${CMAKE_SOURCE_DIR}/3rdparty")

if(OHOS_PLATFORM)
    set(OPENSSL_ROOT "${THIRD_PARTY_DIR}/openssl-ohos")
    set(FFMPEG_ROOT "${THIRD_PARTY_DIR}/ffmpeg-ohos")
    set(PROTOBUF_ROOT "${THIRD_PARTY_DIR}/protobuf-ohos")
    set(POCO_ROOT "${THIRD_PARTY_DIR}/poco-ohos")
endif()

# 添加头文件路径
include_directories(
    ${OPENSSL_ROOT}/include
    ${FFMPEG_ROOT}/include
    ${PROTOBUF_ROOT}/include
    ${POCO_ROOT}/include
)

# 链接库
link_directories(
    ${OPENSSL_ROOT}/lib
    ${FFMPEG_ROOT}/lib
    ${PROTOBUF_ROOT}/lib
    ${POCO_ROOT}/lib
)

4.2 源文件组织

cmake 复制代码
# 公共源文件
set(COMMON_SOURCES
    src/cloud_client.cc
    src/net/control_client.cc
    src/FFmpegDecoder.cpp
    # ... 其他公共文件
)

# 平台特定源文件
if(OHOS_PLATFORM)
    set(PLATFORM_SOURCES
        src/gles/GLViewOHOS.cpp
        src/gles/GLViewBase.cpp
        # ... HarmonyOS 特定文件
    )
elseif(ANDROID)
    set(PLATFORM_SOURCES
        src/gles/GLViewAndroid.cpp
        # ... Android 特定文件
    )
endif()

# 创建静态库
add_library(cloudappclient STATIC
    ${COMMON_SOURCES}
    ${PLATFORM_SOURCES}
)

4.3 链接配置

cmake 复制代码
if(OHOS_PLATFORM)
    target_link_libraries(cloudappclient
        # 系统库
        ace_napi.z
        hilog_ndk.z
        native_window
        EGL
        GLESv3
        
        # 第三方库(注意顺序)
        PocoNetSSL
        PocoNet
        PocoCrypto
        PocoFoundation
        ssl
        crypto
        avcodec
        avutil
        swscale
        protobuf
        pthread
        dl
        z
    )
endif()

链接顺序很重要:

  • 依赖关系:PocoNetSSL → PocoNet → PocoCrypto → OpenSSL
  • 错误的顺序会导致符号未定义错误

五、常见问题与解决方案

5.1 找不到系统头文件

错误信息:

复制代码
fatal error: 'hilog/log.h' file not found

解决方案:

cmake 复制代码
# 显式添加系统头文件路径
include_directories(
    ${OHOS_SDK_NATIVE}/sysroot/usr/include
)

5.2 链接时未定义符号

错误信息:

复制代码
undefined reference to `OH_NativeWindow_CreateNativeWindowFromSurfaceId'

解决方案:

cmake 复制代码
# 确保链接了正确的系统库
target_link_libraries(your_target
    native_window  # 注意:不是 native_window.z
)

5.3 C++ 标准库问题

错误信息:

复制代码
error: no member named 'make_unique' in namespace 'std'

解决方案:

cmake 复制代码
# 设置 C++ 标准为 17 或更高
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

5.4 OpenSSL 版本兼容

如果第三方库(如 Poco)依赖特定版本的 OpenSSL,需确保:

bash 复制代码
# 查看依赖的 OpenSSL 版本
strings libPocoNetSSL.a | grep "OpenSSL"

# 编译时指定 OpenSSL 路径
cmake .. \
    -DOPENSSL_ROOT_DIR=/path/to/openssl-3.x \
    -DOPENSSL_INCLUDE_DIR=/path/to/openssl-3.x/include \
    -DOPENSSL_LIBRARIES="/path/to/openssl-3.x/lib/libssl.a;/path/to/openssl-3.x/lib/libcrypto.a"

六、构建脚本示例

为了简化编译流程,建议编写自动化脚本:

bash 复制代码
#!/bin/bash
# build_ohos.sh

set -e

# 环境变量
export OHOS_SDK_NATIVE="/path/to/ohos/native"
export PATH=$OHOS_SDK_NATIVE/llvm/bin:$PATH

# 创建构建目录
BUILD_DIR="build_ohos_arm64"
rm -rf $BUILD_DIR
mkdir $BUILD_DIR
cd $BUILD_DIR

# 配置
cmake .. \
    -DCMAKE_SYSTEM_NAME=OHOS \
    -DCMAKE_SYSTEM_PROCESSOR=aarch64 \
    -DCMAKE_C_COMPILER=clang \
    -DCMAKE_CXX_COMPILER=clang++ \
    -DCMAKE_SYSROOT=$OHOS_SDK_NATIVE/sysroot \
    -DCMAKE_C_FLAGS="--target=aarch64-linux-ohos" \
    -DCMAKE_CXX_FLAGS="--target=aarch64-linux-ohos -std=c++17" \
    -DCMAKE_BUILD_TYPE=Release \
    -GNinja

# 编译
ninja -j8

# 复制输出文件
cp api/libdlca_cloudapp.so ../output/

echo "Build completed successfully!"

七、总结

本文介绍了 HarmonyOS 6.1 云应用客户端适配的第一步:环境搭建和编译系统配置。关键要点:

  1. 工具链理解 :HarmonyOS NDK 基于 LLVM,目标三元组为 aarch64-linux-ohos
  2. CMake 配置:正确设置编译器、sysroot 和目标架构
  3. 第三方库编译:需要单独交叉编译每个依赖库
  4. 条件编译:使用宏区分不同平台的代码路径
  5. 链接顺序:注意库的依赖关系,避免符号未定义

下一篇预告:

在完成编译系统配置后,下一篇将深入介绍视频渲染的适配,包括 Native Window API 的使用、EGL 初始化、OpenGL ES 纹理渲染等核心功能的实现。

参考资料


作者: Frame Not Work

日期: 2026年6月

系列文章: HarmonyOS 6.1 云应用客户端适配实战

相关推荐
再见6582 小时前
HarmonyOS NEXT 实战:开发一个精美的随机颜色生成器
华为·harmonyos
G_dou_2 小时前
Flutter三方库适配OpenHarmony【color_picker】HSL 调色器项目完整实战
flutter·harmonyos
G_dou_2 小时前
Flutter三方库适配OpenHarmony【random_number】随机数生成器项目完整实战
flutter·harmonyos
FrameNotWork2 小时前
HarmonyOS 6.1 云应用客户端适配实战(三):触摸输入与坐标映射
华为·harmonyos
●VON2 小时前
鸿蒙Flutter实战:日期选择器与截止日期高亮提醒
android·flutter·华为·harmonyos·鸿蒙
●VON3 小时前
鸿蒙Flutter实战:Material 3种子色亮暗双主题系统
android·flutter·harmonyos
慧海灵舟3 小时前
鸿蒙南向开发教程 Day 3:OpenHarmony 线程管理
华为·harmonyos·写文章,赢小鸿ai
想你依然心痛3 小时前
HarmonyOS 6(API 23)实战:打造“光味智厨“——AI烹饪新体验
人工智能·华为·ar·harmonyos·智能体
颜淡慕潇3 小时前
低成本搭建鸿蒙PC运行环境:基于 Docker 的 x86_64 服务器
服务器·docker·harmonyos