欢迎加入 开源鸿蒙跨平台开发者社区,与大家一起共建鸿蒙化 C/C++ 三方库生态。
导读 :本文说明如何在 lycium++ 中完成 thirdparty/nanomsg/ 交叉编译,得到 lycium/output/<ARCH>/ 下 libnanomsg.so 与 HNP/tar。
一、背景与本文目标
| 项 | 说明 |
|---|---|
| 应用场景 | 在鸿蒙应用或原生服务中使用 可扩展消息协议(req/rep、pub/sub、pipeline 等)做进程间或网络通信。 |
| 读者将学会 | 用 cmake "$@" 正确注入工具链;-DNN_*=OFF 收敛交叉构建。 |
| 非本文范围 | 上游协议栈深度定制。 |
二、环境与约束
| 项目 | 说明 |
|---|---|
| 环境配置参考 | 仓库内 lycium/doc/ohos_use_sdk/OHOS_SDK-Usage.md、lycium/README.md;社区可参考 《在 Ubuntu 中搭建鸿蒙 PC 三方库交叉编译构建开发环境》 |
| OHOS SDK 版本 / API Level | 以本地已安装 SDK 为准(示例:6.0 Release,Clang 15.x);需 export OHOS_SDK=<SDK 根目录> |
| lycium++(本仓库)地址 | https://gitcode.com/OpenHarmonyPCDeveloper/lycium_plusplus.git(或实际 fork / 分支) |
| 目标库上游源码地址 | nanomsg/nanomsg,标签 1.2.2 |
| 本仓库适配目录 | thirdparty/nanomsg/ |
| 适配目标平台 | 鸿蒙 PC |
三、目标库说明与移植路径总览
3.1 目标库说明
- 概述 :nanomsg 是实现多种 可扩展消息协议 (req/rep、pub/sub、survey、pipeline、bus 等)的 C 库 ,支持 TCP、IPC、WebSocket 等传输。许可证为 MIT (见上游
COPYING)。 - 本仓库版本 :
pkgver=1.2.2,解压顶层目录nanomsg-1.2.2。 - 依赖关系 :
- 系统/其它 HPK 依赖 :无,
depends=()。 - 宿主构建工具 :无额外
makedepends;CMake 由 OHOS SDK 提供;pthread 由工具链与find_package(Threads)解决。
- 系统/其它 HPK 依赖 :无,
- 构建系统判断 :CMake 。根目录
CMakeLists.txt中project(nanomsg C),并提供NN_TESTS/NN_TOOLS/NN_ENABLE_DOC等选项。
上游工程入口(节选,说明交叉编译时通过 -D 关闭测试与工具):
cmake
cmake_minimum_required (VERSION 2.8.12...3.5)
project (nanomsg C)
option (NN_TESTS "Build and run nanomsg tests" ON)
option (NN_TOOLS "Build nanomsg tools" ON)
# ...
add_subdirectory (src)
3.2 移植路径总览
| 阶段 | 内容 |
|---|---|
| 1 | 创建 thirdparty/nanomsg/ |
| 2 | HPKBUILD(含 archive()),无 patch |
| 3 | HPKCHECK |
| 4 | hnp.json |
| 5 | README_zh.md、README.OpenSource、docs/hap_integrate.md |
| 6 | cd lycium && ./build.sh nanomsg 直至通过 |
四、详细适配过程
以下与仓库 thirdparty/nanomsg/HPKBUILD 保持一致(若你本地有微调,以仓库为准)。
4.1 分析与选型
| 项 | 结论 |
|---|---|
| 编译方式 | CMake (buildtools=cmake) |
| 是否需 patch | 否 ;通过 CMake -DNN_*=OFF 收敛功能 |
downloadpackage / autounpack |
均为 true ;source 使用 codeload URL,与 github.com/.../archive/... 内容等价,部分网络更稳定 |
4.2 HPKBUILD 元数据与下载字段
bash
pkgname=nanomsg
pkgver=1.2.2
pkgrel=0
pkgdesc="High-performance scalability protocols C library (nanomsg)"
url="https://github.com/nanomsg/nanomsg"
archs=("armeabi-v7a" "arm64-v8a" "x86_64")
license=("MIT")
depends=()
makedepends=()
# 与 GitHub archive 等价,部分网络环境下 codeload 更稳定
source="https://codeload.github.com/nanomsg/nanomsg/tar.gz/refs/tags/${pkgver}"
builddir=nanomsg-${pkgver}
packagename=nanomsg-${pkgver}.tar.gz
downloadpackage=true
autounpack=true
buildtools=cmake
source ./envset.sh
4.3 prepare / build / package(核心逻辑)
prepare:每架构一份源码树,避免多架构构建互相污染。
bash
prepare() {
cp -rf "${builddir}" "${builddir}-${ARCH}-build"
}
build :必须 使用 cmake "$@" ,由 lycium/script/build_hpk.sh 注入工具链、安装前缀、-DOHOS_ARCH 等;禁止 再写 -DCMAKE_TOOLCHAIN_FILE="${OHOS_CMAKE_TOOLCHAIN_FILE}"**(该变量本身已是带 -D 的完整参数,重复嵌套会报错)。
关闭测试、文档、工具及 getaddrinfo_a,减小体积并降低 musl 下对 libanl 的依赖风险。
bash
build() {
cd "${builddir}-${ARCH}-build" || return 1
if [ "$ARCH" = "armeabi-v7a" ]; then
setarm32ENV
elif [ "$ARCH" = "arm64-v8a" ]; then
setarm64ENV
elif [ "$ARCH" = "x86_64" ]; then
setx86_64ENV
fi
PKG_CONFIG_LIBDIR="${pkgconfigpath}" \
cmake "$@" \
-B build \
-S . \
-DCMAKE_SYSTEM_NAME=Linux \
-DNN_TESTS=OFF \
-DNN_ENABLE_DOC=OFF \
-DNN_TOOLS=OFF \
-DNN_ENABLE_GETADDRINFO_A=OFF \
>> "${buildlog}" 2>&1 || return 1
${MAKE} -C build >> "${buildlog}" 2>&1
ret=$?
cd "${OLDPWD}" || return 1
return $ret
}
package:
bash
package() {
${MAKE} -C "${builddir}-${ARCH}-build/build" install >> "${buildlog}" 2>&1
}
check() (占位,真机测试在 HPKCHECK 扩展):
bash
check() {
echo "The test must be on an OpenHarmony device!"
}
cleanbuild / recoverpkgbuildenv:
bash
cleanbuild() {
rm -rf "${PWD:?}/${builddir}" \
"${PWD}/${builddir}-armeabi-v7a-build" \
"${PWD}/${builddir}-arm64-v8a-build" \
"${PWD}/${builddir}-x86_64-build"
}
recoverpkgbuildenv() {
if [ "$ARCH" = "armeabi-v7a" ]; then
unsetarm32ENV
elif [ "$ARCH" = "arm64-v8a" ]; then
unsetarm64ENV
elif [ "$ARCH" = "x86_64" ]; then
unsetx86_64ENV
fi
}
4.4 补丁
本适配无需 patch。
4.5 hnp.json 与 archive()
hnp.json 全文 (name / version 与 HPKBUILD 一致):
json
{
"type": "hnp-config",
"name": "nanomsg",
"version": "1.2.2",
"install": {}
}
archive():
bash
archive() {
export HNP_TOOL="${HNP_TOOL:-${OHOS_SDK}/toolchains/hnpcli}"
mkdir -p "${LYCIUM_ROOT}/output/${ARCH}"
pushd "${LYCIUM_ROOT}/usr/${pkgname}/${ARCH}" > /dev/null
tar -zvcf "${LYCIUM_ROOT}/output/${ARCH}/${pkgname}_${pkgver}.tar.gz" .
popd > /dev/null
cp "${PWD}/hnp.json" "${LYCIUM_ROOT}/usr/${pkgname}/${ARCH}/"
${HNP_TOOL} pack -i "${LYCIUM_ROOT}/usr/${pkgname}/${ARCH}" -o "${LYCIUM_ROOT}/output/${ARCH}/"
}
4.6 构建命令与日志
bash
export OHOS_SDK=/path/to/your/ohsdk/linux
cd lycium
./build.sh nanomsg
- 成功标志 :出现
Build nanomsg 1.2.2 end!、ALL JOBS DONE!!!;各架构lycium/usr/nanomsg/<ARCH>/含lib/libnanomsg.so与lycium/output/<ARCH>/nanomsg.hnp(及nanomsg_1.2.2.tar.gz)。 - 失败时 :查看包目录或
lycium/script下nanomsg-1.2.2-<ARCH>-lycium_build.log(文件名以pkgname-pkgver-$ARCH为准)。示例(节选,仅作格式说明):
text
-- The C compiler identification is Clang 15.0.4
-- Detected nanomsg ABI v...
...
[100%] Built target nanomsg
若配置失败,常见为未传 "$@" 或 toolchain 双重嵌套,日志中会出现:
text
CMake Error ... Could not find toolchain file:
-DCMAKE_TOOLCHAIN_FILE=/...
4.7 最终产物与目录树
安装前缀:$LYCIUM_ROOT/usr/nanomsg/$ARCH/ (本仓库中 LYCIUM_ROOT 即 lycium/)。
验证示例 (arm64-v8a):
bash
find lycium/usr/nanomsg/arm64-v8a -type f | head -20
典型输出结构(与本地构建一致):
text
lycium/usr/nanomsg/arm64-v8a/include/nanomsg/nn.h
lycium/usr/nanomsg/arm64-v8a/include/nanomsg/tcp.h
lycium/usr/nanomsg/arm64-v8a/lib/libnanomsg.so
lycium/usr/nanomsg/arm64-v8a/lib/pkgconfig/nanomsg.pc
lycium/usr/nanomsg/arm64-v8a/lib/cmake/nanomsg-1.2.1/nanomsg-config.cmake
# ... 其余协议头文件、CMake 包文件等
说明:
lib/cmake/下目录名可能出现nanomsg-1.2.1,来自上游.version与包版本检测 ,与 tag 1.2.2 不完全一致,一般不影响链接libnanomsg.so。
file 检查交叉架构:
bash
file lycium/usr/nanomsg/arm64-v8a/lib/libnanomsg.so
... ELF 64-bit LSB shared object, ARM aarch64 ...
- 主要库文件 :
lib/libnanomsg.so lycium/output/<ARCH>/:nanomsg_1.2.2.tar.gz、nanomsg.hnp
五、鸿蒙 PC / 设备上的运行与验证
5.1 命令行工具类(静态/动态可执行文件)
不适用(默认配置) :HPKBUILD 中 -DNN_TOOLS=OFF ,交叉产物不包含 nanocat 等 CLI。若需工具,见 §七 FAQ。
5.2 应用工程集成(库 / 非独立 CLI)
应用 CMakeLists.txt 片段 (将预编译目录拷贝到工程 thirdparty/prebuilt/nanomsg/${OHOS_ARCH} 后):
cmake
set(NANOMSG_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/prebuilt/nanomsg/${OHOS_ARCH}")
target_include_directories(entry PRIVATE "${NANOMSG_ROOT}/include")
target_link_libraries(entry PRIVATE "${NANOMSG_ROOT}/lib/libnanomsg.so")
动态库部署到 HAP 时,请按 lycium/doc/app_calls_third_lib.md 将 soname 对应 的 .so 放入 entry/libs/${OHOS_ARCH}/。
最小 C 冒烟示例 (创建 socket 后关闭;在设备或交叉环境编译时指定 -I.../include、-L.../lib -lnanomsg):
c
#include <stdio.h>
#include <nanomsg/nn.h>
int main(void)
{
int s = nn_socket(AF_SP, NN_PAIR);
if (s < 0) {
fprintf(stderr, "nn_socket: %s\n", nn_strerror(nn_errno()));
return 1;
}
nn_close(s);
return 0;
}
5.3 交叉编译阶段测试(构建树 / 宿主)
| 项 | 说明 |
|---|---|
| 上游单测 | HPKBUILD 中 -DNN_TESTS=OFF ,交叉构建不编译、不运行 nanomsg 自带测试二进制。 |
| 本地可选 | 若仅在宿主编原生 nanomsg,可 cmake -DNN_TESTS=ON 后 ctest(与 HPK 流程无关)。 |
bash
# 交叉 HPK 下通常不执行
# ctest --output-on-failure --test-dir build
(以 ALL JOBS DONE 与 libnanomsg.so 为准。)
5.4 仓库 HPKCHECK(openharmonycheck)
bash
source HPKBUILD > /dev/null 2>&1
openharmonycheck() {
echo "The test must be on an OpenHarmony device!"
# 设备上可链接 libnanomsg 编写 req/rep 等冒烟用例
return 0
}
5.5 设备 / 模拟器冒烟(推荐至少一条)
在应用或独立可执行文件中:
nn_socket(AF_SP, NN_PAIR)(或 req/rep)创建 socket;nn_close(s)释放;- 期望 返回码非负 / 无崩溃。
部署 libnanomsg.so 时遵守 lycium/doc/app_calls_third_lib.md。
5.6 应用内自动化(可选)
模块测试中对 pub/sub 或 ipc 做一轮 send/recv 闭环,日志含 成功 关键字即可。
5.7 无测试时的写法(边界说明)
交叉阶段以 §4.7 file libnanomsg.so 与 三架构安装树完整为主;协议一致性依赖上游测试集与真机网络/IPC 环境。
六、总结与后续工作
- 小结 :
cmake "$@"+ 关闭 NN_TESTS/TOOLS ;产物以libnanomsg.so与 HAP 集成 为主。 - 后续 :可按需在交叉构建中开启 TOOLS 并补充 §5.1 命令行验证。
七、FAQ
Could not find toolchain file: -DCMAKE_TOOLCHAIN_FILE=...- 现象:
text
CMake Error ... Could not find toolchain file:
-DCMAKE_TOOLCHAIN_FILE=/home/.../ohos.toolchain.cmake
- 原因 :把环境变量
OHOS_CMAKE_TOOLCHAIN_FILE(已是-DCMAKE_TOOLCHAIN_FILE=路径整段 )再次传给-DCMAKE_TOOLCHAIN_FILE=。 - 解决 :
build()中只保留cmake "$@",勿手写重复 toolchain 行(与thirdparty/libini技能说明一致)。
-
源码包
wget超时或 GitHub archive 失败- 现象 :
download.log中长时间Connecting to github.com ... timed out。 - 解决 :使用
HPKBUILD中已配置的 codeload URL ,或将浏览器下载的nanomsg-1.2.2.tar.gz放到thirdparty/nanomsg/(与packagename同名),build_hpk会跳过下载。
- 现象 :
-
需要
nanocat或单元测试- 解决 :在
cmake行去掉-DNN_TOOLS=OFF或-DNN_TESTS=OFF,并评估构建时间与设备上跑测试的可行性。
- 解决 :在
-
lib/cmake/nanomsg-1.2.1与版本 1.2.2 不一致- 原因 :上游
NN_PACKAGE_VERSION从.version等读取,与 git tag 可能不同。 - 解决 :以
libnanomsg.so与nn.h为准继续集成;若强依赖 CMake config 路径,可在文档中写明实际目录名。
- 原因 :上游
八、附录与参考
- 上游:https://github.com/nanomsg/nanomsg
- 同包短说明:README_zh.md
- 开源清单:README.OpenSource
- HAP 集成:docs/hap_integrate.md