目录

概述

本文档详细介绍了如何将 Google Protocol Buffers (protobuf) 3.25.2 适配到 HarmonyOS 平台,包括交叉编译配置、CMake 构建系统集成、以及 HarmonyOS Native Package (HNP) 打包过程。

项目信息:

  • 库名称: Protocol Buffers (protobuf)
  • 版本: 3.25.2
  • 构建系统: CMake
  • 目标平台: HarmonyOS (aarch64-linux-ohos)
  • 仓库地址: git@gitcode.com:nutpi/protobuf.git
  • Tag: v3.25.2-harmonyos

Protocol Buffers 简介

Protocol Buffers(简称 protobuf)是 Google 开发的一种语言无关、平台无关的序列化结构化数据的机制。它提供了一种高效、可扩展的方式来序列化结构化数据,常用于:

  • 数据交换格式: 用于不同服务之间的数据通信
  • 配置文件: 用于存储和读取配置信息
  • RPC 通信: 作为 gRPC 等 RPC 框架的数据序列化格式
  • 数据存储: 用于持久化结构化数据

主要特性

  • 高效: 比 XML 和 JSON 更小、更快
  • 跨语言: 支持 C++、Java、Python、Go、C# 等多种语言
  • 向后兼容: 支持字段的添加和删除,保持向后兼容
  • 强类型: 通过 .proto 文件定义数据结构,提供类型安全

开发环境

移植环境说明:该命令基于build配置框架进行移植编译,环境搭建可以参考文章《开源软件鸿蒙化适配与构建指南(交叉编译)》,主要是ohos sdk的下载配置和build配置框架的下载使用说明。

项目名称 Protocol Buffers (protobuf)
开源协议 GPL-2.0-or-later
源码版本 3.25.2
目标平台 aarch64-linux-ohos
依赖项 OpenHarmony SDK、CMake
操作系统平台 OpenHarmony PC
源码地址 https://gitcode.com/nutpi/protobuf

基本使用

  1. 定义 .proto 文件:
syntax = "proto3";

message Person {
  string name = 1;
  int32 id = 2;
  string email = 3;
}
  1. 编译 .proto 文件:
protoc --cpp_out=. person.proto
  1. 在代码中使用:
#include "person.pb.h"

Person person;
person.set_name("John Doe");
person.set_id(1234);
person.set_email("john@example.com");

// 序列化
std::string serialized;
person.SerializeToString(&serialized);

// 反序列化
Person deserialized_person;
deserialized_person.ParseFromString(serialized);

适配准备

环境要求

  • HarmonyOS SDK: 已配置交叉编译工具链
  • CMake: 3.16 或更高版本(推荐使用 DevEco Studio SDK 自带的 CMake)
  • 构建工具: make、tar、gzip
  • 网络连接: 构建过程中需要下载 Abseil 依赖

目录结构

code/protobuf/
├── build_ohos.sh          # HarmonyOS 构建脚本
├── hnp.json               # HNP 配置文件
├── CMakeLists.txt         # CMake 主配置文件
├── src/                   # 源代码目录
├── cmake/                 # CMake 模块
└── build_ohos/           # 构建输出目录(自动生成)

构建脚本详解

build_ohos.sh 脚本结构

构建脚本 build_ohos.sh 主要包含以下部分:

1. 环境变量设置
export PROTOBUF_INSTALL_HNP_PATH=${HNP_PUBLIC_PATH}/protobuf.org/protobuf_3.25.2

设置安装路径,遵循 HNP 包命名规范:{组织}.{域名}/{包名}_{版本}

2. CMake 检测

脚本会按以下顺序查找 CMake:

  1. PATH 环境变量中的 cmake
  2. DevEco Studio SDK 的 CMake:
    /Applications/DevEco-Studio.app/Contents/sdk/default/openharmony/native/build-tools/cmake/bin/cmake
    
  3. Homebrew 安装的 CMake: /opt/homebrew/bin/cmake
  4. 传统路径: /usr/local/bin/cmake

如果都找不到,脚本会给出清晰的错误提示和安装建议。

3. CMake 配置
${CMAKE_CMD} .. \
    -DCMAKE_BUILD_TYPE=Release \
    -DCMAKE_INSTALL_PREFIX=${PROTOBUF_INSTALL_HNP_PATH} \
    -DCMAKE_SYSTEM_NAME=Linux \
    -DCMAKE_SYSTEM_PROCESSOR=aarch64 \
    -DCMAKE_C_COMPILER="${CC}" \
    -DCMAKE_CXX_COMPILER="${CXX}" \
    -DCMAKE_C_FLAGS="${CFLAGS}" \
    -DCMAKE_CXX_FLAGS="${CXXFLAGS}" \
    -DCMAKE_EXE_LINKER_FLAGS="${LDFLAGS}" \
    -DCMAKE_SHARED_LINKER_FLAGS="${LDFLAGS}" \
    -DCMAKE_SYSROOT="${SYSROOT}" \
    -Dprotobuf_BUILD_TESTS=OFF \
    -Dprotobuf_BUILD_EXAMPLES=OFF \
    -DBUILD_SHARED_LIBS=OFF \
    -DCMAKE_POSITION_INDEPENDENT_CODE=ON

