系列导读:本文是 Lycium 适配系列的最后一篇,提供完整的快速入门步骤、HPKBUILD 最小模板、以及一个从零到一的完整适配案例。适合打印出来作为桌面速查手册。

欢迎加入【开源鸿蒙PC社区】,一起共建鸿蒙化C/C++三方库生态。

前言

项目 说明
macOS环境配置 https://bxming.blog.csdn.net/article/details/159284830
Ubuntu环境配置(或者windows + wsl) https://bxming.blog.csdn.net /article/details/159284760
lycium框架 https://atomgit.com/OpenHarmonyPCDeveloper/lycium_plusplus.git
应用平台 HarmonyOS PC

系列索引

篇章 标题 内容
第一篇 概述与环境配置 Lycium 概念、构建机要求、OHOS SDK 配置
第二篇 项目结构与适配目录创建 目录结构、community vs thirdparty、创建适配目录
第三篇 HPKBUILD 编写详解 元数据字段、过程函数、三种构建系统写法
第四篇 构建执行与产物获取 构建流程、日志分析、多库递归、HAP 集成
第五篇 流程图与角色职责 完整流程图、各角色职责、协作时序
第六篇 关键注意事项与最佳实践 依赖管理、架构超集、日志调试、外部适配仓
第七篇 快速参考与模板 入门步骤、模板、完整案例、检查清单

1. 最快的入门步骤

如果你已经有一定经验,只想快速上手,按以下步骤操作即可:

1.1 环境准备

# 设置 OHOS SDK 路径(必需)
export OHOS_SDK=/home/user/ohos-sdk/linux

# 验证
ls $OHOS_SDK/native/llvm/bin/aarch64-linux-ohos-clang

提示:建议将 export OHOS_SDK=... 写入 ~/.bashrc~/.zshrc,避免每次打开终端都需要重新设置。

1.2 获取框架

git clone https://atomgit.com/OpenHarmonyPCDeveloper/lycium_plusplus.git
cd lycium_plusplus

### 1.3 验证环境:构建一个官方已适配的库

