三方库 Boost.Regex 在 OpenHarmony 的 lycium完整实践
开源鸿蒙社区推出Boost.Regex三方库适配方案,通过lycium框架实现跨平台编译。该方案以Standalone模式独立编译Boost.Regex正则表达式库,不依赖其他Boost模块。通过patch或CMake覆盖方式增加静态库目标和测试用例,生成libboost_regex.a和测试程序boost_regex_test。
欢迎加入 开源鸿蒙跨平台社区,与开发者一起共建鸿蒙三方库的开源生态。
一、背景与目标
Boost.Regex(boostorg/regex)是 Boost 的 C++ 正则表达式库,为标准库 std::regex 的前身,功能更丰富。上游仓库自带 CMakeLists.txt,但仅定义 INTERFACE 目标,不编译 src/posix_api.cpp、src/wide_posix_api.cpp,因此无法直接得到静态库;且默认依赖 Boost 其它模块(config、throw_exception 等)。本适配在 OpenHarmony 三方库共建仓库(tpc_c_cplusplus) 中,使用 lycium 交叉编译框架 将 Boost.Regex 以 Standalone 模式(BOOST_REGEX_STANDALONE,无其它 Boost 依赖)接入:通过 patch 或 CMakeLists.ohos.txt 覆盖 在上游 CMake 中增加静态库目标与 BUILD_TEST,在 prepare() 中生成 boost_regex_test.cpp(覆盖 regex_match、regex_search、regex_replace、捕获组等多条用例),并在设备上通过 HPKCHECK 执行 ./boost_regex_test 完成验证。
目标:
- 在 Mac/Linux 宿主机上交叉编译出适用于 OpenHarmony(armeabi-v7a / arm64-v8a)的 libboost_regex.a 与头文件(
include/boost/); - 使用 Standalone 模式,不依赖 Boost 其它库;
- 编写 正则测试套件(regex_match、regex_search、regex_replace、捕获组等),编出 boost_regex_test,设备上逐条输出 [PASS];
- 设备上执行
./boost_regex_test,输出 “All boost_regex tests passed.” 表示全部通过。
二、环境与框架简介
环境搭建更详细的步骤(SDK 下载、环境变量、依赖工具安装等)可参考:OpenHarmony 交叉编译环境配置。下文仅列出与本文直接相关的要点。
2.1 编译环境搭建
- 宿主机:建议 Mac(Darwin)或 Linux;需安装
cmake、make、wget(或 curl)、patch等。 - OHOS SDK:需包含
native/llvm、native/build-tools/cmake、native/build/cmake/ohos.toolchain.cmake;环境变量指向 SDK 根目录,例如:export OHOS_SDK=/path/to/OpenHarmony/Sdk/20 - lycium:每个三方库由目录下的 HPKBUILD 定义“下载 → 解压 → prepare → 编译 → 安装”;产物落在
lycium/usr/<pkgname>/<ARCH>/;设备侧测试由 HPKCHECK 中的 openharmonycheck() 定义。
2.2 Boost.Regex 上游特点
- 源码:使用 develop 分支,通过
https://codeload.github.com/boostorg/regex/zip/refs/heads/develop下载,解压后目录名为 regex-develop;主要包含 include/boost/(头文件)、src/posix_api.cpp、src/wide_posix_api.cpp(需编成静态库)。 - 构建:上游 CMakeLists.txt 仅
add_library(boost_regex INTERFACE),不编译 .cpp;提供 BOOST_REGEX_STANDALONE 选项,开启后不依赖 Boost 其它库。本适配通过 patch(两处:else 分支内增加静态库目标、文件末尾增加 BUILD_TEST 块)或失败时用 CMakeLists.ohos.txt 覆盖,编出 libboost_regex_sources.a(安装为 libboost_regex.a)与 boost_regex_test。 - API:
boost::regex、boost::regex_match、boost::regex_search、boost::regex_replace、boost::smatch等,头文件#include <boost/regex.hpp>。 - 依赖:Standalone 模式下无第三方依赖;不启用 ICU。
- 测试:上游无现成测试可执行文件;本适配在 prepare() 中通过 heredoc 生成 boost_regex_test.cpp,覆盖 regex_match(含邮箱等)、regex_search(数字、单词)、regex_replace、捕获组等十多条用例。
2.3 HPKBUILD / HPKCHECK 在本库中的角色
- HPKBUILD:定义 pkgname=boost_regex、pkgver=develop、source、builddir=regex-develop、buildtools=cmake;prepare() 中先对解压后的 CMakeLists.txt 做行尾规范化(
sed 's/\r$//'),再尝试打 0001-standalone-build-static-lib.patch,失败则 cp CMakeLists.ohos.txt 覆盖;用 heredoc 生成 boost_regex_test.cpp(多条 regex 用例);build() 中 cmake 传入-DBOOST_REGEX_STANDALONE=ON、-DBUILD_TEST=ON并 make;package() 中拷贝 libboost_regex.a、include/boost、boost_regex_test 到 usr/boost_regex/$ARCH/。 - HPKCHECK:设备上进入
${builddir}/${ARCH}-build,执行./boost_regex_test,将输出写入 logfile,以退出码作为测试结果。
三、接入步骤
3.1 创建三方库目录与文件
在 Workspace/tpc_c_cplusplus/thirdparty/ 下新建目录 boost_regex,并准备:
| 文件 | 作用 |
|---|---|
| HPKBUILD | 包名、版本、源码、prepare(行尾规范化 + patch/覆盖 + 生成测试)/build/package |
| HPKCHECK | 设备上进入构建目录执行 ./boost_regex_test,以退出码为结果 |
| CMakeLists.ohos.txt | patch 失败时的完整 CMake 备用(上游逻辑 + standalone 静态库 + BUILD_TEST) |
| 0001-standalone-build-static-lib.patch | 两处改动:else 分支静态库、末尾 BUILD_TEST(标准 diff -u 格式) |
| README.OpenSource | 开源协议(BSL-1.0)、上游地址、版本(JSON 格式) |
| README_zh.md | 中文说明:简介、产物、编译、测试、API 用法等 |
| .gitignore | 忽略 regex-develop.zip、regex-develop/、.log、.rej 等 |
3.2 boost_regex 的 HPKBUILD 配置要点
| 项 | boost_regex 取值 / 说明 |
|---|---|
| pkgname | boost_regex |
| pkgver | develop |
| source | https://codeload.github.com/boostorg/regex/zip/refs/heads/develop |
| builddir | regex-develop |
| buildtools | cmake |
| archs | armeabi-v7a、arm64-v8a |
| depends | 无 |
- prepare():进入 builddir 后执行
sed 's/\r$//' CMakeLists.txt > CMakeLists.txt.lf && mv CMakeLists.txt.lf CMakeLists.txt统一行尾;再sed 's/\r$//' ... patch \| patch -p1 -N,若 patch 失败则cp CMakeLists.ohos.txt ./CMakeLists.txt。随后用 heredoc 生成 boost_regex_test.cpp,内含 regex_match(1+$、\d+、简单邮箱)、regex_search(数字、\b\w+\b)、regex_replace(\d→X、world→boost)、捕获组 (\d+)-(\w+) 等用例,每条通过 CHECK 宏输出 [PASS]/[FAIL]。最后mkdir -p $ARCH-build。 - build():在 builddir 中执行 cmake
-DOHOS_ARCH=$ARCH -B$ARCH-build -S. -DBOOST_REGEX_STANDALONE=ON -DBUILD_TEST=ON -DBUILD_SHARED_LIBS=OFF,再$MAKE -C $ARCH-build;编译结束后检查$ARCH-build/boost_regex_test是否存在,不存在则报错。 - package():拷贝
$ARCH-build/libboost_regex_sources.a为usr/boost_regex/$ARCH/lib/libboost_regex.a,include/boost到usr/boost_regex/$ARCH/include/,$ARCH-build/boost_regex_test到usr/boost_regex/$ARCH/bin/。
prepare() 核心片段(行尾规范化 + patch 或覆盖 + 生成测试):
prepare() {
_pkgdir="$PWD"
cd $builddir
sed 's/\r$//' CMakeLists.txt > CMakeLists.txt.lf && mv CMakeLists.txt.lf CMakeLists.txt
if ! (sed 's/\r$//' "${_pkgdir}/0001-standalone-build-static-lib.patch" | patch -p1 -N); then
cp "${_pkgdir}/CMakeLists.ohos.txt" ./CMakeLists.txt
fi
cat > boost_regex_test.cpp << 'ENDTEST'
#include <boost/regex.hpp>
// ... CHECK 宏与多条 regex_match / regex_search / regex_replace / 捕获组用例 ...
ENDTEST
mkdir -p $ARCH-build
cd ${OLDPWD}
}
build() 核心片段:
build() {
cd $builddir
PKG_CONFIG_LIBDIR="${pkgconfigpath}" ${OHOS_SDK}/native/build-tools/cmake/bin/cmake "$@" \
-DOHOS_ARCH=$ARCH -B$ARCH-build -S. \
-DBOOST_REGEX_STANDALONE=ON \
-DBUILD_TEST=ON \
-DBUILD_SHARED_LIBS=OFF \
-L > $buildlog 2>&1
$MAKE VERBOSE=1 -C $ARCH-build >> $buildlog 2>&1
if [ ! -f $ARCH-build/boost_regex_test ]; then
echo "ERROR: boost_regex_test not found after make. Check $buildlog"
return 1
fi
cd $OLDPWD
return 0
}
3.3 与上游 CMakeLists 的仅有两处差异
- else() 分支(BOOST_REGEX_STANDALONE):增加 4 行——
add_library(boost_regex_sources STATIC src/posix_api.cpp src/wide_posix_api.cpp)、对 boost_regex_sources 的target_compile_definitions(BOOST_REGEX_STANDALONE)、target_include_directories、target_link_libraries(boost_regex INTERFACE boost_regex_sources)。 - 文件末尾:增加
option(BUILD_TEST ...)与if(BUILD_TEST)块,编出 boost_regex_test 并enable_testing()、add_test(...)。
因此既可维护小 patch(与上游一致时自动打上),又保留 CMakeLists.ohos.txt 作为下载源行尾/空白不一致时的备用。
3.4 HPKCHECK 设备侧测试逻辑
设备上进入 ${builddir}/${ARCH}-build(即 regex-develop/armeabi-v7a-build 或 regex-develop/arm64-v8a-build):
- 若存在 boost_regex_test,则执行
./boost_regex_test,标准输出与错误追加到${logfile},以可执行文件退出码作为测试结果(0 为通过); - 若不存在,则记录 “No boost_regex_test executable, skip test”,返回 1。
四、编译流程与命令
-
进入 lycium 目录:
cd /path/to/tpc_c_cplusplus/lycium -
执行编译(仅编译 boost_regex):
./build.sh boost_regex -
脚本将依次:检查 OHOS_SDK、下载/解压 regex-develop.zip、对每个 ARCH 执行 prepare(行尾规范化 → patch 或覆盖 → 生成 boost_regex_test.cpp)→ cmake → make → package,并写入
lycium/usr/hpk_build.csv。
-
产物位置:
- 静态库与头文件:
lycium/usr/boost_regex/armeabi-v7a/、lycium/usr/boost_regex/arm64-v8a/(lib/libboost_regex.a、include/boost/)。 - 测试可执行文件:
lycium/usr/boost_regex/<ARCH>/bin/boost_regex_test,或构建目录内thirdparty/boost_regex/regex-develop/<ARCH>-build/boost_regex_test。
- 静态库与头文件:
五、设备侧测试
将对应架构的 boost_regex_test(来自 usr/boost_regex/<ARCH>/bin/ 或 regex-develop/<ARCH>-build/)拷贝到设备后执行:
./boost_regex_test
通过时输出示例:
boost_regex tests:
[PASS] regex_match ^[a-z]+$ "hello"
[PASS] regex_match ^[a-z]+$ "Hello" (no match)
[PASS] regex_match ^[a-z]+$ "" (no match)
[PASS] regex_match ^[a-z]+$ "abc"
[PASS] regex_match \d+ "123"
[PASS] regex_match \d+ "12a" (no match)
[PASS] regex_match email "a@b.co"
[PASS] regex_match email "x@y.com"
[PASS] regex_search \d+ in "abc123def"
[PASS] regex_search first \d+ in "foo 42 bar 99"
[PASS] regex_search \b\w+\b "one two three"
[PASS] regex_replace \d -> X "a1b2c3"
[PASS] regex_replace "world" -> "boost"
[PASS] regex_match capture (\d+)-(\w+) "99-hello"
All boost_regex tests passed.
退出码 0 表示全部通过。HPKCHECK 在设备上执行同一命令,结果写入 .../boost_regex_<ARCH>_<SDK_VER>_test.log,便于排查。