关键配置说明:

  • CMAKE_SYSTEM_NAME=Linux: 指定目标系统为 Linux(HarmonyOS 基于 Linux 内核)
  • CMAKE_SYSTEM_PROCESSOR=aarch64: 指定目标架构为 ARM64
  • CMAKE_SYSROOT: 指定 HarmonyOS SDK 的 sysroot 路径
  • BUILD_SHARED_LIBS=OFF: 构建静态库(适合 HarmonyOS 应用分发)
  • protobuf_BUILD_TESTS=OFF: 禁用测试构建(交叉编译环境无法运行测试)
  • protobuf_BUILD_EXAMPLES=OFF: 禁用示例构建(减少构建时间)
  • CMAKE_POSITION_INDEPENDENT_CODE=ON: 启用位置无关代码(PIC),便于静态库链接
4. 构建和安装
# 构建(并行编译)
${CMAKE_CMD} --build . --config Release --parallel $(sysctl -n hw.ncpu)

# 安装到指定目录
${CMAKE_CMD} --install . --config Release
5. HNP 打包
# 复制 HNP 配置文件
cp hnp.json ${PROTOBUF_INSTALL_HNP_PATH}/

# 打包为 HNP 格式
${HNP_TOOL} pack -i ${PROTOBUF_INSTALL_HNP_PATH} -o ${ARCHIVE_PATH}/

# 创建 tar.gz 归档
tar -zvcf ${ARCHIVE_PATH}/ohos_protobuf_3.25.2.tar.gz protobuf_3.25.2/

遇到的问题及解决方案

问题 1: CMake 未安装

错误信息:

build_ohos.sh: line 40: cmake: command not found
Error: CMake configuration failed

原因分析:
系统未安装 CMake,或者 CMake 不在 PATH 环境变量中。

解决方案:

  1. 使用 DevEco Studio SDK 的 CMake(推荐):
    脚本会自动检测并使用 DevEco Studio SDK 自带的 CMake(版本 3.28.2)。

  2. 手动安装 CMake:

    # macOS (如果 Homebrew 可用)
    brew install cmake
    
    # 或从官网下载
    # https://cmake.org/download/
    
  3. 添加到 PATH:
    如果 CMake 已安装但不在 PATH 中,可以添加到 .zshrc.bashrc:

    export PATH="/path/to/cmake/bin:$PATH"
    

问题 2: Homebrew CMake 安装失败

错误信息:

Error: Cask 'cmake' definition is invalid: 'conflicts_with' stanza failed

原因分析:
Homebrew 的 CMake cask 定义存在问题,可能是版本冲突或配置错误。

解决方案:
使用 DevEco Studio SDK 的 CMake,脚本已自动支持检测该路径。

问题 3: 依赖下载问题

现象:
CMake 配置时会自动下载 Abseil 依赖:

-- Could NOT find absl (missing: absl_DIR)
-- Fallback to downloading Abseil 20250512.1 from GitHub

解决方案:
这是正常行为。protobuf 依赖 Abseil(Google 的 C++ 基础库),CMake 会自动从 GitHub 下载。确保:

  • 网络连接正常
  • 可以访问 GitHub(可能需要代理)

如果下载失败,可以:

  1. 配置 Git 代理
  2. 手动下载 Abseil 并放到 third_party/ 目录
  3. 使用镜像源

问题 4: ZLIB 未找到

警告信息:

-- Could NOT find ZLIB (missing: ZLIB_LIBRARY) (found version "1.3.1")

原因分析:
CMake 找到了 ZLIB 的版本信息,但找不到库文件路径。

解决方案:
这个警告通常不影响构建。protobuf 可以编译,但某些压缩功能可能不可用。如果需要完整的 ZLIB 支持,可以:

  1. 在 HarmonyOS SDK 中安装 ZLIB
  2. 通过 CMake 变量指定 ZLIB 路径:
    -DZLIB_ROOT=/path/to/zlib
    

构建流程

完整构建步骤

  1. 准备环境:

    # 设置 HarmonyOS SDK 路径
    export OHOS_SDK=/path/to/ohosdk
    
    # 运行主构建脚本
    ./build.sh --sdk ${OHOS_SDK}
    
  2. 构建过程:

    • CMake 配置(检测工具链、下载依赖)
    • 编译源代码(C++ 编译器)
    • 安装到指定目录
    • 打包为 HNP 格式
  3. 输出文件:

    • ${ARCHIVE_PATH}/protobuf.hnp - HNP 格式包
    • ${ARCHIVE_PATH}/ohos_protobuf_3.25.2.tar.gz - 压缩归档