```shell
./build.sh cJSON

构建成功后,检查产物:

# 检查产物
ls usr/cJSON/arm64-v8a/
# 应包含 include/ lib/ 等目录

# 确认架构正确
file usr/cJSON/arm64-v8a/lib/libcjson.so
# 输出:ELF 64-bit LSB shared object, ARM aarch64, ...

1.4 创建自己的适配

# 创建适配目录
mkdir -p thirdparty/mylib

# 编写 HPKBUILD(从最小模板开始)
vim thirdparty/mylib/HPKBUILD

# 编写 README.OpenSource
vim thirdparty/mylib/README.OpenSource

1.5 构建

./build.sh mylib

1.6 查看产物

# 检查产物
ls usr/mylib/arm64-v8a/

# 查看构建日志(如果失败)
tail -100 thirdparty/mylib/mylib-1.0.0-arm64-v8a-lycium_build.log

2. HPKBUILD 最小模板

2.1 CMake 项目模板(最常用)

pkgname=mylib
pkgver=1.0.0
pkgrel=0
archs=("armeabi-v7a" "arm64-v8a")
license=("MIT")
depends=()
source="https://github.com/example/$pkgname/archive/refs/tags/v$pkgver.tar.gz"
builddir=$pkgname-$pkgver
packagename=$builddir.tar.gz

prepare() {
    mkdir -p $builddir/$ARCH-build
}

build() {
    cd $builddir
    ${OHOS_SDK}/native/build-tools/cmake/bin/cmake "$@" \
        -DOHOS_ARCH=$ARCH -B$ARCH-build -S./ -L > $buildlog 2>&1
    $MAKE -C $ARCH-build >> $buildlog 2>&1
    ret=$?
    cd $OLDPWD
    return $ret
}

package() {
    cd $builddir
    $MAKE -C $ARCH-build install >> $buildlog 2>&1
    cd $OLDPWD
}

cleanbuild() {
    rm -rf ${PWD}/$builddir
}

2.2 configure(autotools)项目模板

pkgname=mylib
pkgver=1.0.0
pkgrel=0
archs=("armeabi-v7a" "arm64-v8a")
license=("LGPL-2.1-only")
depends=()
buildtools="configure"
source="https://ftp.example.com/$pkgname-$pkgver.tar.gz"
builddir=$pkgname-$pkgver
packagename=$builddir.tar.gz

prepare() {
    cd $builddir
    # 如果需要重新生成 configure 脚本
    # autoreconf -fi
    mkdir -p $ARCH-build
    cd $OLDPWD
}

build() {
    cd $builddir
    export PKG_CONFIG_PATH="${pkgconfigpath}"
    ./configure "$@" $buildargs \
        --host=${ARCH_TRIPLE} \
        CC=$CC CXX=$CXX \
        CFLAGS="$CFLAGS" \
        LDFLAGS="$LDFLAGS" \
        > $buildlog 2>&1
    $MAKE >> $buildlog 2>&1
    ret=$?
    cd $OLDPWD
    return $ret
}

package() {
    cd $builddir
    $MAKE install >> $buildlog 2>&1
    cd $OLDPWD
}

cleanbuild() {
    rm -rf ${PWD}/$builddir
}

2.3 纯 Makefile 项目模板

pkgname=mylib
pkgver=1.0.0
pkgrel=0
archs=("armeabi-v7a" "arm64-v8a")
license=("BSD-3-Clause")
depends=()
buildtools="make"
source="https://github.com/example/$pkgname/archive/v$pkgver.tar.gz"
builddir=$pkgname-$pkgver
packagename=$builddir.tar.gz

prepare() {
    cd $builddir
    mkdir -p $ARCH-build
    cd $OLDPWD
}

build() {
    cd $builddir
    # 通过命令行传递变量到 Makefile
    $MAKE CC=$CC CXX=$CXX AR=$AR \
        CFLAGS="$CFLAGS" \
        LDFLAGS="$LDFLAGS" \
        >> $buildlog 2>&1
    ret=$?
    cd $OLDPWD
    return $ret
}

package() {
    cd $builddir
    # 注意 PREFIX 还是 DESTDIR 取决于具体 Makefile
    $MAKE DESTDIR=$LYCIUM_ROOT/usr/$pkgname/$ARCH/ \
        PREFIX=/ install >> $buildlog 2>&1
    cd $OLDPWD
}

cleanbuild() {
    rm -rf ${PWD}/$builddir
}

3. 完整适配案例:以 cJSON 为例

下面以 cJSON(一个轻量级 JSON 解析库)为例,展示从零开始的完整适配流程。

3.1 准备阶段

# 查看上游代码
# cJSON 在 GitHub 上:https://github.com/DaveGamble/cJSON

# 获取版本信息
# 上游最新稳定版:1.7.15
# 构建系统:CMake(有 CMakeLists.txt)
# 许可证:MIT

3.2 创建适配目录

mkdir -p thirdparty/cJSON/docs

3.3 编写 HPKBUILD

pkgname=cJSON
pkgver=1.7.15
pkgrel=0
pkgdesc="Ultralightweight JSON parser in ANSI C"
url="https://github.com/DaveGamble/cJSON"
archs=("armeabi-v7a" "arm64-v8a")
license=("MIT")
depends=()
makedepends=("cmake")
source="https://github.com/DaveGamble/cJSON/archive/refs/tags/v$pkgver.tar.gz"
builddir=$pkgname-$pkgver
packagename=$builddir.tar.gz

prepare() {
    mkdir -p $builddir/$ARCH-build
}

build() {
    cd $builddir
    ${OHOS_SDK}/native/build-tools/cmake/bin/cmake "$@" \
        -DOHOS_ARCH=$ARCH \
        -B$ARCH-build -S./ -L \
        -DENABLE_CJSON_TEST=OFF \
        -DBUILD_SHARED_LIBS=ON \
        -DBUILD_STATIC_LIBS=ON \
        > $buildlog 2>&1
    $MAKE -C $ARCH-build >> $buildlog 2>&1
    ret=$?
    cd $OLDPWD
    return $ret
}

package() {
    cd $builddir
    $MAKE -C $ARCH-build install >> $buildlog 2>&1
    cd $OLDPWD
}

cleanbuild() {
    rm -rf ${PWD}/$builddir
}

3.4 编写 README.OpenSource

[
    {
        "Name": "cJSON",
        "License": "MIT",
        "License File": "LICENSE",
        "Version Number": "1.7.15",
        "Upstream URL": "https://github.com/DaveGamble/cJSON",
        "Description": "Ultralightweight JSON parser in ANSI C"
    }
]

3.5 生成 SHA512SUM

# 下载源码
cd thirdparty/cJSON
wget https://github.com/DaveGamble/cJSON/archive/refs/tags/v1.7.15.tar.gz \
    -O cJSON-1.7.15.tar.gz

# 生成校验值
sha512sum cJSON-1.7.15.tar.gz > SHA512SUM

# 验证
sha512sum -c SHA512SUM

3.6 执行构建

cd lycium
./build.sh cJSON

3.7 验证产物

# 检查安装目录
ls -la usr/cJSON/arm64-v8a/
# 输出:
# include/
#   ├── cJSON.h
# lib/
#   ├── libcjson.so
#   ├── libcjson.a
#   ├── libcjson.so.1.7.15
#   └── pkgconfig/
#       └── libcjson.pc

# 验证架构
file usr/cJSON/arm64-v8a/lib/libcjson.so
# ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), dynamically linked

# 查看导出符号
$OHOS_SDK/native/llvm/bin/llvm-nm -D usr/cJSON/arm64-v8a/lib/libcjson.so | grep "cJSON_Parse"
# 输出:0000000000001234 T cJSON_Parse

4. 常用命令速查表

4.1 环境相关

命令 用途
export OHOS_SDK=/path/to/ohos-sdk/linux 设置 SDK 路径
ls $OHOS_SDK/native/llvm/bin/*ohos* 确认交叉编译器可用
file usr/<pkgname>/<arch>/lib/*.so 验证产物的目标架构

4.2 构建相关

命令 用途
./build.sh <pkgname> 构建单个库
./build.sh <pkgA> <pkgB> <pkgC> 同时构建多个库
./build_local.sh <pkgname> 鸿蒙本机构建
tail -f script/<pkgname>-*-<arch>-lycium_build.log 实时查看构建日志
grep -i error script/<pkgname>-*.log 搜索构建错误

4.3 调试相关

命令 用途
sha512sum -c SHA512SUM 验证源码包完整性
diff -uNr orig-dir/ new-dir/ > patch.patch 生成补丁文件
sha512sum <file> > SHA512SUM 生成新的校验文件
cat usr/hpk_build.csv 查看所有已构建库的记录

5. 文件编写检查清单

适配完成后,对照以下清单逐项检查:

必需文件

  • HPKBUILD — pkgname、pkgver、pkgrel、archs、license、source、builddir、packagename 是否完整?
  • prepare() — 是否创建了构建目录?是否需要打 patch?
  • build() — 是否使用了 $buildlog 重定向?$buildargs 是否正确传递?
  • package() — 是否正确安装产物?
  • cleanbuild() — 是否清理了构建目录?
  • README.OpenSource — JSON 格式是否正确?许可证是否匹配?

可选但推荐的文件

  • SHA512SUM — 是否已生成?与源码包是否一致?
  • <pkgname>_oh_pkg.patch — 是否有源码级修改?patch 是否干净可复用?
  • OAT.xml — 开源合规配置
  • hnp.json — HNP 打包配置
  • docs/hap_integrate.md — HAP 集成指南

构建验证

  • 所有声明的 archs 是否都构建成功?
  • 产物中是否包含 .so.a 文件?
  • 头文件是否完整?
  • file 命令确认产物架构正确?
  • 依赖库是否都就绪?

6. 常见问题排查指南

Q1: SHA512SUM 校验失败

# 错误提示
ERROR: SHA512SUM mismatch for xxx.tar.gz

# 解决方法
# 1. 确认下载的文件没有损坏(重新下载)
wget -O xxx.tar.gz <source-url>
# 2. 重新生成校验值
sha512sum xxx.tar.gz > SHA512SUM

Q2: configure 找不到依赖库

# 错误提示
# configure: error: Package requirements (openssl >= 1.1) were not met

# 解决方法
# 1. 确认依赖库已构建且产物在 usr/ 下
ls usr/openssl/arm64-v8a/lib/

# 2. 在 HPKBUILD 中添加 depends
depends=("openssl" "zlib")

# 3. 确保 pkg-config 路径正确
# 框架会自动注入 $pkgconfigpath,无需手动设置

Q3: cmake 找不到 Toolchain 文件

# 错误提示
# CMake Error: CMake was unable to find a build program corresponding to "Unix Makefiles".
# CMAKE_TOOLCHAIN_FILE=... not found

# 解决方法
# 1. 确认 OHOS_SDK 路径正确
echo $OHOS_SDK
# 2. 确认 toolchain 文件存在
ls $OHOS_SDK/native/build-tools/cmake/ohos.toolchain.cmake
# 3. 使用 $buildargs 而非手动指定 toolchain
# 框架会自动注入 -DCMAKE_TOOLCHAIN_FILE=...

Q4: 编译错误 undefined reference to xxx

# 错误原因
# 通常是链接顺序问题或缺少必要的库

# 解决方法
# 1. 检查 makedepends 或 depends 是否完整
# 2. 在 build() 中手动添加链接库
# 例如添加 -lssl -lcrypto
# 3. 如果是 C++ 库,确认使用了 extern "C" 或 g++ 编译

# 排查命令
grep -A20 "BUILD ERROR" script/mylib-arm64-v8a-lycium_build.log

Q5: 产物架构不对

# 验证产物
file usr/mylib/arm64-v8a/lib/libmylib.so
# 正确输出:ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), dynamically linked

# 如果输出是 x86_64 或 wrong architecture
# 说明编译器环境变量没有正确传递
# 检查 HPKBUILD 中是否使用了 $CC $CXX 等框架变量

# 强制指定编译器
# 在 build() 中打印环境变量
echo "CC=$CC CXX=$CXX" >> $buildlog

Q6: 多次构建后缓存导致问题

# 现象:修改 HPKBUILD 后重新构建,行为不变

# 解决方法
# 1. 清理构建目录
./build.sh mylib --clean

# 2. 或者手动清理
rm -rf usr/mylib/* output/* script/mylib-*

# 3. 重新构建
./build.sh mylib

Q7: 本机调试时使用 build_local.sh 但编译失败

# 确保 OHOS SDK 已正确设置
export OHOS_SDK=/path/to/ohos/sdk

# 查看日志
tail -f script/mylib-arm64-v8a-lycium_build.log

# 常见问题:本机 clang 版本过高,不兼容 OHOS NDK
# 解决方法:确认使用的是 OHOS SDK 中的 LLVM 工具链
which aarch64-linux-ohos-clang

Q8: 如何定位构建失败的具体行

# 方法 1: 搜索错误关键词
grep -i "error:" script/mylib-arm64-v8a-lycium_build.log | tail -20

# 方法 2: 从后往前查看最后 100 行
tail -100 script/mylib-arm64-v8a-lycium_build.log

# 方法 3: 实时查看(重新构建时)
./build.sh mylib 2>&1 | tee /tmp/build.log

总结

至此,Lycium C/C++ 三方库适配系列博文全部完成。七个篇章覆盖了从环境搭建、目录结构、HPKBUILD 编写、构建执行、产物获取到最佳实践的完整流程。

希望这个系列能帮助你在 OpenHarmony 生态中高效完成 C/C++ 三方库的适配工作!

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