当前位置: 首页 > news >正文

避坑指南:鸿蒙 PC 部署 AtomCode Skills 压测工具 wrk

欢迎加入【开源鸿蒙PC社区】,一起共建鸿蒙化C/C++三方库生态。
欢迎在【PC社区】平台贡献你的项目。
仓库: wg/wrk v4.2.0 — HTTP 基准测试工具
适配平台: 鸿蒙PC


资源地址
wrk 官方仓库https://github.com/wg/wrk
LuaJIT 官方仓库https://github.com/LuaJIT/LuaJIT
LuaJIT 适配博文https://blog.csdn.net/u011178696/article/details/161835480
lycium_plusplus 框架https://atomgit.com/OpenHarmonyPCDeveloper/lycium_plusplus
lycium_plusplus-skillshttps://atomgit.com/unisources/lycium_plusplus-skills
wrk 适配后仓库https://atomgit.com/unisources/wrk

目录

  1. 背景与挑战
  2. AtomCode Skills 工作流总览
  3. Step 1:一键生成 HPKBUILD 骨架
  4. Step 2:构建环境检查
  5. Step 3:移植审查与问题发现
  6. Step 4:逐一修复与构建验证
  7. Step 5:最终构建与产物验证
  8. 经验总结与最佳实践

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 压测标准工具之一。

为什么选择 wrk

wrk 是 Linux 生态中最流行的 HTTP 压测工具之一。将其移植到鸿蒙PC的意义:

价值说明
服务端压测在鸿蒙PC上运行的 HTTP 服务可用 wrk 自测性能
网络调试替代 curl 进行更细粒度的 HTTP 测试
Lua 脚本自定义压测场景,无需重新编译
社区生态与 Linux 工具链对齐,降低开发者迁移成本
wrk 的构建技术栈

wrk 的构建系统是自定义 Makefile,它本身不是为交叉编译设计的。其构建流程包含:

  1. 预编译 LuaJIT:通过luajit -b将 Lua 脚本转为 C 字节码(bytecode.c
  2. 编译 C 源码:wrk.c,net.c,ssl.c,script.c
  3. 链接依赖:LuaJIT 运行时 + OpenSSL 加密库 + pthread 线程库

这意味着交叉编译 wrk 需要同时解决LuaJIT 交叉编译OpenSSL 交叉编译两个前置问题。LuaJIT 的交叉编译尤为特殊——它需要一个 HOST 架构的 luajit 二进制来编译 Lua 脚本(Build Tool 问题)。

技术特点
特性说明
编程语言C (C99)
构建系统自定义 Makefile(非 CMake)
核心依赖LuaJIT(脚本支持)+ OpenSSL(HTTPS 支持)
性能单机可生成数百万 QPS
协议HTTP/1.1 + HTTPS
脚本Lua 脚本自定义请求生成逻辑
许可证Apache-2.0

2. AtomCode Skills 工作流总览

本次适配使用了以下 Skills:

Skill作用
/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 tool"

Skill 自动分析 wrk 的构建系统(自定义 Makefile)并生成标准骨架。

3.2 关键修改

与之前适配的 CMake 项目不同,wrk 使用自定义 Makefile,需要手动处理:

  1. buildtools设为make
  2. 声明depends=("LuaJIT" "openssl")
  3. build()中通过环境变量传递WITH_LUAJITWITH_OPENSSL
  4. CFLAGS/LDFLAGS/LIBS中显式指定依赖路径

3.3 HPKBUILD 代码节选

pkgname=wrkpkgver=v4.2.0pkgrel=0pkgdesc="A HTTP benchmarking tool"url="https://github.com/wg/wrk"archs=("arm64-v8a")license=("Apache-2.0")depends=("LuaJIT""openssl")buildtools="make"builddir=wrk-4.2.0

3.4 关键变量说明

变量说明
pkgnamewrk必须与目录名thirdparty/wrk一致
pkgverv4.2.0对应 GitHub Release 标签
archsarm64-v8a仅 64 位 ARM(OpenSSL 依赖限制)
licenseApache-2.0上游许可证
dependsLuaJIT,openssl两个外部依赖,由 lycium 自动先构建
buildtoolsmake非 CMake 项目,需手动管理编译和链接
patchflagtrue启用补丁管理
ccaarch64-linux-ohos-clang直接设置交叉编译器,避免 Makefile 自动检测

3.5 变量分类解读

基本信息
pkgname=wrk# 包名,与目录名一致pkgver=4.2.0# 版本号pkgrel=0# 构建版本号pkgdesc="A HTTP..."# 描述url="..."# 上游仓库archs=("arm64-v8a")# 目标架构license=("Apache-2.0")# 许可证

这些是 lycium 框架的元信息,用于标识包的身份和兼容性。archs仅包含arm64-v8a的原因是 wrk 依赖的 OpenSSL 在 OHOS 上仅测试了 ARM64 架构。

依赖声明
depends=("LuaJIT""openssl")

这是 wrk 适配中最关键的声明之一。depends数组告诉 lycium 构建系统两个信息:

  1. 构建顺序:在构建 wrk 之前,先构建LuaJITopenssl
  2. 依赖注入build_hpk.sh会将这两个包的安装路径注入CMAKE_FIND_ROOT_PATH(仅对 CMake 项目有效)

⚠️注意CMAKE_FIND_ROOT_PATH对 Makefile 项目无效。wrk 使用自定义 Makefile,我们需要在build()函数中手动通过CFLAGS/LDFLAGS/LIBS传递依赖路径。

构建配置
source="https://github.com/wg/wrk/archive/refs/tags/$pkgver.tar.gz"buildtools="make"# 非 CMake,使用 makebuilddir=wrk-4.2.0# tarball 解压后的顶层目录名packagename=$pkgver.tar.gz# 下载的 tarball 文件名patchflag=true# 允许在 prepare() 中打补丁

buildtools="make"与 CMake 项目的buildtools="cmake"有本质区别:

方面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.patchpatchflag=falsecd$OLDPWDfi}

