使用 PowerShell + MinGW 编译 libcurl 静态库指南

使用 PowerShell + MinGW 编译 libcurl 静态库指南

适用于:Windows + Qt 5.12.8 自带 MinGW 7.3.0 工具链
目标:生成纯 FTP 功能的 libcurl.a,零外部依赖
实测版本:curl-8.21.0

一、背景

libcurl 作为 C/C++ 生态最成熟的网络库之一,覆盖 FTP、HTTP、SFTP 等数十种协议。但在 Windows + MinGW 环境下,预编译包通常由新版 MinGW-w64 构建,与 Qt 5.12.8 自带的 MinGW 7.3.0 存在 ABI 不兼容问题,导致 undefined reference to curl_easy_init 等链接错误。

本文给出了一套 纯 PowerShell 环境(无需 MSYS2/Git Bash)下,使用 CMake + MinGW 自行编译 libcurl 静态库的完整流程。

二、环境要求

组件 版本要求
Windows 7 / 10 / 11(Win32 线程模型)
MinGW Qt 5.12.8 自带 mingw730
CMake 3.15+(或 Qt Creator 自带)
curl 源码 8.x 系列(本文以 8.21.0 为例)
PowerShell 5.1+

提示:在 Qt Creator 中执行时,可直接使用 "项目 → 构建环境" 查看 MinGW 的确切路径。

三、获取源码

# 推荐在 C:\Work\ 下统一管理第三方依赖
cd C:\Work
mkdir curl
cd curl

