避坑指南:鸿蒙 PC 部署 AtomCode Skills 压测工具 wrk
欢迎加入【开源鸿蒙PC社区】一起共建鸿蒙化C/C三方库生态。欢迎在【PC社区】平台贡献你的项目。仓库: wg/wrk v4.2.0 — HTTP 基准测试工具适配平台: 鸿蒙PC资源地址wrk 官方仓库https://github.com/wg/wrkLuaJIT 官方仓库https://github.com/LuaJIT/LuaJITLuaJIT 适配博文https://blog.csdn.net/u011178696/article/details/161835480lycium_plusplus 框架https://atomgit.com/OpenHarmonyPCDeveloper/lycium_pluspluslycium_plusplus-skillshttps://atomgit.com/unisources/lycium_plusplus-skillswrk 适配后仓库https://atomgit.com/unisources/wrk目录背景与挑战AtomCode Skills 工作流总览Step 1一键生成 HPKBUILD 骨架Step 2构建环境检查Step 3移植审查与问题发现Step 4逐一修复与构建验证Step 5最终构建与产物验证经验总结与最佳实践1. 背景与挑战1.1 什么是鸿蒙化适配OpenHarmony开源鸿蒙使用musl libc而非 Linux 常用的glibc并使用自有的OHOS SDK交叉编译工具链。将 Linux/macOS/Windows 生态下的 C/C 三方库移植到 OpenHarmony 平台通常需要编写HPKBUILD构建脚本类 Arch Linux PKGBUILD 风格配置交叉编译工具链arm-linux-ohos-clang等处理 musl libc 与 glibc 的 API 差异解决 Makefile/CMake 构建系统的交叉编译问题验证产物在 OHOS 设备上的正确运行1.2 传统适配流程的痛点环节传统方式痛点HPKBUILD 编写手动对照模板易遗漏变量耗时长依赖分析手动追踪依赖树wrk 依赖 LuaJIT OpenSSL需处理传递依赖交叉编译工具链手动配置 CC/LDFLAGSMakefile 变量传递方式与 CMake 不同Build Tool 处理忽略 host vs target 区分luajit 二进制需在构建机运行但编译为 ARM 架构文档记录最后补写细节易丢失1.3 wrk 项目概况wrk 是一个高性能 HTTP 基准测试工具由 Will Glozer 开发。它能利用多线程和多路复用技术对 HTTP 服务生成大量请求并统计性能指标。wrk 的核心工作机制是通过 LuaJIT 执行用户编写的 Lua 脚本动态生成 HTTP 请求利用 epoll 事件循环管理数千个并发连接结合多线程充分利用 CPU 多核能力。其单机性能可达数百万 QPS是业界广泛使用的 HTTP 压测标准工具之一。为什么选择 wrkwrk 是 Linux 生态中最流行的 HTTP 压测工具之一。将其移植到鸿蒙PC的意义价值说明服务端压测在鸿蒙PC上运行的 HTTP 服务可用 wrk 自测性能网络调试替代 curl 进行更细粒度的 HTTP 测试Lua 脚本自定义压测场景无需重新编译社区生态与 Linux 工具链对齐降低开发者迁移成本wrk 的构建技术栈wrk 的构建系统是自定义 Makefile它本身不是为交叉编译设计的。其构建流程包含预编译 LuaJIT通过luajit -b将 Lua 脚本转为 C 字节码bytecode.c编译 C 源码wrk.c,net.c,ssl.c,script.c等链接依赖LuaJIT 运行时 OpenSSL 加密库 pthread 线程库这意味着交叉编译 wrk 需要同时解决LuaJIT 交叉编译和OpenSSL 交叉编译两个前置问题。LuaJIT 的交叉编译尤为特殊——它需要一个 HOST 架构的 luajit 二进制来编译 Lua 脚本Build Tool 问题。技术特点特性说明编程语言C (C99)构建系统自定义 Makefile非 CMake核心依赖LuaJIT脚本支持 OpenSSLHTTPS 支持性能单机可生成数百万 QPS协议HTTP/1.1 HTTPS脚本Lua 脚本自定义请求生成逻辑许可证Apache-2.02. AtomCode Skills 工作流总览本次适配使用了以下 SkillsSkill作用/new-package生成 HPKBUILD 骨架/build-check验证交叉编译环境/porting-reviewer审查 Makefile 依赖和交叉编译问题/dependency-reviewer检查 LuaJIT/OpenSSL 依赖声明渲染错误:Mermaid 渲染失败: Lexical error on line 2. Unrecognized text. ...R A[/new-package] -- B[HPKBUILD 骨架] ----------------------^3. Step 1一键生成 HPKBUILD 骨架3.1 使用/new-packageSkill一条指令生成 wrk 的 HPKBUILD 骨架/new-package wrk v4.2.0 https://github.com/wg/wrk A HTTP benchmarking toolSkill 自动分析 wrk 的构建系统自定义 Makefile并生成标准骨架。3.2 关键修改与之前适配的 CMake 项目不同wrk 使用自定义 Makefile需要手动处理将buildtools设为make声明depends(LuaJIT openssl)在build()中通过环境变量传递WITH_LUAJIT和WITH_OPENSSL在CFLAGS/LDFLAGS/LIBS中显式指定依赖路径3.3 HPKBUILD 代码节选pkgnamewrkpkgverv4.2.0pkgrel0pkgdescA HTTP benchmarking toolurlhttps://github.com/wg/wrkarchs(arm64-v8a)license(Apache-2.0)depends(LuaJITopenssl)buildtoolsmakebuilddirwrk-4.2.03.4 关键变量说明变量值说明pkgnamewrk必须与目录名thirdparty/wrk一致pkgverv4.2.0对应 GitHub Release 标签archsarm64-v8a仅 64 位 ARMOpenSSL 依赖限制licenseApache-2.0上游许可证dependsLuaJIT,openssl两个外部依赖由 lycium 自动先构建buildtoolsmake非 CMake 项目需手动管理编译和链接patchflagtrue启用补丁管理ccaarch64-linux-ohos-clang直接设置交叉编译器避免 Makefile 自动检测3.5 变量分类解读基本信息pkgnamewrk# 包名与目录名一致pkgver4.2.0# 版本号pkgrel0# 构建版本号pkgdescA HTTP...# 描述url...# 上游仓库archs(arm64-v8a)# 目标架构license(Apache-2.0)# 许可证这些是 lycium 框架的元信息用于标识包的身份和兼容性。archs仅包含arm64-v8a的原因是 wrk 依赖的 OpenSSL 在 OHOS 上仅测试了 ARM64 架构。依赖声明depends(LuaJITopenssl)这是 wrk 适配中最关键的声明之一。depends数组告诉 lycium 构建系统两个信息构建顺序在构建 wrk 之前先构建LuaJIT和openssl依赖注入build_hpk.sh会将这两个包的安装路径注入CMAKE_FIND_ROOT_PATH仅对 CMake 项目有效⚠️注意CMAKE_FIND_ROOT_PATH对 Makefile 项目无效。wrk 使用自定义 Makefile我们需要在build()函数中手动通过CFLAGS/LDFLAGS/LIBS传递依赖路径。构建配置sourcehttps://github.com/wg/wrk/archive/refs/tags/$pkgver.tar.gzbuildtoolsmake# 非 CMake使用 makebuilddirwrk-4.2.0# tarball 解压后的顶层目录名packagename$pkgver.tar.gz# 下载的 tarball 文件名patchflagtrue# 允许在 prepare() 中打补丁buildtoolsmake与 CMake 项目的buildtoolscmake有本质区别方面CMake 项目Makefile 项目工具链注入CMAKE_TOOLCHAIN_FILE自动设置需手动设置CC/AR/RANLIB依赖注入CMAKE_FIND_ROOT_PATH自动生效需手动设置CFLAGS/LDFLAGS并行编译$MAKE(make -jN)同$MAKE安装make install需手动cp二进制工具链变量cc${OHOS_SDK}/native/llvm/bin/aarch64-linux-ohos-clang与其他 CMake 项目不同这里直接在 HPKBUILD 顶层设置了cc。这是因为 wrk 的 Makefile 使用CC变量而交叉编译时必须指定为 OHOS 的 clang。prepare() 函数prepare(){mkdir-p$builddir/$ARCH-buildif$patchflag;thencd$builddir# patch -p1 ../xxx.patchpatchflagfalsecd$OLDPWDfi}prepare()在build()之前执行用于创建架构特定构建目录$builddir/$ARCH-build应用补丁patchflag确保每轮构建只打一次补丁wrk 的prepare()相对简单因为 wrk 的适配问题主要集中在build()函数中依赖路径和 Build Tool 架构。build() 函数关键行解读详见 Step 4build() 函数最终代码。package() 函数package(){cd$builddirlocaldest$LYCIUM_ROOT/usr/$pkgname/$ARCHmkdir-p$dest/bincp-fwrk$dest/bin/}wrk 的 Makefile没有install目标因此package()需要手动将编译好的二进制复制到安装目录。这与 CMake 项目的make install自动安装有本质区别。check() 与 cleanbuild()check(){echoThe test must be run on an OpenHarmony device!}cleanbuild(){rm-rf${PWD}/$builddir}check()用于在设备上运行测试。由于 wrk 是 HTTP 压测工具需要在 OHOS 设备上实际运行才能验证。cleanbuild()清理构建产物。4. Step 2构建环境检查4.1 使用/build-checkSkill在首次构建前运行环境检查/build-check检查项结果OHOS_SDK环境变量✅/home/ohpkg/linuxSYSROOT 目录✅/home/ohpkg/linux/native/sysrootLLVM 工具链 (3 架构)✅ aarch64 / arm / x86_64 clang 均存在构建依赖 (16 个工具)✅ gcc, cmake, make, git, curl 等全齐/usr输出目录✅ 存在4.2 自动化诊断当工具缺失时Skill 自动给出安装命令⚠️ 缺少必要工具cmake 请安装sudo apt install cmake # Debian/Ubuntu sudo yum install cmake # Fedora/RHEL5. Step 3移植审查与问题发现5.1 使用/porting-reviewerSkill/porting-reviewer维度审查结果 构建系统自定义 Makefile非 CMake 依赖管理需 LuaJIT OpenSSL通过depends声明 Build Tool 问题luajit 二进制需在构建机运行但交叉编译为 ARM 许可证Apache-2.0兼容 OHOS5.2 关键发现发现 1Makefile 变量传递方式不同wrk 使用自定义 Makefile通过ifneq ($(WITH_LUAJIT),)判断依赖是否可用。与 CMake 的find_package不同Makefile 变量必须在环境中导出才能在解析时可见# wrk 的 Makefile在解析时检查变量 ifneq ($(WITH_LUAJIT),) CFLAGS -I$(WITH_LUAJIT)/include LDFLAGS -L$(WITH_LUAJIT)/lib else DEPS $(ODIR)/lib/libluajit-5.1.a # 构建 vendored 版本 endif这里有一个细微但关键的区别make VARval命令行参数与export VAR环境变量的行为不同。在 GNU Make 中传递方式可见范围在 Makefile 解析时可用make VARval顶层 Makefile✅ 可以export VAR; make所有子进程✅ 可以make -C subdir VARval子 Makefile⚠️ 取决于传递方式wrk 使用ifneq ($(WITH_LUAJIT),)在最顶层 Makefile 中检查变量两种方式都有效。但export方式可以确保子 Makefile 也能继承变量如果 wrk 后续扩展了构建流程。修复在make之前export WITH_LUAJITexportWITH_LUAJIT${luajit_dir}exportWITH_OPENSSL${openssl_dir}发现 2CMake 依赖注入不适用于 Makefilelycium 的build_hpk.sh通过CMAKE_FIND_ROOT_PATH注入依赖路径但这只对 CMake 项目生效。对于 Makefile 项目需要在CFLAGS中显式添加CFLAGS-I${luajit_dir}/include/luajit-2.1 -I${openssl_dir}/includeLDFLAGS-L${luajit_dir}/lib -L${openssl_dir}/libLIBS-lluajit-5.1 -lssl -lcrypto发现 3Build Tool 需要 HOST 版本wrk 的 Makefile 使用luajit -b将wrk.lua编译为obj/bytecode.c预编译字节码。但是交叉编译的 ARM64 luajit不能在 x86_64 构建机上运行导致Exec format error。方案说明可行性构建 HOST 版 luajit在构建机上编译 x86_64 版 luajit可行但复杂使用 stub bytecode.c创建空wrk_lua[]数组✅ 最简单使用系统 luajit安装 host 版 luajit 包需 root 权限修复创建 stub bytecode.cmkdir-pobjechoconst char wrk_lua[] ;obj/bytecode.c6. Step 4逐一修复与构建验证6.1 问题修复清单#问题修复方式1Makefile 的WITH_LUAJIT变量未生效改为export环境变量2OpenSSL/LuaJIT 头文件找不到在 CFLAGS 中显式添加-I路径3luajit ARM64 无法在 x86 主机运行创建 stubobj/bytecode.c4LuaJIT 库未链接在 LIBS 中添加-lluajit-5.15.a文件链接顺序问题主库在前、依赖库在后、系统库最后6.2 build() 函数最终代码最终的build()函数需要同时处理 4 个关键问题工具链配置、依赖路径注入、Build Tool 架构、链接顺序。build(){cd$builddirlocalluajit_dir$LYCIUM_ROOT/usr/LuaJIT/$ARCHlocalopenssl_dir$LYCIUM_ROOT/usr/openssl/$ARCHexportWITH_LUAJIT${luajit_dir}exportWITH_OPENSSL${openssl_dir}# Stub bytecode — ARM luajit cant run on x86 hostmkdir-pobjechoconst char wrk_lua[] ;obj/bytecode.cmakeCC${cc}\ARllvm-ar\RANLIBllvm-ranlib\CFLAGS-stdc99 -O2 -D__MUSL__ \ --targetaarch64-linux-ohos \ --sysroot${OHOS_SDK}/native/sysroot \ -I${luajit_dir}/include/luajit-2.1 \ -I${openssl_dir}/include\LDFLAGS--targetaarch64-linux-ohos \ --sysroot${OHOS_SDK}/native/sysroot \ -L${luajit_dir}/lib -L${openssl_dir}/lib\LIBS-lm -lssl -lcrypto -lluajit-5.1 -lpthread -ldl\VER$pkgver-j8$buildlog21}关键行说明行作用为什么需要export WITH_LUAJIT传递 LuaJIT 路径给 MakefileMakefile 的ifneq检查需要echo ... obj/bytecode.c创建空字节码避免 HOST 架构 luajit 不可用导致的构建中断-I${luajit_dir}/include/luajit-2.1LuaJIT 头文件路径LuaJIT 头文件在include/luajit-2.1/子目录-lluajit-5.1链接 LuaJIT 运行时wrk 的script.c和script.h依赖 Lua API-lssl -lcrypto链接 OpenSSLwrk 的ssl.c依赖 SSL/TLS 功能6.3 修复流程对比首次构建luajit: not foundPATH 添加 luajit 路径openssl/lua 头文件找不到CFLAGS 添加 -I 路径luajit: Exec format error创建 stub bytecode.c构建成功 ✅7. Step 5最终构建与产物验证7.1 构建通过./build.sh wrk实际输出Compileing OpenHarmony arm64-v8a wrk 4.2.0 libs... The test must be run on an OpenHarmony device! Build wrk 4.2.0 end! ALL JOBS DONE!!!7.2 产物清单lycium/usr/wrk/ └── arm64-v8a/ └── bin/ └── wrk # HTTP 压测二进制7.3 正确性验证# 验证二进制为 ARM64 ELFfilelycium/usr/wrk/arm64-v8a/bin/wrk# 输出: ELF 64-bit LSB executable, ARM aarch64# 验证链接的库ldd lycium/usr/wrk/arm64-v8a/bin/wrk# libluajit-5.1.so, libssl.so, libcrypto.so8. 经验总结与最佳实践8.2 鸿蒙化适配最佳实践Makefile vs CMake 差异Makefile 项目不能依赖CMAKE_FIND_ROOT_PATH需手动在CFLAGS/LDFLAGS/LIBS中配置依赖路径。Build Tool 架构匹配交叉编译时所有在构建机上运行的工具如代码生成器、脚本编译器都必须是 HOST 架构版本。交叉编译的 ARM64 二进制无法在 x86_64 构建机上执行。Makefile 变量传递Makefile 的ifneq ($(VAR),)在解析时检查变量是否定义。需要export环境变量或在make命令行中传递二者不可兼用时优先使用export。Stub 策略当无法编译 HOST 版本的 build tool 时可以创建 stub 文件满足链接需求。wrk 的obj/bytecode.c为空数组不会影响功能Lua 脚本会在运行时加载。依赖声明顺序depends中的库按顺序构建。LuaJIT 和 OpenSSL 均需在 wrk 之前完成lycium 的 round 机制会优先处理依赖。8.4 总结wrk 的鸿蒙PC适配是Makefile 项目的代表案例——它展示了与 CMake 项目完全不同的适配模式手动管理 CFLAGS/LDFLAGS、处理 Build Tool 架构不匹配、使用export传递 Makefile 变量。从 spdlog (CMake, L1) → zlib (Makefile, L2) → wrk (Makefile Build Tool, L3)覆盖了从简单到复杂的不同构建系统。每篇教程沉淀的知识都写回了 Skills 集合使下一次适配更高效。AtomCode 不是替开发者做适配而是让开发者每次只解决新问题不再重复踩坑。附录A. 最终文件结构thirdparty/wrk/ ├── HPKBUILD # 构建脚本83 行 ├── SHA512SUM # 源码校验和 ├── OAT.xml # 许可证合规配置 ├── README.OpenSource # 开源声明 └── README_zh.md # 中文说明文档