本文记录通过开源项目Termony目录下使用命令 OHOS_ARCH=aarch64 OHOS_ABI=arm64-v8a sh ./create-hnp.sh 构建 curl 8.14.1 的完整过程,包括环境、构建链路、关键日志、常见问题与解决方案、产物验证与重建方法,便于复现与运维。
📖 curl 简介
curl(Client URL)是一个强大的命令行工具和库,用于使用 URL 语法传输数据。它支持多种协议(HTTP、HTTPS、FTP、FTPS、SCP、SFTP、TFTP、DICT、TELNET、LDAP、FILE 等),是网络开发和测试中最常用的工具之一。
🎯 curl 的作用与重要性
curl 是网络传输的核心工具,提供了:
- 多协议支持:支持 HTTP、HTTPS、FTP、FTPS、SCP、SFTP、TFTP、DICT、TELNET、LDAP、FILE 等多种协议
- 命令行工具:强大的命令行接口,支持各种数据传输场景
- 编程库:libcurl 库提供 C API,被广泛用于各种应用程序
- 跨平台:支持多种操作系统和平台
- 网络调试:用于测试和调试网络服务和 API
- 数据传输:支持上传、下载、流式传输等多种数据传输方式
🔧 curl 核心特性
1. 多协议支持
- HTTP/HTTPS:完整的 HTTP 协议支持,包括 HTTP/1.1、HTTP/2、HTTP/3
- FTP/FTPS:文件传输协议支持
- SCP/SFTP:安全文件传输协议支持
- 其他协议:TFTP、DICT、TELNET、LDAP、FILE 等
- 协议自动检测:根据 URL 自动选择协议
2. 安全特性
- SSL/TLS 支持:通过 OpenSSL 提供完整的 SSL/TLS 支持
- 证书验证:支持 CA 证书验证和自定义证书
- 客户端证书:支持客户端证书认证
- 代理支持:支持 HTTP、SOCKS4、SOCKS5 代理
3. 高级功能
- 异步 DNS:通过 c-ares 支持异步 DNS 解析
- 国际化域名:通过 libidn2 支持 IDN(国际化域名)
- 压缩支持:通过 zlib 支持 gzip、deflate 压缩
- 断点续传:支持断点续传功能
- Cookie 管理:支持 Cookie 的读取和写入
4. 命令行工具
- 丰富的选项:支持 200+ 命令行选项
- 多种输出格式:支持 JSON、XML、自定义格式输出
- 进度显示:支持传输进度显示
- 详细输出:支持详细的调试和诊断输出
5. 编程接口
- C API:提供完整的 C 语言接口(libcurl)
- 多语言绑定:支持 Python、PHP、Java、Go 等多种语言绑定
- 简单易用:简洁的 API 设计
- 线程安全:线程安全的实现
6. 应用场景
- API 测试:测试 REST API 和 Web 服务
- 文件下载:下载文件和资源
- 数据上传:上传文件和表单数据
- 网络调试:调试网络问题和性能
- 自动化脚本:在脚本中执行网络操作
🚀 构建入口与环境
-
📝 执行命令 :
OHOS_ARCH=aarch64 OHOS_ABI=arm64-v8a sh ./create-hnp.sh -
🔧 入口脚本 :
create-hnp.sh- 检查必需的环境变量
OHOS_ARCH和OHOS_ABI
sh# 检查必需的环境变量 if [ -z "$OHOS_ARCH" ]; then echo "Error: OHOS_ARCH is not set" echo "Usage: OHOS_ARCH=aarch64 OHOS_ABI=arm64-v8a sh ./create-hnp.sh" echo " or: OHOS_ARCH=x86_64 OHOS_ABI=x86_64 sh ./create-hnp.sh" exit 1 fi if [ -z "$OHOS_ABI" ]; then echo "Error: OHOS_ABI is not set" echo "Usage: OHOS_ARCH=aarch64 OHOS_ABI=arm64-v8a sh ./create-hnp.sh" echo " or: OHOS_ARCH=x86_64 OHOS_ABI=x86_64 sh ./create-hnp.sh" exit 1 fi- 导出
LC_CTYPE、TOOL_HOME、OHOS_SDK_HOME
shexport LC_CTYPE=C export TOOL_HOME=/Applications/DevEco-Studio.app/Contents export OHOS_SDK_HOME=$TOOL_HOME/sdk/default/openharmony- 执行
make -C build-hnp
- 检查必需的环境变量
-
📦 顶层构建 :
build-hnp/MakefilePKGS变量定义需要构建的包列表(包含curl)
makefile# base gettext必须,终端正常交互需要 # curl前置依赖:openssl zlib c-ares libidn2,需要在curl构建前完成构建 PKGS=bash \ gettext \ openssl \ zlib \ c-ares \ libidn2 \ curl- 通过
check-pkgs机制自动检测PKGS变化并触发重新构建
makefilecheck-pkgs: @echo "$(PKGS)" > $(PKGS_MARKER).tmp @if [ -f $(PKGS_MARKER) ]; then \ if ! cmp -s $(PKGS_MARKER) $(PKGS_MARKER).tmp; then \ echo "PKGS changed from '$$(cat $(PKGS_MARKER))' to '$(PKGS)', cleaning build artifacts to force rebuild..."; \ rm -f base.hnp; \ old_pkgs="$$(cat $(PKGS_MARKER))"; \ for pkg in $$old_pkgs; do \ if ! echo "$(PKGS)" | grep -qw "$$pkg"; then \ echo " Removing stale stamp file: $$pkg/.stamp"; \ rm -f "$$pkg/.stamp"; \ fi; \ done; \ for pkg in $(PKGS); do \ if ! echo "$$old_pkgs" | grep -qw "$$pkg"; then \ echo " Removing stamp file for new package: $$pkg/.stamp"; \ rm -f "$$pkg/.stamp"; \ fi; \ done; \ fi; \ else \ echo "Creating PKGS marker file with: $(PKGS)"; \ fi @mv $(PKGS_MARKER).tmp $(PKGS_MARKER)- 自动合并
external-hnp目录下的外部 HNP 包
makefile# merge external hnp packages @if ls ../external-hnp/*.hnp >/dev/null 2>&1; then \ echo "Merging external HNP packages into sysroot..."; \ tmpdir="sysroot/.external_merge"; rm -rf "$$tmpdir"; mkdir -p "$$tmpdir"; \ for pkg in ../external-hnp/*.hnp; do \ echo " -> $$pkg"; \ if command -v ditto >/dev/null 2>&1; then \ ditto -x -k "$$pkg" "$$tmpdir" 2>/dev/null || unzip -q -o "$$pkg" -d "$$tmpdir" 2>/dev/null || true; \ else \ unzip -q -o "$$pkg" -d "$$tmpdir" 2>/dev/null || true; \ fi; \ if [ -d "$$tmpdir/sysroot" ]; then \ echo " Found sysroot/, merging directly..."; \ cp -a "$$tmpdir/sysroot/." sysroot/; \ else \ usr_dirs="$$(find "$$tmpdir" -type d -name usr 2>/dev/null)"; \ if [ -n "$$usr_dirs" ]; then \ for ud in $$usr_dirs; do \ if [ -n "$$ud" ] && [ -d "$$ud" ]; then \ echo " Found usr directory: $$ud"; \ for comp in bin lib include share; do \ if [ -d "$$ud/$$comp" ] && [ -n "$$(ls -A "$$ud/$$comp" 2>/dev/null)" ]; then \ mkdir -p "sysroot/$$comp"; \ cp -a "$$ud/$$comp/." "sysroot/$$comp/" 2>/dev/null || true; \ fi; \ done; \ if [ -d "$$ud/lib/pkgconfig" ] && [ -n "$$(ls -A "$$ud/lib/pkgconfig" 2>/dev/null)" ]; then \ mkdir -p "sysroot/lib/pkgconfig"; \ cp -a "$$ud/lib/pkgconfig/." "sysroot/lib/pkgconfig/" 2>/dev/null || true; \ fi; \ fi; \ done; \ else \ top_dirs="$$(find "$$tmpdir" -maxdepth 1 -type d ! -path "$$tmpdir" 2>/dev/null)"; \ merged=0; \ for top_dir in $$top_dirs; do \ if [ -n "$$top_dir" ] && [ -d "$$top_dir" ]; then \ for comp in bin lib include share; do \ if [ -d "$$top_dir/$$comp" ] && [ -n "$$(ls -A "$$top_dir/$$comp" 2>/dev/null)" ]; then \ echo " Found $$comp/ in $$(basename "$$top_dir"), merging to sysroot/$$comp/..."; \ mkdir -p "sysroot/$$comp"; \ cp -a "$$top_dir/$$comp/." "sysroot/$$comp/" 2>/dev/null || true; \ merged=1; \ fi; \ done; \ if [ -d "$$top_dir/lib/pkgconfig" ] && [ -n "$$(ls -A "$$top_dir/lib/pkgconfig" 2>/dev/null)" ]; then \ mkdir -p "sysroot/lib/pkgconfig"; \ cp -a "$$top_dir/lib/pkgconfig/." "sysroot/lib/pkgconfig/" 2>/dev/null || true; \ merged=1; \ fi; \ fi; \ done; \ if [ "$$merged" = "0" ]; then \ echo " No standard directories found, merging all content..."; \ cp -a "$$tmpdir/." sysroot/ 2>/dev/null || true; \ fi; \ fi; \ fi; \ rm -rf "$$tmpdir"; mkdir -p "$$tmpdir"; \ done; \ rm -rf "$$tmpdir"; \ echo " Ensuring executable permissions for binaries..."; \ find sysroot/bin -type f -exec chmod +x {} \; 2>/dev/null || true; \ else \ echo "No external HNP packages found, skipping merge"; \ fibase.hnp依赖所有包的.stamp和外部 HNP 包
makefile%/.stamp: %/Makefile make -C $(patsubst %/.stamp,%,$@) touch $@ rebuild-%: make -C $(patsubst rebuild-%,%,$@) touch $(patsubst rebuild-%,%/.stamp,$@)- 总目标
all: copy,打包base.hnp并拷贝到entry/hnp/$(OHOS_ABI)
makefileall: copy copy: base.hnp rm -f ../entry/hnp/$(OHOS_ABI)/*.hnp cp $^ ../entry/hnp/$(OHOS_ABI) cp $^ ../entry/hnp/$(OHOS_ABI)/base-public.hnp
⚙️ curl 包的构建配置
- 📁 包目录 :
build-hnp/curl/Makefile- 继承通用规则:
include ../utils/Makefrag - 源地址:
https://github.com/curl/curl/releases/download/curl-8_14_1/curl-8.14.1.tar.xz - 版本:
8.14.1
- 继承通用规则:
makefile
include ../utils/Makefrag
SOURCE_URL = https://github.com/curl/curl/releases/download/curl-8_14_1/curl-8.14.1.tar.xz
SOURCE_FILE = curl-8.14.1.tar.xz
SOURCE_DIR = curl-8.14.1
- ⚙️ Autotools 配置参数 :
--prefix=$(PREFIX)- 安装前缀(/data/app/base.org/base_1.0)--host $(OHOS_ARCH)-unknown-linux-musl- 目标平台--enable-shared- 构建共享库--disable-static- 禁用静态库--with-openssl=$(shell pwd)/../sysroot- OpenSSL 路径--with-zlib- 启用 zlib 支持--with-libidn2- 启用 libidn2 支持(IDN)--enable-ares- 启用 c-ares 支持(异步 DNS)--disable-ldap --disable-ldaps- 禁用 LDAP 协议--disable-rtsp --disable-dict --disable-telnet --disable-tftp- 禁用其他协议--disable-pop3 --disable-imap --disable-smtp --disable-gopher- 禁用邮件和 Gopher 协议--disable-manual --disable-unix-sockets --disable-mqtt- 禁用其他功能--disable-http-auth-gssnegotiate --disable-nls --disable-proxy- 禁用认证和代理--enable-optimize- 启用优化
makefile
CONFIG_ARGS = --prefix=$(PREFIX) --host $(OHOS_ARCH)-unknown-linux-musl \
--without-libssh --without-libssh2 --without-libpsl --with-libidn2 --enable-ares \
--without-nghttp2 --without-brotli --without-zstd --without-libgsasl \
--enable-shared --disable-static \
--disable-ldap --disable-ldaps --disable-rtsp --disable-dict --disable-telnet --disable-tftp \
--disable-pop3 --disable-imap --disable-smtp --disable-gopher --disable-manual \
--disable-unix-sockets --with-ca-path=/etc/ssl/certs --with-ca-bundle=/etc/ssl/certs/cacert.pem \
--disable-http-auth-gssnegotiate --disable-mqtt --disable-nls --disable-proxy --enable-optimize \
--with-ssl --with-zlib --with-openssl=$(shell pwd)/../sysroot \
CPPFLAGS="--sysroot=$(OHOS_SDK_HOME)/native/sysroot -I$(OHOS_SDK_HOME)/native/sysroot/usr/include -I$(shell pwd)/../sysroot/include -D_FORTIFY_SOURCE=2" \
CFLAGS="--target=$(OHOS_ARCH)-unknown-linux-ohos --sysroot=$(OHOS_SDK_HOME)/native/sysroot -O2 -g -pipe -fstack-protector-strong -fno-omit-frame-pointer" \
LDFLAGS="--target=$(OHOS_ARCH)-unknown-linux-ohos --sysroot=$(OHOS_SDK_HOME)/native/sysroot -L$(shell pwd)/../sysroot/lib" \
PKG_CONFIG_PATH=$(shell pwd)/../sysroot/lib/pkgconfig
- 🔨 构建流程 :
- 下载源码包(从 GitHub releases)
- 解包并进入
temp/curl-8.14.1目录 - 运行
./configure配置构建系统 - 使用
make -j $(nproc)并行编译 - 使用
make install安装 - 执行 ELF strip 减小体积
- 复制到
../sysroot

- 🔧 通用工具链与路径 :
build-hnp/utils/MakefragCC/CXX/LD/AR/RANLIB/...均指向 OHOS SDK 的 LLVM 工具链- 下载支持多镜像回退:
wget→curl,主镜像失败时自动尝试备用镜像
- 📦 依赖关系 :
- 前置依赖 :
openssl、zlib、c-ares、libidn2(均已在sysroot中提供) - 建议构建顺序 :
openssl → zlib → c-ares → libidn2 → curl
- 前置依赖 :
📋 关键日志与过程节点
- 📥 下载与解包 :
- 从 GitHub releases 下载
curl-8.14.1.tar.xz - 完成解包并进入
temp/curl-8.14.1目录 - 下载规则支持多镜像回退:
wget→curl兜底
- 从 GitHub releases 下载
- ⚙️ 配置阶段 :
- 运行
./configure --prefix=... --host=aarch64-unknown-linux-musl ... - 工具链与链接器探测成功(
clang/ld.lld) - 检测到 OpenSSL、zlib、c-ares、libidn2 依赖
- 配置成功,启用共享库构建
- 生成
Makefile和构建配置
- 运行
- 🔨 编译与安装 :
- 使用
make -j $(nproc)并行编译 - 成功编译生成
libcurl.so.4.8.0和curl命令行工具 - 使用
make install安装到临时前缀 - 执行
llvm-strip剥离共享库和二进制符号 - 复制到
../sysroot
- 使用
- 📦 打包 :
- 完成
base.hnp重打包,拷贝产物到entry/hnp/arm64-v8a/ - curl 库和工具已成功打包到
base.hnp中
- 完成
✅ 产物验证
📦 检查打包文件
bash
ls build-hnp/base.hnp # 应存在
ls entry/hnp/arm64-v8a/*.hnp # 应包含 base.hnp 与 base-public.hnp

🔍 检查二进制和库文件
bash
# 检查 curl 命令行工具
ls -lh build-hnp/sysroot/bin/curl build-hnp/sysroot/bin/curl-config
file build-hnp/sysroot/bin/curl
# 检查库文件
ls -lh build-hnp/sysroot/lib/libcurl.so*
file build-hnp/sysroot/lib/libcurl.so.4.8.0
# 检查头文件
ls -lh build-hnp/sysroot/include/curl/curl.h
# 检查 pkg-config 文件
ls -lh build-hnp/sysroot/lib/pkgconfig/libcurl.pc
cat build-hnp/sysroot/lib/pkgconfig/libcurl.pc

✅ 构建验证结果:
- ✅ curl 命令行工具已成功安装:
curl(196K) - 主程序二进制curl-config(6.8K) - 配置工具wcurl(10K) - 包装脚本
- ✅ libcurl 库已安装:
libcurl.so.4.8.0(535K) - 主库文件libcurl.so.4- 版本符号链接libcurl.so- 通用符号链接
- ✅ 文件类型:ELF 64-bit LSB pie executable/shared object, ARM aarch64
- ✅ 动态链接:interpreter
/lib/ld-musl-aarch64.so.1 - ✅ 已剥离符号:
stripped - ✅ 头文件已安装:
curl/curl.h(131K) 及完整的头文件集合 - ✅ pkg-config 文件已安装:
libcurl.pc - ✅ 依赖库已安装:
libssl.so.3、libcrypto.so.3、libcares.so、libidn2.so、libz.so - ✅ 已打包到
base.hnp中
🐛 常见问题与处理
❌ 问题 1:OpenSSL 链接失败
- 🔍 症状:链接错误,无法找到 OpenSSL 库
- 🔎 原因 :
pkg-config前缀指向/data/app/base.org/base_1.0,构建期找不到库 - ✅ 解决方法 :
- 使用
--with-openssl=$(shell pwd)/../sysroot明确 OpenSSL 路径 - 添加
-L$(shell pwd)/../sysroot/lib到LDFLAGS - 确保 OpenSSL 已构建并安装到
sysroot - 位置:
build-hnp/curl/Makefile:14
- 使用
❌ 问题 2:编译器探测错误
- 🔍 症状 :
aarch64-unknown-linux-musl-gcc被探测 - 🔎 原因:交叉环境应使用 clang 三元组
- ✅ 解决方法 :
- 确保
CC已由通用Makefrag导出并参与configure - 检查
OHOS_SDK_HOME环境变量是否正确设置 - 位置:
build-hnp/utils/Makefrag
- 确保
❌ 问题 3:依赖缺失
- 🔍 症状:配置失败,提示找不到依赖库
- 🔎 原因:依赖库未在 curl 之前构建
- ✅ 解决方法 :
- 确保
openssl、zlib、c-ares、libidn2在curl之前构建 - 检查
PKG_CONFIG_PATH是否正确设置 - 位置:
build-hnp/curl/Makefile:18
- 确保
❌ 问题 4:非必要协议导致依赖缺失
- 🔍 症状 :配置失败,提示找不到
nghttp2等依赖 - 🔎 原因:启用了不需要的协议,但依赖库未提供
- ✅ 解决方法 :
- 禁用不需要的协议:
--without-nghttp2、--without-brotli、--without-zstd - 禁用不需要的功能:
--disable-ldap、--disable-rtsp、--disable-dict等 - 位置:
build-hnp/curl/Makefile:7-12
- 禁用不需要的协议:
❌ 问题 5:GitHub 下载失败
- 🔍 症状:无法从 GitHub releases 下载源码包
- 🔎 原因:网络问题或 GitHub 访问受限
- ✅ 解决方法 :
- 手动下载源码包放置到
build-hnp/curl/download/curl-8.14.1.tar.xz - 使用代理或镜像站点下载
- 位置:
build-hnp/curl/Makefile:3
- 手动下载源码包放置到
❌ 问题 6:链接失败
- 🔍 症状 :链接错误,无法找到
libcurl或依赖库符号 - 🔎 原因:链接时未指定库或库路径不正确
- ✅ 解决方法 :
- 确保链接时添加
-lcurl和依赖库 - 使用
pkg-config --libs libcurl获取正确的链接标志 - 检查
LD_LIBRARY_PATH是否包含库路径 - 位置:编译和链接阶段
- 确保链接时添加
❌ 问题 7:架构不支持
- 🔍 症状 :
Unsupported OHOS_ARCH= - 🔎 原因:传入的架构不在支持列表中
- ✅ 解决方法 :
- 确保传入支持架构(
aarch64或x86_64) - 位置:
build-hnp/Makefile:1-49
- 确保传入支持架构(
🔄 重建与扩展
-
🔧 重建单包:
bashmake -C build-hnp rebuild-curl # 触发子包重新编译并刷新 .stamp -
🧹 清理:
bashmake -C build-hnp clean # 清理 sysroot、所有 .stamp 和 PKGS_MARKER -
📦 扩展:curl 是网络传输的核心工具,被广泛用于各种应用程序
-
🔄 自动重建机制:
- 修改
PKGS后,check-pkgs会自动检测变化并触发重新构建 - 新增外部 HNP 包到
external-hnp目录后,会自动合并到base.hnp
- 修改
💡 实践建议
- 🔧 构建配置:使用共享库构建以减少体积,适合大多数场景
- 🚀 依赖管理:确保所有依赖库在 curl 之前构建
- 📦 网络应用:curl 为网络应用提供了强大的工具和库支持
- 🔗 编程接口 :使用
pkg-config获取正确的编译和链接标志 - 🌐 协议支持:根据需要启用或禁用协议以减小体积
📝 结论与建议
- ✅ 本次已在 aarch64 环境下完成 curl 8.14.1 的交叉编译与打包,curl 工具和 libcurl 库已安装到
sysroot并纳入 HNP 包。 - 💡 为保证构建稳定 :
- 确保所有依赖库(
openssl、zlib、c-ares、libidn2)在 curl 之前构建 - 使用共享库构建以减少体积
- 确保通过
create-hnp.sh触发构建以获得完整环境变量 - 利用
check-pkgs机制自动检测包列表变化,无需手动清理 - curl 为网络传输提供了强大的工具和库支持
- 常见陷阱包括 OpenSSL 链接失败、编译器探测错误、依赖缺失;当前已通过构建配置和参数处理
- 建议禁用不需要的协议以减小体积,并根据需要启用特定功能
- 已完成 aarch64 目标下 curl 的交叉编译与打包,库与头文件进入
sysroot并纳入 HNP 包
- 确保所有依赖库(
📚 以上为 curl 构建的深度解读与实践记录。