六、遇到的问题与解决方案
问题一:HPKBUILD 使用 CRLF 导致 source 报错或 syntax error
现象:执行 ./build.sh boost_regex 时出现 syntax error near unexpected token '{'(prepare() 附近)或 cleanbuild: command not found。
原因:HPKBUILD 使用 Windows 换行符(CRLF),行尾 \r 导致 bash 解析异常,函数未正确定义。
解决:将 HPKBUILD、HPKCHECK 统一为 Unix 换行(LF),例如:
sed 's/\r$//' HPKBUILD > HPKBUILD.tmp && mv HPKBUILD.tmp HPKBUILD
或在仓库内通过 .gitattributes 指定 HPKBUILD text eol=lf、HPKCHECK text eol=lf。
问题二:patch 报 malformed patch 或 2 out of 2 hunks failed
现象:prepare() 中执行 patch 时出现 malformed patch at line 18 或 2 out of 2 hunks failed--saving rejects to CMakeLists.txt.rej。
原因:① 手写 patch 的 hunk 头部(如 section 名、行号)与当前 patch 工具(如 Apple patch)不兼容;② 下载的 zip 中 CMakeLists.txt 与生成 patch 时的上下文不一致(行尾 CRLF、空行差异等)。
解决:① 在 prepare() 中先对 CMakeLists.txt 做行尾规范化:sed 's/\r$//' CMakeLists.txt > CMakeLists.txt.lf && mv CMakeLists.txt.lf CMakeLists.txt,再打 patch,使与 GitHub raw 一致。② 使用 diff -u 生成的标准 patch,避免手写 section 名。③ patch 失败时自动回退:if ! patch ...; then cp CMakeLists.ohos.txt ./CMakeLists.txt; fi,保证构建总能继续;CMakeLists.ohos.txt 保留完整适配内容作备用。
问题三:设备上只看到 “All boost_regex tests passed.” 看不到每条 [PASS]
现象:测试通过但希望看到每条用例的 [PASS] 输出。
原因:初版测试代码仅在全部通过时打印一句总结,未对每条用例单独 cout。
解决:在 boost_regex_test.cpp 中为每条用例增加输出,使用 CHECK 宏在通过时打印 [PASS] 用例描述,失败时打印 [FAIL];最后再打印 “All boost_regex tests passed.” 或 “Some tests failed.”。重新编译并推送新 boost_regex_test 到设备即可看到完整列表。
七、总结
- Boost.Regex 在 OpenHarmony 上的交叉编译依赖 lycium 的 HPKBUILD/HPKCHECK 机制。上游 CMake 仅 INTERFACE 目标、不编 .cpp,本适配通过 patch(两处改动) 或 CMakeLists.ohos.txt 覆盖 在 BOOST_REGEX_STANDALONE=ON 下增加静态库与 BUILD_TEST,在宿主机完成构建,得到 libboost_regex.a、include/boost/ 与 boost_regex_test。
- 测试策略:在 prepare() 中生成 boost_regex_test.cpp,覆盖 regex_match、regex_search、regex_replace、捕获组等多条用例,设备上执行
./boost_regex_test即可逐条看到 [PASS];HPKCHECK 以该可执行文件退出码与 logfile 记录结果。 - 典型问题:HPKBUILD 的 CRLF 需统一为 LF;patch 前先规范化 CMakeLists.txt 行尾,失败则回退到 CMakeLists.ohos.txt;测试输出可增强为逐条 [PASS]/[FAIL] 便于查看。
- 最终产物:lycium/usr/boost_regex/
<ARCH>/ 下的静态库与头文件可供应用集成(链接-lboost_regex,包含<boost/regex.hpp>);boost_regex_test 用于设备端正则功能验证。
若你在使用 lycium 接入带 CMake 但仅 INTERFACE、需额外编出静态库与测试的 C++ 库时,可参考本文的“行尾规范化 + patch + 备用覆盖 + prepare 内生成测试”的方式。更多鸿蒙三方库共建内容,欢迎在 开源鸿蒙跨平台社区 交流。
参考与相关链接
- Boost.Regex 上游:https://github.com/boostorg/regex(BSL-1.0)
- Boost 文档:boost.org/libs/regex
- tpc_c_cplusplus / lycium:OpenHarmony 三方库 C/C++ 共建仓库及交叉编译框架
- 环境搭建:OpenHarmony 交叉编译环境配置
- 开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net/
-
a-z ↩︎
更多推荐



所有评论(0)