prepare()build()之前执行,用于:

  1. 创建架构特定构建目录($builddir/$ARCH-build
  2. 应用补丁(patchflag确保每轮构建只打一次补丁)

wrk 的prepare()相对简单,因为 wrk 的适配问题主要集中在build()函数中(依赖路径和 Build Tool 架构)。

build() 函数关键行解读

详见 Step 4:build() 函数最终代码。

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(){echo"The 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/linux
SYSROOT 目录/home/ohpkg/linux/native/sysroot
LLVM 工具链 (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/RHEL

5. Step 3:移植审查与问题发现

5.1 使用/porting-reviewerSkill

/porting-reviewer
维度审查结果
🔵 构建系统自定义 Makefile(非 CMake)
🟡 依赖管理需 LuaJIT + OpenSSL,通过depends声明
🟡 Build Tool 问题luajit 二进制需在构建机运行,但交叉编译为 ARM
🟢 许可证Apache-2.0,兼容 OHOS

5.2 关键发现

发现 1:Makefile 变量传递方式不同

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 VAR=val命令行参数与export VAR环境变量的行为不同。在 GNU Make 中:

传递方式可见范围在 Makefile 解析时可用?
make VAR=val顶层 Makefile✅ 可以
export VAR; make所有子进程✅ 可以
make -C subdir VAR=val子 Makefile⚠️ 取决于传递方式

wrk 使用ifneq ($(WITH_LUAJIT),)在最顶层 Makefile 中检查变量,两种方式都有效。但export方式可以确保子 Makefile 也能继承变量(如果 wrk 后续扩展了构建流程)。

修复:在make之前export WITH_LUAJIT

exportWITH_LUAJIT="${luajit_dir}"exportWITH_OPENSSL="${openssl_dir}"
发现 2:CMake 依赖注入不适用于 Makefile

lycium 的build_hpk.sh通过CMAKE_FIND_ROOT_PATH注入依赖路径,但这只对 CMake 项目生效。对于 Makefile 项目,需要在CFLAGS中显式添加:

CFLAGS="-I${luajit_dir}/include/luajit-2.1 -I${openssl_dir}/include"LDFLAGS="-L${luajit_dir}/lib -L${openssl_dir}/lib"LIBS="-lluajit-5.1 -lssl -lcrypto"
发现 3:Build Tool 需要 HOST 版本

wrk 的 Makefile 使用luajit -bwrk.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.c:

mkdir-pobjecho'const char wrk_lua[] = "";'>obj/bytecode.c

6. Step 4:逐一修复与构建验证

6.1 问题修复清单

#问题修复方式
1Makefile 的WITH_LUAJIT变量未生效改为export环境变量
2OpenSSL/LuaJIT 头文件找不到在 CFLAGS 中显式添加-I路径
3luajit ARM64 无法在 x86 主机运行创建 stubobj/bytecode.c
4LuaJIT 库未链接在 LIBS 中添加-lluajit-5.1
5.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 can't run on x86 hostmkdir-pobjecho'const char wrk_lua[] = "";'>obj/bytecode.cmakeCC="${cc}"\AR="llvm-ar"\RANLIB="llvm-ranlib"\CFLAGS="-std=c99 -O2 -D__MUSL__ \ --target=aarch64-linux-ohos \ --sysroot=${OHOS_SDK}/native/sysroot \ -I${luajit_dir}/include/luajit-2.1 \ -I${openssl_dir}/include"\LDFLAGS="--target=aarch64-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>$buildlog2>&1}

关键行说明:

作用为什么需要
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.cscript.h依赖 Lua API
-lssl -lcrypto链接 OpenSSLwrk 的ssl.c依赖 SSL/TLS 功能

6.3 修复流程对比

首次构建

luajit: not found

PATH 添加 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.so

8. 经验总结与最佳实践

8.2 鸿蒙化适配最佳实践

  1. Makefile vs CMake 差异:Makefile 项目不能依赖CMAKE_FIND_ROOT_PATH,需手动在CFLAGS/LDFLAGS/LIBS中配置依赖路径。

  2. Build Tool 架构匹配:交叉编译时,所有在构建机上运行的工具(如代码生成器、脚本编译器)都必须是 HOST 架构版本。交叉编译的 ARM64 二进制无法在 x86_64 构建机上执行。

  3. Makefile 变量传递:Makefile 的ifneq ($(VAR),)在解析时检查变量是否定义。需要export环境变量或在make命令行中传递,二者不可兼用时优先使用export

  4. Stub 策略:当无法编译 HOST 版本的 build tool 时,可以创建 stub 文件满足链接需求。wrk 的obj/bytecode.c为空数组不会影响功能(Lua 脚本会在运行时加载)。

  5. 依赖声明顺序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 # 中文说明文档
http://www.cnnetsun.cn/news/2871910.html

相关文章:

  • Chrome for Testing:Web自动化测试的终极浏览器版本管理解决方案
  • OpenBlock Desktop:5分钟快速上手的硬件图形化编程工具
  • iVCam最全配置指南:旧手机变4K电脑摄像头,OBS直播参数一步到位
  • 12500 黄大年茶思屋榜文“难题揭榜”第125期——媒体技术难题第四期 完整全题梳理
  • 三分钟学会:KMS_VL_ALL_AIO智能激活脚本的完整使用指南
  • 5分钟学会Office界面定制:免费工具打造专属办公功能区
  • e2 Studio 调试与配置避坑指南
  • 智能Agent的规划与推理:从ReAct到Tree-of-Thought的任务分解策略
  • 终极指南:3分钟为macOS微信安装强力防撤回插件
  • SolidWorks_基于草图的实体特征12_轮廓选择法则
  • TikTok防关联浏览器选型测评:分区隔离账号,稳定店铺权重
  • 用AT89C52和Proteus从零搭建一个电子密码锁:手把手教你C语言编程与电路仿真
  • NCMconverter:专业音频格式转换工具,释放加密音乐潜能
  • 如何快速配置黑苹果:OpCore-Simplify完整指南
  • 收藏!小白程序员必看:2026年企业AI应用指南,教你避坑赢市场
  • Vue项目实战:基于TradingView轻量库构建可配置的资金折线图
  • 避坑指南:Three.js加载GLTF人体模型时,菲涅尔着色器与点击事件的那些‘坑’
  • Java毕设选题推荐:基于jspm自行车个性化改装推荐系统【附源码、mysql、文档、调试+代码讲解+全bao等】
  • 别再死记硬背了!用PyTorch手把手教你从Conv到C3模块的代码复用技巧
  • 互联网大厂 Java 求职面试:从 Spring Boot 到微服务的技术深度探讨
  • 图生视频一键成片:潮际好麦让电商商品视频制作效率翻倍
  • Spring AI Alibaba 1.x 系列【75】分布式智能体
  • OmenSuperHub终极指南:免费开源工具释放惠普游戏本隐藏性能
  • Lapce远程开发深度解析:解决SSH连接文件夹无响应的终极方案
  • 3分钟学会本地视频字幕提取:Video-subtitle-extractor完整指南
  • 3步掌握猫抓Cat-Catch:浏览器资源嗅探与下载完整指南
  • Flask全功能后台模板:带登录、图表看板、实时聊天、文件操作和标准API
  • 深度解析PersonaLive:CVPR 2026实时人像动画的终极实战指南
  • OEXN平台:从公开信息出发,归纳合规意识与运营连贯性
  • UIA-v2终极指南:Windows桌面自动化从入门到精通