系列导读:本文是 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 环境准备
shell
# 设置 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 获取框架
shell
git clone https://atomgit.com/OpenHarmonyPCDeveloper/lycium_plusplus.git
cd lycium_plusplus
### 1.3 验证环境:构建一个官方已适配的库
```shell
./build.sh cJSON
构建成功后,检查产物:
shell
# 检查产物
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 创建自己的适配
shell
# 创建适配目录
mkdir -p thirdparty/mylib
# 编写 HPKBUILD(从最小模板开始)
vim thirdparty/mylib/HPKBUILD
# 编写 README.OpenSource
vim thirdparty/mylib/README.OpenSource
1.5 构建
shell
./build.sh mylib
1.6 查看产物
shell
# 检查产物
ls usr/mylib/arm64-v8a/
# 查看构建日志(如果失败)
tail -100 thirdparty/mylib/mylib-1.0.0-arm64-v8a-lycium_build.log
2. HPKBUILD 最小模板
2.1 CMake 项目模板(最常用)
bash
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)项目模板
bash
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 项目模板
bash
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 准备阶段
shell
# 查看上游代码
# cJSON 在 GitHub 上:https://github.com/DaveGamble/cJSON
# 获取版本信息
# 上游最新稳定版:1.7.15
# 构建系统:CMake(有 CMakeLists.txt)
# 许可证:MIT
3.2 创建适配目录
shell
mkdir -p thirdparty/cJSON/docs
3.3 编写 HPKBUILD
bash
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
json
[
{
"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
shell
# 下载源码
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 执行构建
shell
cd lycium
./build.sh cJSON
3.7 验证产物
shell
# 检查安装目录
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 校验失败
shell
# 错误提示
ERROR: SHA512SUM mismatch for xxx.tar.gz
# 解决方法
# 1. 确认下载的文件没有损坏(重新下载)
wget -O xxx.tar.gz <source-url>
# 2. 重新生成校验值
sha512sum xxx.tar.gz > SHA512SUM
Q2: configure 找不到依赖库
shell
# 错误提示
# 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 文件
shell
# 错误提示
# 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
shell
# 错误原因
# 通常是链接顺序问题或缺少必要的库
# 解决方法
# 1. 检查 makedepends 或 depends 是否完整
# 2. 在 build() 中手动添加链接库
# 例如添加 -lssl -lcrypto
# 3. 如果是 C++ 库,确认使用了 extern "C" 或 g++ 编译
# 排查命令
grep -A20 "BUILD ERROR" script/mylib-arm64-v8a-lycium_build.log
Q5: 产物架构不对
shell
# 验证产物
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: 多次构建后缓存导致问题
shell
# 现象:修改 HPKBUILD 后重新构建,行为不变
# 解决方法
# 1. 清理构建目录
./build.sh mylib --clean
# 2. 或者手动清理
rm -rf usr/mylib/* output/* script/mylib-*
# 3. 重新构建
./build.sh mylib
Q7: 本机调试时使用 build_local.sh 但编译失败
shell
# 确保 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: 如何定位构建失败的具体行
shell
# 方法 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++ 三方库的适配工作!