HarmonyOS 6.1 云应用客户端适配实战(一):环境搭建与编译系统
前言随着 HarmonyOS 生态的快速发展越来越多的应用需要从 Android 平台迁移到 HarmonyOS。本系列文章将以一个真实的云应用客户端项目为例详细记录从 Android 到 HarmonyOS 6.1 的完整适配过程。项目背景原项目是一个基于 WebSocket 的云桌面/云应用客户端使用 C 实现核心功能视频解码、网络通信、输入处理Android 端使用 JNI 封装HarmonyOS 需要改用 N-API依赖多个第三方库OpenSSL、FFmpeg、Protobuf、Poco、Boost 等本文作为系列第一篇重点介绍环境搭建和编译系统的适配工作。一、开发环境准备1.1 工具链安装必需工具# HarmonyOS NDK包含在 DevEco Studio 中路径D:\Program Files\Huawei\DevEco Studio\sdk\default\openharmony\native# CMake 3.16# Ninja 构建工具# Python 3.x用于构建脚本关键环境变量exportOHOS_SDK_NATIVE/path/to/ohos/nativeexportPATH$OHOS_SDK_NATIVE/llvm/bin:$PATH1.2 工具链特点HarmonyOS NDK 使用的是LLVM/Clang工具链与 Android NDK 类似但有几个关键差异特性Android NDKHarmonyOS NDK编译器Clang (Android 定制)Clang (OpenHarmony)标准库libclibc目标三元组aarch64-linux-androidaarch64-linux-ohos系统根目录sysrootsysroot重点注意目标架构名称的差异会影响到第三方库的交叉编译。二、CMake 配置适配2.1 平台识别首先需要在 CMakeLists.txt 中添加 HarmonyOS 平台的识别# 检测 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 编译器和链接器配置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( --targetaarch64-linux-ohos --sysroot${CMAKE_SYSROOT} -D__MUSL__ ) # 链接选项 add_link_options( --targetaarch64-linux-ohos --sysroot${CMAKE_SYSROOT} ) endif()2.3 条件编译宏的使用在代码中需要大量使用条件编译来区分平台// 平台检测示例#ifdefined(OHOS)||defined(OHOS_PLATFORM)// HarmonyOS 特定代码#includenative_window/external_window.h#includehilog/log.h#elifdefined(__ANDROID__)// Android 特定代码#includeandroid/native_window.h#includeandroid/log.h#elifdefined(_WIN32)// Windows 特定代码#includewindows.h#endif最佳实践使用#if defined(OHOS) || defined(OHOS_PLATFORM)而不是#ifdef OHOS在 CMake 中同时定义两个宏确保兼容性关键分支点添加日志便于排查条件编译错误三、第三方库交叉编译3.1 OpenSSL 编译OpenSSL 是网络通信的基础库编译步骤# 配置./Configure linux-aarch64\--prefix/path/to/install\--cross-compile-prefixaarch64-linux-ohos-\CCclang\--sysroot$OHOS_SDK_NATIVE/sysroot\no-shared\no-tests# 编译make-j8makeinstall关键点使用linux-aarch64配置没有专门的 ohos 配置必须指定--cross-compile-prefix建议编译静态库no-shared3.2 FFmpeg 编译FFmpeg 是视频解码的核心库配置较为复杂./configure\--prefix/path/to/install\--enable-cross-compile\--cross-prefixaarch64-linux-ohos-\--archaarch64\--target-oslinux\--ccclang\--cxxclang\--sysroot$OHOS_SDK_NATIVE/sysroot\--extra-cflags--targetaarch64-linux-ohos\--extra-ldflags--targetaarch64-linux-ohos\--disable-shared\--enable-static\--disable-programs\--disable-doc\--enable-decoderh264\--enable-decoderhevc\--enable-parserh264\--enable-parserhevcmake-j8makeinstall重点配置说明--target-oslinuxHarmonyOS 内核基于 Linux使用 linux 配置--extra-cflags和--extra-ldflags必须显式指定目标三元组裁剪配置只编译需要的解码器减小体积3.3 Protobuf 编译Protobuf 用于消息序列化需要注意宿主机和目标机的兼容性# 第一步编译宿主机版本用于生成代码mkdirbuild-hostcdbuild-host cmake..-DCMAKE_INSTALL_PREFIX/path/to/protobuf-hostmake-j8makeinstall# 第二步交叉编译目标版本mkdirbuild-ohoscdbuild-ohos cmake..\-DCMAKE_SYSTEM_NAMEOHOS\-DCMAKE_C_COMPILERclang\-DCMAKE_CXX_COMPILERclang\-DCMAKE_SYSROOT$OHOS_SDK_NATIVE/sysroot\-DCMAKE_C_FLAGS--targetaarch64-linux-ohos\-DCMAKE_CXX_FLAGS--targetaarch64-linux-ohos\-Dprotobuf_BUILD_TESTSOFF\-DCMAKE_INSTALL_PREFIX/path/to/protobuf-ohosmake-j8makeinstall为什么需要两个版本宿主机版本的protoc用于在编译时生成.pb.cc和.pb.h文件目标版本的libprotobuf.a用于链接到最终的 HarmonyOS 应用中3.4 Poco 编译Poco 是一个 C 网络库用于 HTTP 和 WebSocket 通信mkdirbuild-ohoscdbuild-ohos cmake..\-DCMAKE_SYSTEM_NAMELinux\-DCMAKE_C_COMPILERclang\-DCMAKE_CXX_COMPILERclang\-DCMAKE_SYSROOT$OHOS_SDK_NATIVE/sysroot\-DCMAKE_C_FLAGS--targetaarch64-linux-ohos\-DCMAKE_CXX_FLAGS--targetaarch64-linux-ohos -stdc17\-DENABLE_NETSSL_WINOFF\-DENABLE_NETSSLON\-DENABLE_CRYPTOON\-DENABLE_TESTSOFF\-DCMAKE_INSTALL_PREFIX/path/to/poco-ohosmake-j8makeinstall注意事项CMAKE_SYSTEM_NAME使用Linux而不是OHOS需要启用ENABLE_NETSSL和ENABLE_CRYPTO支持 HTTPS关闭测试以加快编译速度四、主项目 CMake 配置4.1 第三方库集成# 设置第三方库路径 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 源文件组织# 公共源文件 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 链接配置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解决方案# 显式添加系统头文件路径 include_directories( ${OHOS_SDK_NATIVE}/sysroot/usr/include )5.2 链接时未定义符号错误信息undefined reference to OH_NativeWindow_CreateNativeWindowFromSurfaceId解决方案# 确保链接了正确的系统库 target_link_libraries(your_target native_window # 注意不是 native_window.z )5.3 C 标准库问题错误信息error: no member named make_unique in namespace std解决方案# 设置 C 标准为 17 或更高 set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON)5.4 OpenSSL 版本兼容如果第三方库如 Poco依赖特定版本的 OpenSSL需确保# 查看依赖的 OpenSSL 版本strings libPocoNetSSL.a|grepOpenSSL# 编译时指定 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六、构建脚本示例为了简化编译流程建议编写自动化脚本#!/bin/bash# build_ohos.shset-e# 环境变量exportOHOS_SDK_NATIVE/path/to/ohos/nativeexportPATH$OHOS_SDK_NATIVE/llvm/bin:$PATH# 创建构建目录BUILD_DIRbuild_ohos_arm64rm-rf$BUILD_DIRmkdir$BUILD_DIRcd$BUILD_DIR# 配置cmake..\-DCMAKE_SYSTEM_NAMEOHOS\-DCMAKE_SYSTEM_PROCESSORaarch64\-DCMAKE_C_COMPILERclang\-DCMAKE_CXX_COMPILERclang\-DCMAKE_SYSROOT$OHOS_SDK_NATIVE/sysroot\-DCMAKE_C_FLAGS--targetaarch64-linux-ohos\-DCMAKE_CXX_FLAGS--targetaarch64-linux-ohos -stdc17\-DCMAKE_BUILD_TYPERelease\-GNinja# 编译ninja-j8# 复制输出文件cpapi/libdlca_cloudapp.so../output/echoBuild completed successfully!七、总结本文介绍了 HarmonyOS 6.1 云应用客户端适配的第一步环境搭建和编译系统配置。关键要点工具链理解HarmonyOS NDK 基于 LLVM目标三元组为aarch64-linux-ohosCMake 配置正确设置编译器、sysroot 和目标架构第三方库编译需要单独交叉编译每个依赖库条件编译使用宏区分不同平台的代码路径链接顺序注意库的依赖关系避免符号未定义下一篇预告在完成编译系统配置后下一篇将深入介绍视频渲染的适配包括 Native Window API 的使用、EGL 初始化、OpenGL ES 纹理渲染等核心功能的实现。参考资料HarmonyOS NDK 开发指南CMake Cross CompilingFFmpeg Compilation Guide作者Frame Not Work日期2026年6月系列文章HarmonyOS 6.1 云应用客户端适配实战