构建时间

  • CMake 配置: 约 1-2 分钟(包括下载 Abseil)
  • 编译: 约 5-10 分钟(取决于 CPU 核心数)
  • 安装和打包: 约 30 秒

总计: 约 7-13 分钟

使用示例

在 HarmonyOS 应用中使用 protobuf

1. 定义 .proto 文件

创建 person.proto:

syntax = "proto3";

package tutorial;

message Person {
  string name = 1;
  int32 id = 2;
  string email = 3;
  
  enum PhoneType {
    MOBILE = 0;
    HOME = 1;
    WORK = 2;
  }
  
  message PhoneNumber {
    string number = 1;
    PhoneType type = 2;
  }
  
  repeated PhoneNumber phones = 4;
}
2. 编译 .proto 文件
# 使用交叉编译的 protoc
${PROTOBUF_INSTALL_HNP_PATH}/bin/protoc \
  --cpp_out=. \
  --proto_path=. \
  person.proto
3. 在 C++ 代码中使用
#include "person.pb.h"
#include <iostream>
#include <fstream>

int main() {
    // 创建 Person 对象
    tutorial::Person person;
    person.set_name("John Doe");
    person.set_id(1234);
    person.set_email("john@example.com");
    
    // 添加电话号码
    tutorial::Person::PhoneNumber* phone = person.add_phones();
    phone->set_number("123-456-7890");
    phone->set_type(tutorial::Person::MOBILE);
    
    // 序列化到文件
    std::fstream output("person.pb", 
                       std::ios::out | std::ios::binary | std::ios::trunc);
    if (!person.SerializeToOstream(&output)) {
        std::cerr << "Failed to write person." << std::endl;
        return -1;
    }
    output.close();
    
    // 从文件反序列化
    tutorial::Person person2;
    std::fstream input("person.pb", std::ios::in | std::ios::binary);
    if (!person2.ParseFromIstream(&input)) {
        std::cerr << "Failed to parse person." << std::endl;
        return -1;
    }
    
    // 读取数据
    std::cout << "Name: " << person2.name() << std::endl;
    std::cout << "ID: " << person2.id() << std::endl;
    std::cout << "Email: " << person2.email() << std::endl;
    
    return 0;
}
4. 编译应用
# 使用 HarmonyOS SDK 工具链
${CC} -std=c++17 \
  -I${PROTOBUF_INSTALL_HNP_PATH}/include \
  -L${PROTOBUF_INSTALL_HNP_PATH}/lib \
  person.pb.cc main.cpp \
  -lprotobuf \
  -o person_app

在 HarmonyOS Native 应用中使用

在 HarmonyOS Native 应用的 CMakeLists.txt 中:

cmake_minimum_required(VERSION 3.16)
project(PersonApp)

set(CMAKE_CXX_STANDARD 17)

# 查找 protobuf
find_package(Protobuf REQUIRED)

# 编译 .proto 文件
protobuf_generate_cpp(PROTO_SRCS PROTO_HDRS person.proto)

# 添加可执行文件
add_executable(person_app 
    main.cpp
    ${PROTO_SRCS}
)

# 链接 protobuf
target_link_libraries(person_app 
    ${Protobuf_LIBRARIES}
)

target_include_directories(person_app PRIVATE
    ${Protobuf_INCLUDE_DIRS}
)

总结

适配要点

  1. CMake 构建系统: protobuf 使用 CMake,需要正确配置交叉编译工具链
  2. 依赖管理: protobuf 依赖 Abseil,CMake 会自动下载
  3. 静态库构建: 构建静态库便于 HarmonyOS 应用分发
  4. 工具链配置: 正确设置编译器、链接器和 sysroot

优势

  • 标准化: protobuf 是业界标准的数据序列化格式
  • 高效: 序列化后的数据体积小、速度快
  • 跨语言: 支持多种编程语言,便于不同服务间通信
  • 向后兼容: 支持字段的添加和删除,保持 API 兼容性

应用场景

  • 微服务通信: 服务间的数据交换
  • 配置文件: 结构化配置的存储和读取
  • 数据持久化: 高效的数据存储格式
  • RPC 框架: 作为 gRPC 等 RPC 框架的基础

后续工作

  • 测试 protobuf 在 HarmonyOS 上的完整功能
  • 优化构建脚本,支持更多配置选项
  • 添加使用文档和示例代码
  • 集成到 HarmonyOS 应用开发工具链

相关链接:

Logo

赋能鸿蒙PC开发者,共建全场景原生生态,共享一次开发多端部署创新价值。

更多推荐