libnghttp2 是一个用 C 语言编写的高性能 HTTP/2 协议库。它实现了 HTTP/2 的核心功能包括二进制分帧层、多路复用、头部压缩HPACK以及服务器推送等特性。该库不仅支持 HTTP/2 客户端和服务器的实现还提供了用于负载测试和基准评测的工具。文章目录二、libnghttp2 的主要功能和用途三、如何在鸿蒙PC命令行工具中移植libnghttp23.1 编译环境准备3.2 下载并配置ohos-sdk版本OpenHarmony_6.1.0.283.3 配置环境变量3.4 编译libnghttp2命令集3.5 确认编译产物3.6 鸿蒙PC端验证四、错误处理4.1 错误1Relocations in generic ELF (EM:183) error adding symbols:file in wrong format4.2 错误2checking host system type... Invalid configuration aarch64-linux-ohos: OS ohos not recognized五、总结欢迎加入开源鸿蒙PC社区https://harmonypc.csdn.net/## 一、什么是libnghttp2libnghttp2是nghttp2项目的核心组件是一个用C语言编写的高性能、可重用的HTTP/2协议库。它主要实现了HTTP/2协议的帧层framing layer为构建支持HTTP/2的客户端和服务器应用程序提供了基础功能。核心功能libnghttp2库提供了HTTP/2协议的完整实现包括连接管理、流控制、帧的编码与解码等核心机制并支持HPACK头部压缩算法。主要用途该库本身不直接提供命令行工具而是作为开发库供其他软件集成用于在应用程序中添加HTTP/2支持。相关工具nghttp2项目还包含基于libnghttp2构建的实用工具例如nghttpHTTP/2客户端和nghttpxHTTP/2代理但这些是独立于libnghttp2的可执行程序。依赖与集成许多网络工具和服务器软件如curl、Apache、Node.js、Wireshark等都依赖于libnghttp2库来实现HTTP/2功能。开发版本在Linux系统中libnghttp2-dev软件包提供了编译基于libnghttp2的应用程序所需的头文件和开发资源。二、libnghttp2 的主要功能和用途libnghttp2 的设计注重灵活性不直接处理 I/O 操作允许开发者将其轻松集成到现有的事件循环系统中。它被广泛应用于需要高效处理 HTTP/2 请求与响应的场景例如 Web 服务器、代理和客户端工具。此外libnghttp2 还提供了对 HTTP/2 协议栈的完整支持包括对 RFC 7540、RFC 7541 和最新的 RFC 9113 的实现。其源码结构清晰主要包含 src/、lib/ 和 tests/ 等目录其中 lib/nghttp2 目录下是核心协议实现。除了作为底层库使用外libnghttp2 还支持多种高级功能如命令行客户端工具 nghttp、高性能代理 nghttpx 以及负载测试工具 h2load 等。这些工具使得开发者可以方便地测试和调试 HTTP/2 服务。在实际部署中libnghttp2 也常用于嵌入式平台或物联网设备上例如 ESP32 系列 SOC 平台。它支持多种操作系统和编译环境并且提供了详细的开发文档和示例。三、如何在鸿蒙PC命令行工具中移植libnghttp23.1 编译环境准备在鸿蒙PC命令行工具中移植使用的是交叉编译的方式交叉编译是指在A架构如x86_64 Linux编译出能在B架构如鸿蒙PC运行的程序这样可以达到命令跨平台运行的目的。本人使用的是vagrant ubuntu 22.04的镜像包进行的测试,在x86_64的Linux主机Ubuntu 24.04上编译出能在aarch64架构HarmonyOS系统的鸿蒙PC上运行的程序。学习教程可以看看Ubuntu如何搭建OpenHarmony_6.1.0.28的lycium_plusplus及鸿蒙 PC 环境设计的 C/C 编译框架 这个文章讲的还是比较详细的。3.2 下载并配置ohos-sdk版本OpenHarmony_6.1.0.28直接使用wget将这个包下载下来我们可以看到这个包的大小有2.33Gwget https://cidownload.openharmony.cn/version/Daily_Version/OpenHarmony_6.1.0.28/20260120_120146/version-Daily_Version-OpenHarmony_6.1.0.28-20260120_120146-ohos-sdk-full.tar.gz使用tar来解压这个gz压缩包tar xf version-Daily_Version-OpenHarmony_6.1.0.28-20260120_120146-ohos-sdk-full.tar.gz接下来我们进入linux目录中我们解压native模块unzip-q native-linux-x64-6.1.0.28-Beta1.zip同时再次解压toolchains模块unzip-q toolchains-linux-x64-6.0.0.46-Beta1.zip3.3 配置环境变量SDK解压完成之后这里我们设置一下全局的环境变量配置交叉编译必备的环境变量可以根据自己的exportOHOS_SDK~/harmonypc/linux echo $OHOS_SDK# 下面的都是根据上面的环境变量来动态配置的不需要改动exportPATH${OHOS_SDK}/native/llvm/bin:${OHOS_SDK}/native/build-tools/cmake/bin:$PATHexportAS${OHOS_SDK}/native/llvm/bin/llvm-asexportCC${OHOS_SDK}/native/llvm/bin/clang --targetaarch64-linux-ohosexportCXX${OHOS_SDK}/native/llvm/bin/clang --targetaarch64-linux-ohosexportLD${OHOS_SDK}/native/llvm/bin/ld.lldexportSTRIP${OHOS_SDK}/native/llvm/bin/llvm-stripexportRANLIB${OHOS_SDK}/native/llvm/bin/llvm-ranlibexportOBJDUMP${OHOS_SDK}/native/llvm/bin/llvm-objdumpexportOBJCOPY${OHOS_SDK}/native/llvm/bin/llvm-objcopyexportNM${OHOS_SDK}/native/llvm/bin/llvm-nmexportAR${OHOS_SDK}/native/llvm/bin/llvm-arexportCFLAGS-fPIC -D__MUSL__1exportCXXFLAGS-fPIC -D__MUSL__1上面在设置完全局环境变量后我们再执行$CC -v命令可以查询到clang的版本号就说明设置成功了,到此为止编译环境就全部准备就绪接下来就可以进行编译移植了。3.4 编译libnghttp2命令集源码的原始仓库维护在github上我们直接使用wget下载下来wget https://github.com/nghttp2/nghttp2/releases/download/v1.68.0/nghttp2-1.68.0.tar.gz tar xf nghttp2-1.68.0.tar.gz配置编译规则通过configure脚本指定目标架构、安装路径、依赖等核心参数说明完整配置命令CC$CC $CFLAGS./configure--hostaarch64-unknown-linux-musl--prefixpwd/nghttp2_targetaarch64-unknown-linux-musl目标架构对应鸿蒙PC的aarch64-linux-ohos–prefix指定安装路径建议设为源码目录下的target方便后续引用使用make命令进行编译(多线程编译可根据CPU核心数调整-j后的数字加快编译速度)make使用make install命令安装到指定路径–prefix指定的target目录这里是当前源码目录下的nghttp2_target目录make install1.configure是GNU Autotools生成的配置脚本核心作用是检测环境、适配平台、生成Makefile新手只需掌握“配置→编译→安装”核心三步2.鸿蒙PC交叉编译的核心是通过–hostaarch64-linux-ohos指定目标架构并提前配置鸿蒙PC SDK的交叉编译器环境变量3.鸿蒙PC编译需确保编译器、依赖库均为适配鸿蒙PC的aarch64版本避免混用x86架构的工具或依赖。3.5 确认编译产物安装完成后进入target目录会看到以下核心产物适配aarch64-linux-ohos架构lib/库文件目录包含libnghttp2.so核心文件。bin/工具目录包含鸿蒙PC版可执行文件用于验证库可用性但是这时空的是因为这个库不是可执行程序。因为这个库不是可执行程序所以不能直接运行所以我们这里可以手写一个C的程序来验证一下库是否可用#includestdio.h#includestring.h#includestdint.h#includenghttp2/nghttp2.hintmain(int argc,char**argv){nghttp2_session_callbacks*callbacksNULL;nghttp2_session*sessionNULL;nghttp2_session_callbacks_new(callbacks);nghttp2_session_client_new(session,callbacks,NULL);nghttp2_settings_entry iv[1];iv[0].settings_idNGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS;iv[0].value100;nghttp2_submit_settings(session,NGHTTP2_FLAG_NONE,iv,1);constchar*path/;constchar*hostwww.baidu.com;constchar*schemehttps;if(argc1)pathargv[1];if(argc2)hostargv[2];nghttp2_nv hdrs[]{{(uint8_t*):method,(uint8_t*)GET,7,3,NGHTTP2_NV_FLAG_NONE},{(uint8_t*):path,(uint8_t*)path,5,(uint16_t)strlen(path),NGHTTP2_NV_FLAG_NONE},{(uint8_t*):scheme,(uint8_t*)scheme,7,(uint16_t)strlen(scheme),NGHTTP2_NV_FLAG_NONE},{(uint8_t*):authority,(uint8_t*)host,10,(uint16_t)strlen(host),NGHTTP2_NV_FLAG_NONE},{(uint8_t*)accept,(uint8_t*)*/*,6,3,NGHTTP2_NV_FLAG_NONE},};int32_t stream_idnghttp2_submit_request(session,NULL,hdrs,sizeof(hdrs)/sizeof(hdrs[0]),NULL,NULL);constuint8_t*data;ssize_t lennghttp2_session_mem_send(session,data);if(len0){fprintf(stderr,mem_send error: %zd\n,len);nghttp2_session_del(session);nghttp2_session_callbacks_del(callbacks);return1;}constnghttp2_info*infonghttp2_version(0);printf(nghttp2 version: %s\n,info-version_str);printf(stream id: %d\n,(int)stream_id);printf(encoded length: %zd\n,len);for(ssize_t i0;ilen;i){printf(%02X,data[i]);}printf(\n);nghttp2_session_del(session);nghttp2_session_callbacks_del(callbacks);return0;}以上代码的作用是创建一个简单的 HTTP/2 客户端会话构造一个 GET 请求并序列化到内存中。这里不涉及网络通信仅用于演示库的 API 使用和功能验证。1.初始化一个 HTTP/2 客户端会话设置一个简单的 SETTINGS 参数。2.构造一个带伪首部字段的 GET 请求:method/:path/:scheme/:authority。3.将当前待发送的 HTTP/2 帧序列化到内存中并以十六进制打印出来。4.不进行任何网络连接或收发仅展示“会话打包出的字节”。接下来我们使用鸿蒙PC的clang进行编译将上面写的C程序编译成可执行文件/root/harmonypc/linux/native/llvm/bin/clang--targetaarch64-linux-ohos\-I/root/test/nghttp2-1.68.0/nghttp2_target/include \/root/test/main.c \-L/root/test/nghttp2-1.68.0/nghttp2_target/lib \-lnghttp2 \-static-o/root/test/hello_nghttp2这里最后打包的文件为hello_nghttp2将hello_nghttp2拷贝到鸿蒙PC的/root目录下。3.6 鸿蒙PC端验证所有文件拷贝到鸿蒙PC之后启动终端执行binary-sign-tool命令分别对hello_nghttp2进行自签名。先需要进行签名部署在鸿蒙 PC 上部署的程序和库文件完成后需要进行 签名 操作保证安全性与系统兼容性binary-sign-tool sign-inFile \xxxx\hello_nghttp2-outFile \xxxx\hello_nghttp2-selfSign1如果出现 “Permission denied” 等错误需要检查当前用户是否有足够的权限执行这些操作或者尝试使用sudo来提升权限我这里使用chmod 755 命令来修改文件权限。接下来执行hello_nghttp2程序至此鸿蒙PC版的libnghttp2编译移植完成。四、错误处理4.1 错误1Relocations in generic ELF (EM:183) error adding symbols:file in wrong format在编译鸿蒙PC版的libnghttp2时configure已经顺利通过但是执行make命令编译时最后链接阶段遇到如下报错从日志看编译器使用的ohos sdk的clang但是最终链接so时链接器没有使用ohos sdk的lld而是用了系统的ld即使我们定义了LD环境变量也不起作用就导致了最终的链接失败。在CFLAGS里指定了–targetaarch64-linux-ohos架构但是libtool并没有去使用它导致平台架构判断失败使用了错误的链接器。要解决这个问题需要在执行configure命令时给CC环境变量强制追加一个–targetaarch64-linux-ohos参考命令如下所示我们将预先定义好的CFLAGS环境变量追加给CC环境变量即可CC$CC $CFLAGS./configure--hostaarch64-unknown-linux-musl--prefixpwd/nghttp2_target重新执行./configure之后重新运行make命令就可以顺利编译通过了。4.2 错误2checking host system type… Invalid configurationaarch64-linux-ohos: OSohos’ not recognizedds-c and-o together...yes checkingforstdio.h...yes checkingforstdlib.h...yes checkingforstring.h...yes checkingforinttypes.h...yes checkingforstdint.h...yes checkingforstrings.h...yes checkingforsys/stat.h...yes checkingforsys/types.h...yes checkingforunistd.h...yes checkingforwchar.h...yes checkingforminix/config.h...no checkingforvfork.h...no checking whether it is safe to define __EXTENSIONS__...yes checking whether _XOPEN_SOURCE should be defined...no checking build system type...x86_64-pc-linux-gnu checking host system type...Invalid configurationaarch64-linux-ohos: OSohos not recognizedconfigure:error:/bin/bash././config.sub aarch64-linux-ohos failed基于OHOS SDK环境对某些C/C应用进行交叉编译时需要指定–hostaarch64-linux-ohos参数以便configure能正常识别目标平台架构和编译器等信息在编译命令时遇到了一个报错在执行configure过程中调用了/bin/bash ./build-aux/config.sub aarch64-linux-ohos但是脚本不识别ohos这个配置导致configure失败更换host为aarch64-unknown-linux-musl更换–host参数重新执行configure命令CC$CC $CFLAGS./configure--hostaarch64-unknown-linux-musl--prefixpwd/nghttp2_target五、总结鉴于鸿蒙操作系统HarmonyOS是一种与Windows、Linux及macOS等传统操作系统不同的新型平台其软件架构和EABIEmbedded Application Binary Interface等特性均采用了全新的设计本次移植的核心是“配置正确的交叉编译环境解决系统识别与依赖问题”通过掌握configure的核心逻辑后无论是本地编译还是鸿蒙PC交叉编译核心都是让configure“认对”目标平台鸿蒙PC、“找对”编译器鸿蒙PC SDK版、“配对”依赖库鸿蒙PC适配版就能快速编译出可在鸿蒙PC上运行的程序。欢迎加入开源鸿蒙PC社区 。