# 从官网下载
Invoke-WebRequest -Uri "https://curl.se/download/curl-8.21.0.tar.gz" `
    -OutFile "curl-8.21.0.tar.gz"

# 解压(PowerShell 5+)
tar -xzf curl-8.21.0.tar.gz

四、编译参数详解

为了生成 最小体积、纯 FTP 功能 的静态库,我们关闭所有非必需特性:

CMake 选项 作用 关闭原因
BUILD_SHARED_LIBS=OFF 编译静态库 部署无需 DLL
BUILD_CURL_EXE=OFF 不编译 curl.exe 仅需要库文件
CURL_USE_OPENSSL=OFF 禁用 OpenSSL FTP 无需加密传输
CURL_USE_LIBSSH2=OFF 禁用 SSH 不涉及 SFTP
CURL_USE_LIBPSL=OFF 禁用 PSL 减少域名解析依赖
CURL_ZLIB/BROTLI/ZSTD=OFF 禁用压缩 FTP 不需要
CURL_USE_NGHTTP2/3=OFF 禁用 HTTP/2, HTTP/3 不涉及 HTTP 协议
CURL_DISABLE_LDAP=ON 禁用 LDAP 非目录服务场景
CURL_DISABLE_TESTS=ON 跳过测试代码 加速编译

激活项:

选项 作用
USE_WINDOWS_SSPI=ON 使用 Windows 原生认证接口
_WIN32_WINNT=0x0600 最低系统要求 Vista(避免 configure 报错)

五、编译步骤

5.1 32 位(MinGW 32-bit)

# ========== 设置 MinGW 32 位编译器 ==========
$env:PATH = "C:\Qt\Qt5.12.8\Tools\mingw730_32\bin;$env:PATH"

# ========== 进入源码目录 & 创建构建目录 ==========
cd C:\Work\curl\curl-8.21.0
Remove-Item build32 -Recurse -Force -ErrorAction SilentlyContinue
mkdir build32
cd build32

# ========== CMake 配置 ==========
cmake .. -G "MinGW Makefiles" `
    -DCMAKE_INSTALL_PREFIX=C:/Work/curl/curl-8.21.0/build32 `
    -DBUILD_SHARED_LIBS=OFF `
    -DBUILD_CURL_EXE=OFF `
    -DBUILD_TESTING=OFF `
    -DCURL_DISABLE_TESTS=ON `
    -DCURL_USE_OPENSSL=OFF `
    -DCURL_USE_LIBSSH2=OFF `
    -DCURL_USE_LIBPSL=OFF `
    -DCURL_ZLIB=OFF `
    -DCURL_ZSTD=OFF `
    -DCURL_BROTLI=OFF `
    -DCURL_USE_NGHTTP2=OFF `
    -DCURL_USE_NGHTTP3=OFF `
    -DCURL_DISABLE_LDAP=ON `
    -DUSE_WINDOWS_SSPI=ON `
    -DCMAKE_BUILD_TYPE=Release `
    -DCMAKE_C_FLAGS="-D_WIN32_WINNT=0x0600" `
    -DCMAKE_C_STANDARD_LIBRARIES="-lws2_32 -liphlpapi -lbcrypt -lcrypt32 -lsecur32"

# ========== 编译 & 安装 ==========
mingw32-make -j4
mingw32-make install

5.2 64 位(MinGW 64-bit)

# ========== 设置 MinGW 64 位编译器 ==========
$env:PATH = "C:\Qt\Qt5.12.8\Tools\mingw730_64\bin;$env:PATH"

# ========== 进入源码目录 & 创建构建目录 ==========
cd C:\Work\curl\curl-8.21.0
Remove-Item build64 -Recurse -Force -ErrorAction SilentlyContinue
mkdir build64
cd build64

# ========== CMake 配置 ==========
cmake .. -G "MinGW Makefiles" `
    -DCMAKE_INSTALL_PREFIX=C:/Work/curl/curl-8.21.0/build64 `
    -DBUILD_SHARED_LIBS=OFF `
    -DBUILD_CURL_EXE=OFF `
    -DBUILD_TESTING=OFF `
    -DCURL_DISABLE_TESTS=ON `
    -DCURL_USE_OPENSSL=OFF `
    -DCURL_USE_LIBSSH2=OFF `
    -DCURL_USE_LIBPSL=OFF `
    -DCURL_ZLIB=OFF `
    -DCURL_ZSTD=OFF `
    -DCURL_BROTLI=OFF `
    -DCURL_USE_NGHTTP2=OFF `
    -DCURL_USE_NGHTTP3=OFF `
    -DCURL_DISABLE_LDAP=ON `
    -DUSE_WINDOWS_SSPI=ON `
    -DCMAKE_BUILD_TYPE=Release `
    -DCMAKE_C_FLAGS="-D_WIN32_WINNT=0x0600" `
    -DCMAKE_C_STANDARD_LIBRARIES="-lws2_32 -liphlpapi -lbcrypt -lcrypt32 -lsecur32"

# ========== 编译 & 安装 ==========
mingw32-make -j4
mingw32-make install

注意mingw32-make 是 MinGW 下 make 的统一名称,32 位和 64 位工具链都使用这个名字。

六、编译产物

build64/
├── include/
│   └── curl/
│       ├── curl.h          # 主头文件
│       ├── easy.h           # easy 接口
│       ├── curlver.h        # 版本信息
│       └── ... (其他头文件)
└── lib/
    └── libcurl.a           # 静态库(约 1.4 MB)

验证符号:

# 检查关键函数是否存在
nm build64\lib\libcurl.a | Select-String "curl_easy_init"
# 应输出:0000000000000300 T curl_easy_init

T 标记表示该符号已被定义(Text section),U 则表示未定义引用,需要其他库提供。

七、集成到 CMake 项目

7.1 目录结构

your-project/
└── third_party/
    └── curl-8.21.0/
        ├── include/curl/    ← 拷贝 build64/include/curl/*
        └── lib/
            ├── win-x64/
            │   └── libcurl.a
            └── win-x32/
                └── libcurl.a

7.2 CMakeLists.txt 配置

set(CURL_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/third_party/curl-8.21.0)
include_directories(${CURL_ROOT}/include)

# 静态链接
add_definitions(-DCURL_STATICLIB)

if(WIN32)
    if(CMAKE_SIZEOF_VOID_P EQUAL 8)
        # 64 位
        target_link_libraries(YourTarget PRIVATE
            ${CURL_ROOT}/lib/win-x64/libcurl.a
            ws2_32 iphlpapi bcrypt crypt32 secur32)
    else()
        # 32 位
        target_link_libraries(YourTarget PRIVATE
            ${CURL_ROOT}/lib/win-x32/libcurl.a
            ws2_32 iphlpapi bcrypt crypt32 secur32)
    endif()
else()
    # Linux / Kylin aarch64
    target_link_libraries(YourTarget PRIVATE
        ${CURL_ROOT}/lib/linux/libcurl.a
        pthread)
endif()

7.3 对应关系

Windows 系统库及其解释:

系统库 作用 解析的符号
ws2_32 Windows Sockets socket, connect, select
iphlpapi IP Helper API if_nametoindex
bcrypt Cryptography Next Gen BCryptGenRandom
crypt32 CryptoAPI CertOpenStore
secur32 Security Support InitSecurityInterfaceA

八、常见问题排查

Q1: 报错 libpsl libs and/or directories were not found

原因libpsl 是一个公共后缀列表库,默认会被 curl 检测。

解决:添加 -DCURL_USE_LIBPSL=OFF


Q2: 链接时 undefined reference to curl_easy_init

原因:预编译 libcurl 的 MinGW 版本与当前工具链 ABI 不兼容。

排查

# 查看 .a 文件是用哪个 GCC 版本编译的
nm libcurl.a 2>&1 | Select-String "curl_easy_init"
# 如果输出为空 → ABI 不匹配,需要自行编译

解决:按本文步骤重新编译。


Q3: __guard_dispatch_icall_fptr 未定义

原因USE_WINDOWS_SSPI=ON 开启了 CFG(Control Flow Guard)但 MinGW 7.3.0 CRT 不支持。

解决:确认已设置了 -DCMAKE_C_FLAGS="-D_WIN32_WINNT=0x0600" 且使用了正确的 MinGW 版本。

若仍报错,可尝试关闭 SSPI:-DUSE_WINDOWS_SSPI=OFF(但 FTP 功能不受影响)。


Q4: if_nametoindex / BCryptGenRandom 等符号找不到

原因:项目最终链接时未包含 curl 间接依赖的 Windows 系统库。

解决:在 target_link_libraries 中加上 ws2_32 iphlpapi bcrypt crypt32 secur32(见第七节)。


Q5: configure: error: Building for Windows Vista or newer is required

原因:新版 curl 要求 _WIN32_WINNT >= 0x0600

解决:已包含在本文的 -DCMAKE_C_FLAGS="-D_WIN32_WINNT=0x0600" 中。

九、总结

通过 CMake + MinGW 按需编译 libcurl,可以得到一份体积小、零外部依赖、完全兼容当前 MinGW 工具链的静态库。实际使用仅需 3 行配置:

add_definitions(-DCURL_STATICLIB)
include_directories(third_party/curl-8.21.0/include)
target_link_libraries(YourTarget PRIVATE libcurl.a ws2_32 iphlpapi bcrypt crypt32 secur32)

本文基于 Qt 5.12.8 / MinGW 7.3.0 / curl-8.21.0 实测通过。
编译时间:约 1~2 分钟(取决于 CPU 核心数)。
适用场景:Windows 平台 C++ 项目,需要轻量级 FTP 客户端能力。

posted @ 2026-06-30 15:57  xhubobo  阅读(21)  评论(0)    收藏  举报