常用URL语法传输数据开源命令行工具curl鸿蒙化构建过程深度解析

本文记录通过开源项目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_ARCHOHOS_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_CTYPETOOL_HOMEOHOS_SDK_HOME
    sh 复制代码
    export 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/Makefile

    • PKGS 变量定义需要构建的包列表(包含 curl
    makefile 复制代码
    # base gettext必须,终端正常交互需要
    # curl前置依赖:openssl zlib c-ares libidn2,需要在curl构建前完成构建
    PKGS=bash \
    	gettext \
    	openssl \
    	zlib \
    	c-ares \
    	libidn2 \
    	curl
    • 通过 check-pkgs 机制自动检测 PKGS 变化并触发重新构建
    makefile 复制代码
    check-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"; \
    fi
    • base.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)
    makefile 复制代码
    all: 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
  • 🔨 构建流程
    1. 下载源码包(从 GitHub releases)
    2. 解包并进入 temp/curl-8.14.1 目录
    3. 运行 ./configure 配置构建系统
    4. 使用 make -j $(nproc) 并行编译
    5. 使用 make install 安装
    6. 执行 ELF strip 减小体积
    7. 复制到 ../sysroot
  • 🔧 通用工具链与路径build-hnp/utils/Makefrag
    • CC/CXX/LD/AR/RANLIB/... 均指向 OHOS SDK 的 LLVM 工具链
    • 下载支持多镜像回退:wgetcurl,主镜像失败时自动尝试备用镜像
  • 📦 依赖关系
    • 前置依赖opensslzlibc-areslibidn2(均已在 sysroot 中提供)
    • 建议构建顺序openssl → zlib → c-ares → libidn2 → curl

📋 关键日志与过程节点

  • 📥 下载与解包
    • 从 GitHub releases 下载 curl-8.14.1.tar.xz
    • 完成解包并进入 temp/curl-8.14.1 目录
    • 下载规则支持多镜像回退:wgetcurl 兜底
  • ⚙️ 配置阶段
    • 运行 ./configure --prefix=... --host=aarch64-unknown-linux-musl ...
    • 工具链与链接器探测成功(clang/ld.lld
    • 检测到 OpenSSL、zlib、c-ares、libidn2 依赖
    • 配置成功,启用共享库构建
    • 生成 Makefile 和构建配置
  • 🔨 编译与安装
    • 使用 make -j $(nproc) 并行编译
    • 成功编译生成 libcurl.so.4.8.0curl 命令行工具
    • 使用 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.3libcrypto.so.3libcares.solibidn2.solibz.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/libLDFLAGS
    • 确保 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 之前构建
  • ✅ 解决方法
    • 确保 opensslzlibc-areslibidn2curl 之前构建
    • 检查 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=
  • 🔎 原因:传入的架构不在支持列表中
  • ✅ 解决方法
    • 确保传入支持架构(aarch64x86_64
    • 位置:build-hnp/Makefile:1-49

🔄 重建与扩展

  • 🔧 重建单包

    bash 复制代码
    make -C build-hnp rebuild-curl  # 触发子包重新编译并刷新 .stamp
  • 🧹 清理

    bash 复制代码
    make -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 包。
  • 💡 为保证构建稳定
    • 确保所有依赖库(opensslzlibc-areslibidn2)在 curl 之前构建
    • 使用共享库构建以减少体积
    • 确保通过 create-hnp.sh 触发构建以获得完整环境变量
    • 利用 check-pkgs 机制自动检测包列表变化,无需手动清理
    • curl 为网络传输提供了强大的工具和库支持
    • 常见陷阱包括 OpenSSL 链接失败、编译器探测错误、依赖缺失;当前已通过构建配置和参数处理
    • 建议禁用不需要的协议以减小体积,并根据需要启用特定功能
    • 已完成 aarch64 目标下 curl 的交叉编译与打包,库与头文件进入 sysroot 并纳入 HNP 包

📚 以上为 curl 构建的深度解读与实践记录。

相关推荐
robot_learner1 小时前
11 月 AI 动态:多模态突破・智能体模型・开源浪潮・机器人仿真・AI 安全与主权 AI
人工智能·机器人·开源
坚果派·白晓明2 小时前
通过开源鸿蒙终端工具Termony完成Zlib 命令行工具构建过程深度解读
openharmony·开源鸿蒙·开源软件termony
wei_shuo4 小时前
zoxide 开源鸿蒙 PC 生态适配实战:Rust 交叉编译与 HNP 打包完整指南
rust·开源鸿蒙·zoxide
CoderJia程序员甲4 小时前
GitHub 热榜项目 - 日榜(2025-11-24)
ai·开源·llm·github·ai教程
坚果派·白晓明12 小时前
Tree 命令行工具鸿蒙化构建过程问题及解决方法
openharmony·开源鸿蒙·开源软件termony
TTGGGFF16 小时前
开源项目分享 : Gitee热榜项目 2025-11-24 日榜
gitee·开源
西风未眠17 小时前
一款开源的轻量级云管平台搭建与试用
开源·资源管理·运维工具
开源头条17 小时前
2025开源鸿蒙开发者激励计划正式启动,为生态繁荣注入持久动力
华为·开源·harmonyos
坚果派·白晓明18 小时前
开源鸿蒙化构建GNU Tar 1.35:完整过程与验证
openharmony·开源鸿蒙·开源软件termony