ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Windows下使用VS2019编译支持OpenSSL的Curl静态库完整指南

Windows下使用VS2019编译支持OpenSSL的Curl静态库完整指南 简介本资源是为Windows 10平台开发者提供的、基于Visual Studio 2019预编译完成的64位libcurl静态/动态链接库套件版本7.84.0当前稳定最新版完整支持HTTPS/SSL协议适用于C/C项目快速集成HTTP/FTP等网络通信能力尤其适合初学者规避复杂编译配置或嵌入式、桌面应用开发中需轻量级网络模块的场景。压缩包共19个文件含11个头文件.h用于API调用声明、2个构建脚本.am、1个README说明文档、1个可执行程序curl.exe开箱即用命令行工具、以及核心的.lib/.dll/.exp二进制库文件整体仅354KB结构精简已按标准lib/include目录组织便于VS工程直接引用。目前已有774人下载学习用户可立即获得开箱即用的跨协议网络传输能力——无需自行搭建CMakeVS编译环境避免OpenSSL依赖冲突与链接错误同时附带功能完整的curl.exe便于调试与接口验证。1. 项目概述与背景最近在做一个需要处理HTTP/HTTPS网络请求的C项目环境是Windows 10 Visual Studio 2019。项目依赖一个稳定可靠的网络库curl自然是首选。虽然官方提供了预编译的二进制包但要么版本太旧要么缺少我需要的特定功能比如支持最新的TLS 1.3协议或者启用了特定的SSL后端如OpenSSL/WinSSL。更关键的是我需要确保库的运行时依赖比如特定的OpenSSL DLL与我的部署环境完全匹配避免在客户机器上出现“找不到VCRUNTIME140_1.dll”或者“应用程序无法正常启动(0xc000007b)”这类令人头疼的问题。自己动手丰衣足食从源码编译出完全符合自己需求的curl库是解决这些潜在兼容性问题的根本方法。这次编译的目标很明确在Windows 10 64位系统上使用Visual Studio 2019生成一个64位的、静态链接的curl库libcurl.lib版本锁定在7.84.0。选择这个版本是因为它在功能稳定性和对新协议的支持上达到了一个不错的平衡。整个过程涉及从获取源码、准备编译环境主要是Perl和NASM、配置构建选项到最终生成库文件的一系列步骤。下面我就把这次踩过坑、趟过雷的完整编译过程记录下来希望能给有同样需求的开发者提供一个清晰的参考。2. 编译前的环境与工具准备编译curl尤其是要支持HTTPS即SSL/TLS并不是下载源码直接用VS打开那么简单。它依赖一些辅助工具来生成Makefile或项目文件。在Windows上我们主要使用curl官方推荐的buildconf脚本配合nmake或者使用CMake。这里我选择更接近官方构建流程的nmake方式因为它能更好地利用curl源码包里的winbuild目录这也是官方文档中针对Windows的构建方法。2.1 核心编译工具链Visual Studio 2019这是我们的主力编译器。确保你已经安装了“使用C的桌面开发”工作负载。安装后最关键的一步是准备好**“开发者命令提示符”**。我们所有的编译命令都需要在这个特殊的环境下运行因为它会自动设置好cl、nmake、lib等编译工具的环境变量如INCLUDE、LIB。你可以在开始菜单搜索“Developer Command Prompt for VS 2019”找到它。后续所有操作都将在这个命令行窗口中进行。2.2 必需辅助工具Perl 和 NASM这是两个容易被忽略但至关重要的工具。Perlcurl的构建系统特别是configure脚本和一些源文件生成依赖Perl。我们需要一个Windows版本的Perl。推荐使用 Strawberry Perl 或 ActiveState Perl 。安装后需要将Perl的可执行文件路径例如C:\Strawberry\perl\bin添加到系统的PATH环境变量中以便在命令行中直接调用perl命令。NASM(Netwide Assembler)如果你计划编译支持SSL的curl并且选择的SSL后端是OpenSSL那么NASM是必须的。因为OpenSSL的某些优化模块是用汇编写的在Windows上构建时需要NASM来编译它们。从 NASM官网 下载并安装同样需要将其安装目录例如C:\NASM添加到系统的PATH环境变量。注意添加PATH后务必重新打开“开发者命令提示符”新的环境变量才会生效。你可以通过在命令提示符中输入perl --version和nasm -v来验证安装是否成功。2.3 源码与依赖库获取curl 源码从curl官方仓库或发布页面下载 curl 7.84.0 的源码包。推荐下载.tar.gz或.zip格式的完整源码包而不是通过Git克隆除非你需要最新开发版。解压到一个没有中文和空格的路径例如D:\Dev\curl-7.84.0。依赖库可选但推荐为了支持HTTPS我们需要SSL库。有两个主流选择OpenSSL功能最全支持最新协议跨平台。你需要下载对应VS2019和64位的OpenSSL开发库。可以自己编译OpenSSL或者从 Shining Light Productions 等网站下载预编译的Windows版本选择 “Win64 OpenSSL v1.1.1*” 或 “Win64 OpenSSL v3.*” 的 “Light” 或 “Full” 安装包。安装后记住其安装目录例如C:\Program Files\OpenSSL-Win64。Windows 原生 Schannel使用Windows系统自带的加密API。好处是无须额外依赖库部署简单。但功能可能不如OpenSSL丰富且行为与Linux/macOS上的curl可能略有差异。本次编译我们将以使用OpenSSL为例因为这是更通用、可控性更强的方案。3. 编译配置详解与参数选择curl在Windows下的构建系统位于源码目录的\winbuild文件夹下。核心文件是Makefile.vc。我们通过向nmake命令传递参数来控制编译过程。3.1 理解构建命令的结构标准的构建命令格式如下nmake /f Makefile.vc modestatic/dll options我们需要在一个已启动VS2019开发环境的命令行中切换到curl源码目录下的\winbuild目录再执行此命令。关键参数解析modestatic 生成静态库 (libcurl.lib)。程序编译时会将该库的所有代码链接进你的exe运行时无需额外的libcurl.dll。生成文件大但部署简单。modedll 生成动态库 (libcurl.dll和对应的导入库libcurl.lib)。程序运行时需要依赖这个dll。生成文件小便于多个程序共享。VC版本号 指定Visual Studio版本。对于VS2019通常使用VC16。构建系统会自动寻找对应版本的编译工具。RTLIBCFGstatic/dynamic 指定C运行时库CRT的链接方式。dynamic表示使用MD/MDd动态链接MSVCRTstatic表示使用MT/MTd静态链接LIBCMT。这需要与你主项目的设置匹配否则会导致链接冲突。通常建议使用dynamic即/MD以减少最终exe体积并便于系统更新。DEBUGyes/no 是否编译调试版本。yes会生成带调试信息的libcurl-debug.lib并启用断言等调试代码。MACHINEx86/x64 指定目标机器架构。我们需要x64。WITH_SSLschannel/openssl 指定SSL后端。schannel使用Windows原生openssl使用OpenSSL。SSL_PATHOpenSSL安装路径 当WITH_SSLopenssl时必须指定OpenSSL的开发文件include和lib目录所在路径。3.2 本次编译的具体配置决策基于我的项目需求我做出了以下选择modestatic 项目希望最终生成一个独立的exe避免处理dll分发问题。WITH_SSLopenssl 需要更好的跨平台一致性以及对最新TLS 1.3协议的完整支持。DEBUGno 生成发布版本库用于最终产品发布。调试时我会单独编译一个调试版。RTLIBCFGdynamic 我的主项目使用的是/MD多线程DLL运行时库这里必须保持一致。GEN_PDByes 即使发布版也生成程序数据库文件(.pdb)便于日后调试或分析崩溃dump。4. 完整编译步骤实操记录假设我的目录结构如下curl源码:D:\Dev\curl-7.84.0OpenSSL: 安装在C:\Program Files\OpenSSL-Win64(包含\include和\lib子目录)输出目录: 我希望库文件生成在D:\Dev\curl-build-output4.1 步骤一启动编译环境并定位目录从开始菜单打开 “x64 Native Tools Command Prompt for VS 2019”。务必选择x64版本以确保编译目标是64位。在命令行中切换至curl的winbuild目录cd /d D:\Dev\curl-7.84.0\winbuild4.2 步骤二执行编译命令执行以下命令进行编译。这是一条完整的命令为了清晰我将其分行显示实际输入时应在一行内完成。nmake /f Makefile.vc modestatic VC16 MACHINEx64 DEBUGno RTLIBCFGdynamic WITH_SSLopenssl SSL_PATHC:\Program Files\OpenSSL-Win64 GEN_PDByes命令逐项解释nmake /f Makefile.vc: 调用nmake指定使用Makefile.vc这个构建文件。modestatic: 构建静态库。VC16: 对应VS2019的编译器工具集。MACHINEx64: 构建64位库。DEBUGno: 构建发布版本。RTLIBCFGdynamic: 使用动态链接的C运行时库 (/MD)。WITH_SSLopenssl: 启用OpenSSL支持。SSL_PATH...: 指向你的OpenSSL安装目录。注意路径有空格必须用双引号包裹。GEN_PDByes: 生成PDB文件。4.3 步骤三等待编译完成按下回车后编译过程开始。你会看到大量的cl.exe编译和lib.exe链接命令输出。整个过程可能需要几分钟取决于你的机器性能。如果一切顺利最终会看到类似Finished creating library ...和nmake成功退出的提示。4.4 步骤四定位编译产出编译成功后产出物不会在winbuild目录而是在源码目录下的\builds文件夹里。系统会按照你的配置参数自动生成一个复杂的子目录路径来存放输出以避免不同配置的编译结果相互覆盖。对于上述命令生成的库文件通常位于D:\Dev\curl-7.84.0\builds\libcurl-vc16-x64-release-static-ipv6-sspi-ssl这个长名字的目录结构是libcurl-{VC版本}-{机器架构}-{调试/发布}-{链接类型}-{特性}。进入该目录你应该能找到以下关键文件libcurl.lib 我们需要的静态库文件。libcurl.pdb 对应的调试符号文件因为设置了GEN_PDByes。bin子目录 里面会有编译好的curl.exe命令行工具可以用来测试。include子目录 里面是curl的头文件在开发时需要引用。为了方便使用我通常会将这个目录下的include文件夹和libcurl.lib、libcurl.pdb文件复制到一个统一的、干净的目录中例如D:\Dev\curl-build-output。5. 在Visual Studio 2019项目中集成现在我们将编译好的库集成到自己的VS2019 C项目中。5.1 项目配置以x64 Release为例添加包含目录 在项目属性 - “C/C” - “常规” - “附加包含目录”中添加curl头文件所在路径例如D:\Dev\curl-build-output\include。添加库目录 在项目属性 - “链接器” - “常规” - “附加库目录”中添加libcurl.lib所在路径例如D:\Dev\curl-build-output。添加依赖库 在项目属性 - “链接器” - “输入” - “附加依赖项”中添加libcurl.lib。此外由于我们使用了OpenSSL还必须添加OpenSSL的库。通常需要添加libssl.lib和libcrypto.lib。你需要在“附加库目录”中也加入OpenSSL的lib路径例如C:\Program Files\OpenSSL-Win64\lib或者在“附加依赖项”中填写完整路径。“附加依赖项”内容示例libcurl.lib; libssl.lib; libcrypto.lib; Ws2_32.lib; Crypt32.lib;Ws2_32.lib是Windows sockets库curl网络基础依赖。Crypt32.lib是Windows加密API库即使使用OpenSSLcurl也可能需要它。确保运行时库一致 在项目属性 - “C/C” - “代码生成” - “运行时库”中确认设置为“多线程DLL (/MD)”这与我们编译curl时使用的RTLIBCFGdynamic对应。5.2 一个简单的测试代码创建一个简单的源文件来测试库是否正常工作。#include iostream #include curl/curl.h // 确保包含目录已设置 // 一个简单的回调函数用于处理接收到的数据 size_t WriteCallback(void* contents, size_t size, size_t nmemb, std::string* userp) { size_t totalSize size * nmemb; userp-append((char*)contents, totalSize); return totalSize; } int main() { CURL* curl; CURLcode res; std::string readBuffer; curl_global_init(CURL_GLOBAL_DEFAULT); curl curl_easy_init(); if (curl) { // 设置一个测试URL这里以访问一个公共API为例 curl_easy_setopt(curl, CURLOPT_URL, https://httpbin.org/get); // 忽略SSL证书验证仅用于测试生产环境应正确验证 curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); // 设置写回调函数 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback); curl_easy_setopt(curl, CURLOPT_WRITEDATA, readBuffer); // 执行请求 res curl_easy_perform(curl); // 检查错误 if (res ! CURLE_OK) { std::cerr curl_easy_perform() failed: curl_easy_strerror(res) std::endl; } else { std::cout Received data:\n readBuffer std::endl; } // 清理 curl_easy_cleanup(curl); } curl_global_cleanup(); return 0; }编译并运行这个测试程序。如果成功输出https://httpbin.org/get返回的JSON数据恭喜你curl库已经成功集成并可以正常工作。6. 编译过程中的常见问题与解决方案自己编译的过程很少一帆风顺下面是我遇到的一些典型问题及解决方法。6.1 错误NMAKE : fatal error U1073: dont know how to make ...\packages\vstudio\...\curl_config.h问题分析 这个错误通常是因为构建系统找不到或无法自动生成curl_config.h配置文件。在winbuild模式下这个文件应该由构建系统根据你的参数自动处理。解决方案确保你在curl-7.84.0\winbuild目录下执行nmake命令而不是在根目录或其他地方。检查命令参数是否正确特别是VC的版本号。VS2019是16VS2017是15VS2015是14。尝试先执行一个最简单的清理和构建命令排除其他干扰nmake /f Makefile.vc clean nmake /f Makefile.vc modestatic VC16 MACHINEx646.2 错误Cannot open include file: openssl/ssl.h或cannot open file libssl.lib问题分析 这是最常见的错误表明编译系统找不到OpenSSL的头文件或库文件。解决方案检查SSL_PATH路径 确认SSL_PATH指向的目录是正确的OpenSSL安装目录并且该目录下包含include和lib子文件夹。路径中的空格必须用双引号括起来。检查OpenSSL版本 确保你下载的OpenSSL是64位Win64版本且其库文件格式与VS2019兼容。老版本VS如2015编译的库可能不兼容VS2019。从可信来源下载为VS2019预编译的版本是最稳妥的。手动指定库文件 如果问题持续可以尝试在winbuild目录下创建一个Makefile.vc的本地副本进行修改但更简单的方法是检查OpenSSL的lib目录下是否存在libssl.lib和libcrypto.lib。有时它们可能以libssl-3-x64.lib的形式存在你需要根据实际情况调整。6.3 错误LNK2001: 无法解析的外部符号 __imp_xxxx链接阶段问题分析 这发生在你自己项目链接libcurl.lib的时候。根本原因是你的主项目与curl库使用了不同的运行时库Runtime Library设置。解决方案绝对确保一致性 检查你的项目属性“C/C” - “代码生成” - “运行时库”。如果你编译curl时使用了RTLIBCFGdynamic对应/MD你的项目就必须设置为“多线程DLL (/MD)”。如果你编译curl时使用了RTLIBCFGstatic对应/MT你的项目就必须设置为“多线程 (/MT)”。Debug版本同理/MDd对应DEBUGyes RTLIBCFGdynamic/MTd对应DEBUGyes RTLIBCFGstatic。检查所有依赖项 不仅仅是curl你项目链接的所有第三方库如OpenSSL的libssl.lib都应该使用相同类型的运行时库。混合使用/MT和/MD的库必然导致链接错误。6.4 运行时错误应用程序无法正常启动(0xc000007b)问题分析 这个错误通常在运行编译好的程序时出现。可能的原因有程序是64位的但依赖了某个32位的DLL或反之。缺少必要的运行时DLL如OpenSSL的libcrypto-1_1-x64.dll或libssl-1_1-x64.dll。解决方案确认架构一致性 确保你的主项目、curl库、OpenSSL库都是x64。部署依赖DLL 如果你编译的是DLL版本的curl (modedll)需要将libcurl.dll和OpenSSL的DLL如libcrypto-1_1-x64.dll,libssl-1_1-x64.dll放置在与你的exe相同的目录或放在系统PATH包含的目录下。使用静态库的优势 这正是我选择modestatic的主要原因之一。静态链接会将curl和C运行时库的代码都打包进exe极大减少了运行时对系统DLL的依赖部署更简单。但请注意OpenSSL的DLL可能仍然需要除非你将OpenSSL也静态链接进来那又是另一个复杂的编译过程了。6.5 性能与功能取舍Schannel vs OpenSSL问题 为什么选择OpenSSL而不是更简单的Windows自带的Schannel分析与选择Schannel优势 无需额外依赖部署极其方便。与Windows证书存储集成好。OpenSSL优势协议特性 通常对最新TLS协议如TLS 1.3的支持更及时、更完整。跨平台一致性 如果你的代码需要在Linux/macOS上运行使用OpenSSL可以保证SSL相关行为如证书验证、密码套件在各个平台上高度一致减少平台差异带来的bug。功能控制 OpenSSL提供了更细粒度的配置选项。算法支持 可能支持一些Schannel没有的特定加密算法。如果你的应用仅部署在Windows环境且对最新TLS特性没有强烈需求使用WITH_SSLschannel可以省去管理OpenSSL依赖的麻烦是更简洁的选择。我的项目有跨平台考虑因此选择了OpenSSL。7. 进阶编译调试版本与多配置管理在实际开发中我们通常需要Debug和Release两个版本的库。7.1 编译Debug版本库只需将DEBUG参数改为yes并为输出指定一个不同的目录构建系统会自动处理但为了管理方便我们可以在命令中通过CFG参数指定一个配置名。nmake /f Makefile.vc modestatic VC16 MACHINEx64 DEBUGyes RTLIBCFGdynamic WITH_SSLopenssl SSL_PATHC:\Program Files\OpenSSL-Win64 GEN_PDByes CFGdebug-static-ssl这会在builds目录下生成一个类似libcurl-vc16-x64-debug-static-ipv6-sspi-ssl的文件夹里面包含libcurl-debug.lib。7.2 在VS项目中管理多配置在VS项目属性管理器里可以为“Debug | x64”和“Release | x64”分别设置不同的包含目录和库目录。创建一个统一的第三方库目录例如D:\Dev\ThirdPartyLibs\curl。在里面创建子文件夹include(存放头文件Debug和Release共用)lib\x64\debug(存放libcurl-debug.lib)lib\x64\release(存放libcurl.lib)在VS项目属性中为“Debug | x64”配置的“附加库目录”添加D:\Dev\ThirdPartyLibs\curl\lib\x64\debug “附加依赖项”添加libcurl-debug.lib。为“Release | x64”配置的“附加库目录”添加D:\Dev\ThirdPartyLibs\curl\lib\x64\release “附加依赖项”添加libcurl.lib。这样当你切换解决方案配置时VS会自动链接对应版本的库。7.3 关于字符集Unicode vs MBCScurl库本身对字符集是透明的它使用char*处理URL和头部。在Windows项目中如果你使用了Unicode字符集项目属性 - “常规” - “字符集”设置为“使用Unicode字符集”那么所有Windows API调用会使用宽字符。这并不影响你调用curl的函数因为curl的接口是窄字符的。你只需要注意在将Windows宽字符串wchar_t*传递给curl前将其转换为UTF-8编码的窄字符串这是现代网络应用的推荐做法。curl内部会正确处理UTF-8编码的URL和数据进行传输。本文还有配套的精品资源点击获取
返回列表