公司动态

Windows 10 + VS2019 下编译64位libcurl库(支持HTTPS)完整指南

📅 2026/8/30 18:45:41
Windows 10 + VS2019 下编译64位libcurl库(支持HTTPS)完整指南
简介本资源是为Windows 10平台开发者准备的、开箱即用的CURL 64位静态/动态链接库集合基于最新稳定版7.84.0源码使用CMake 3.22与Visual Studio 2019完整编译生成专为C/C网络编程初学者及嵌入式HTTP客户端开发人员设计可快速集成HTTPS请求能力免去繁琐的跨平台编译配置过程。压缩包共19个文件包含11个头文件.h、2个构建脚本.am、1个README说明文档、1个可执行程序curl.exe、1个动态链接库libcurl.dll、1个导入库libcurl_imp.lib、1个导出符号文件libcurl_imp.exp以及配套的.gitignore总大小仅354KB结构清晰分为include与lib两级目录便于VS工程直接引用。已有774人下载学习用户可直接调用libcurl接口实现GET/POST/SSL认证等HTTP操作亦可立即运行内置curl.exe进行命令行调试显著降低Win10环境下网络工具链搭建门槛。1. 项目概述与背景最近在做一个需要处理HTTP请求的C项目环境是Windows 10开发工具用的是Visual Studio 2019。项目里需要用到libcurl库来处理网络通信比如上传下载文件、调用RESTful API这些。一开始图省事直接去官网下载了预编译的二进制包结果发现要么是32位的要么就是用MinGW或者其它编译器链编译的跟VS2019的MSVC编译器环境不太兼容链接的时候总报各种运行时库冲突或者符号找不到的错误调试起来非常头疼。折腾了几次之后我决定还是自己动手用VS2019从源码编译一个64位的libcurl库版本就选当时最新的7.84.0。自己编译虽然前期麻烦点但好处太多了一是能确保库的编译环境运行时库版本、编译器特性和我的项目完全一致彻底杜绝兼容性问题二是可以按需定制功能比如我需要HTTPS支持就编译进OpenSSL不需要的功能可以关掉让库更精简三是能生成调试版本Debug的库方便在开发阶段单步跟踪到libcurl内部排查一些诡异的网络问题。这个过程涉及从获取源码、配置编译选项、解决依赖库到最终生成lib和dll文件。网上虽然有一些教程但要么步骤不全要么针对的是老版本有些关键的坑点没提到。我把整个流程和踩过的坑详细记录下来如果你也在Win10VS2019环境下需要64位的curl库这份记录应该能帮你省下不少时间。2. 编译前的环境与工具准备工欲善其事必先利其器。在开始编译之前我们需要把“厨房”收拾好把必要的“食材”和“工具”备齐。这一步看似简单但准备不充分往往是后续编译失败的主要原因。2.1 核心工具链确认Visual Studio 2019首先确保你的Visual Studio 2019安装正确且包含了C开发组件。打开Visual Studio Installer查看已安装的内容。必须确保安装了“使用C的桌面开发”工作负载。这个工作负载包含了我们编译C/C项目所需的MSVC编译器cl.exe、链接器link.exe、库管理器lib.exe以及最重要的“x64 Native Tools Command Prompt for VS 2019”这个命令行工具。为什么强调这个命令行工具因为我们需要在命令行下使用nmake微软的Make工具来编译curl。这个“x64 Native Tools Command Prompt”不是一个普通的CMD或PowerShell它会在启动时自动设置好所有编译64位程序所需的环境变量比如PATH、INCLUDE、LIB等指向VS2019自带的工具和库。如果你在普通命令行下直接操作很可能会遇到“nmake不是内部或外部命令”或者找不到cl.exe的错误。验证方法很简单在Windows开始菜单里搜索“x64 Native”找到并打开它。在弹出的命令行窗口中依次输入cl和nmake如果能看到它们的版本信息而不是错误提示说明环境就绪了。2.2 获取curl源码与依赖项接下来是准备“食材”curl源码和它可能依赖的“调味料”。1. 下载curl源码前往curl的官方GitHub发布页面https://github.com/curl/curl/releases找到版本7.84.0的源代码包。通常有两个选择.tar.gz适用于Linux/Mac和.zip适用于Windows。我们直接下载curl-7.84.0.zip。下载后解压到一个没有中文和空格的路径下比如D:\Dev\curl-7.84.0。记住这个路径后面我们称之为CURL_SRC。2. 识别并准备依赖库以OpenSSL为例curl本身可以不依赖任何外部库进行编译即编译成仅支持HTTP的版本但如今网络环境复杂HTTPSSSL/TLS支持几乎是必需品。要让curl支持HTTPS我们需要一个SSL库在Windows上最常见的选择是OpenSSL。这里有一个关键决策点是自己编译OpenSSL还是使用预编译好的二进制文件对于新手或者想快速上手的开发者我强烈建议使用预编译的OpenSSL库。自己编译OpenSSL过程更复杂且容易出错。我们可以从Shining Light Productions一个知名的Windows平台OpenSSL预编译包维护站点下载对应VS2019和64位的版本例如Win64 OpenSSL v1.1.1系列。下载后将其安装或解压到一个简单的路径例如D:\Dev\OpenSSL-Win64。这个目录下通常会有include、lib和bin等子文件夹分别存放头文件、库文件和运行时DLL。3. 其他可选依赖根据你的需求可能还需要其他库比如zlib用于支持HTTP压缩gzip, deflate。可以从zlib官网下载源码自己编译或者使用预编译版本。libssh2用于支持SCP/SFTP。c-ares用于支持异步DNS解析提升性能。对于本次编译我们以支持HTTPSOpenSSL为主要目标其他依赖暂不添加以简化流程。你可以根据项目需要后续再添加。2.3 规划构建目录结构清晰的目录结构能让后续的配置和文件管理更轻松。我建议建立如下结构D:\Dev\curl-build\ ├── source\ # 放置 curl-7.84.0 源码 ├── openssl\ # 放置 OpenSSL 的头文件和库文件 ├── build-vs2019-x64\ # 编译输出目录 └── output\ # 最终整理好的头文件、库文件、DLL的存放目录将之前下载的curl-7.84.0解压到source目录下。将OpenSSL的include和lib文件夹复制到openssl目录下或者直接在配置时指向OpenSSL的安装目录。build-vs2019-x64是编译过程中的工作目录output是我们最终提取成果的地方。3. 编译配置与生成工程文件curl在Windows上通常不直接提供VS的解决方案文件.sln而是通过其自带的构建系统生成。对于MSVC它主要支持两种方式一是使用CMake生成VS工程二是使用其自带的winbuild目录下的Makefile.vc配合nmake进行编译。后者是curl官方为WindowsMSVC量身定制的传统方式更直接也更容易控制。我们选择第二种方式。3.1 进入编译环境与源码目录打开“x64 Native Tools Command Prompt for VS 2019”。使用cd命令切换到curl源码的winbuild目录。这个目录包含了Windows编译的专用脚本。cd /d D:\Dev\curl-build\source\curl-7.84.0\winbuild3.2 理解并配置nmake参数在winbuild目录下有一个BUILD.WINDOWS.txt文件是编译指南。但更直接的是查看Makefile.vc和使用说明。我们通过给nmake命令传递参数来控制编译过程。编译命令的基本格式是nmake /f Makefile.vc modestatic/dll options关键参数解析modestatic或modedll这是最重要的选项决定生成静态库.lib还是动态库.dll .lib。静态库static将curl的所有代码编译进一个.lib文件。你的程序在链接时会把库的代码直接合并到最终的可执行文件.exe中。优点是部署简单一个.exe文件就够了。缺点是exe文件体积会变大且如果多个模块都用了静态库会在最终程序里存在多份代码副本。动态库dll生成libcurl.dll动态链接库和libcurl.lib导入库。你的程序在运行时需要依赖这个dll文件。优点是程序体积小多个程序可以共享同一个dll节省内存升级curl库时只需替换dll需注意接口兼容性。缺点是部署时需要将dll和exe一起发布。如何选择如果开发供他人使用的SDK或者希望程序独立不依赖外部文件选static。如果是大型应用注重模块化和更新方便选dll。我这里以生成动态库modedll为例因为更通用。VC版本号指定Visual Studio版本。对于VS2019我们使用VC16。VS版本号对应关系VS201514, VS201715, VS201916, VS202217。RTLIBCFGstatic/dynamic指定C运行时库CRT的链接方式。dynamic链接到动态CRT如MD、MDd。你的程序需要微软的运行时库如msvcrt.dll,vcruntime140.dll才能运行。这是推荐的方式符合现代Windows应用分发惯例这些DLL通常系统已有或通过安装包提供。static链接到静态CRT如MT、MTd。CRT代码会被打包进你的库或程序生成的文件更大但理论上部署更独立。强烈建议使用RTLIBCFGdynamic以避免潜在的运行时库冲突特别是当你项目中的其他第三方库也使用动态CRT时。DEBUGyes/no是否生成调试版本。DEBUGyes会生成带调试信息的库通常更大运行更慢并启用_DEBUG宏定义方便调试。DEBUGno则生成发布版本经过优化。MACHINEx86/x64指定目标机器架构。我们需要64位库所以是MACHINEx64。WITH_SSLstatic/dll和SSL_PATH路径这是启用SSL支持的关键。WITH_SSLdll表示我们使用动态链接的OpenSSL库libssl-1_1-x64.dll,libcrypto-1_1-x64.dll。SSL_PATH必须指向你的OpenSSL安装目录包含include和lib子目录的那个例如SSL_PATHD:\Dev\OpenSSL-Win64。GEN_PDByes/no是否生成程序数据库文件.pdb。这对于调试至关重要特别是动态库。设置为GEN_PDByes这样在调试时就能看到curl库内部的函数名和调用栈。3.3 执行配置与编译命令综合以上我使用的完整编译命令如下在winbuild目录下执行nmake /f Makefile.vc modedll VC16 RTLIBCFGdynamic DEBUGno MACHINEx64 WITH_SSLdll SSL_PATHD:\Dev\OpenSSL-Win64 GEN_PDByes如果你想同时编译一个调试版本Debug可以再开一个命令行或者稍后执行nmake /f Makefile.vc modedll VC16 RTLIBCFGdynamic DEBUGyes MACHINEx64 WITH_SSLdll SSL_PATHD:\Dev\OpenSSL-Win64 GEN_PDByes注意nmake命令的参数之间用空格分隔路径中如果有空格需要用双引号括起来例如SSL_PATHC:\Program Files\OpenSSL-Win64。另外编译过程会从网络下载一些辅助工具如perl用于生成一些源文件请确保网络通畅。如果遇到下载失败可以尝试手动下载并放置到指定位置具体可查看错误信息或Makefile.vc中的相关规则。敲下回车后nmake就会开始工作。它会先根据参数配置构建环境然后调用编译器cl.exe和链接器link.exe进行编译。整个过程会在控制台输出大量信息如果没有报错error最终会显示编译成功并在源码目录下的builds文件夹里生成结果。4. 编译输出结果的处理与使用编译成功后我们需要的文件在哪里如何正确地集成到自己的VS2019项目中这一步处理不好前面所有工作都白费。4.1 定位与整理编译产物curl的构建系统会将输出放在一个比较深的目录里。对于我们的参数modedll,MACHINEx64,DEBUGno,VC16生成的目录路径大致为CURL_SRC\builds\libcurl-vc16-x64-release-dll-ssl-dll进入这个目录你会看到几个重要的子文件夹bin 这里存放着运行时需要的文件。libcurl.dll 这是我们编译出的curl动态库本体。libcurl.pdb 对应的调试符号文件如果GEN_PDByes。可能还有libssl-1_1-x64.dll和libcrypto-1_1-x64.dll如果你编译时WITH_SSLdll且OpenSSL也是动态库它们会被自动复制过来。这一点非常重要你的程序运行时必须能找到这三个dll如果用了SSL。lib 这里存放着开发时需要的库文件。libcurl.lib 这是导入库Import Library用于在链接阶段告诉链接器你的程序将要调用libcurl.dll中的哪些函数。它不是静态库体积很小。include 这里存放着curl的头文件。但注意这个include目录可能不是完整的。更可靠的做法是直接使用源码根目录下的include\curl文件夹。为了方便项目管理我习惯将必要的文件整理到一个独立的output目录结构如下D:\Dev\curl-build\output\ ├── include\ │ └── curl\ # 从 CURL_SRC\include\curl 复制过来 │ ├── curl.h │ ├── easy.h │ └── ... (其他所有.h文件) ├── lib\ │ ├── release\ │ │ ├── libcurl.lib # 发布版的导入库 │ │ └── libcurl.pdb # 发布版的符号文件可选 │ └── debug\ │ ├── libcurl.lib # 调试版的导入库 │ └── libcurl.pdb # 调试版的符号文件 └── bin\ ├── release\ │ ├── libcurl.dll # 发布版的动态库 │ ├── libssl-1_1-x64.dll │ └── libcrypto-1_1-x64.dll └── debug\ ├── libcurl.dll # 调试版的动态库 ├── libssl-1_1-x64.dll └── libcrypto-1_1-x64.dll将对应版本Release/Debug的文件分别放入release和debug子目录在VS项目中配置时就可以方便地根据配置切换。4.2 在Visual Studio 2019项目中配置现在在你的C项目中引入我们编译好的curl库。包含头文件目录 打开项目属性 - “C/C” - “常规” - “附加包含目录”。添加你整理好的include目录路径例如D:\Dev\curl-build\output\include。配置库目录和附加依赖项打开“链接器” - “常规” - “附加库目录”。添加对应配置Debug/Release的lib目录例如对于Release配置添加D:\Dev\curl-build\output\lib\release。打开“链接器” - “输入” - “附加依赖项”。在这里添加libcurl.lib。注意只需要加.lib文件不需要加.dll。链接器会根据.lib文件知道在运行时需要加载libcurl.dll。确保DLL在运行时可用 这是新手最容易出错的地方。链接编译阶段成功了但程序一运行就提示“找不到libcurl.dll”。解决方法有三种方法一推荐用于开发调试将bin\release或bin\debug目录下的所有.dll文件复制到你的项目生成的可执行文件.exe所在的目录。VS默认生成目录是$(SolutionDir)$(Configuration)\例如x64\Release\。方法二将DLL所在目录如D:\Dev\curl-build\output\bin\release添加到系统的PATH环境变量中。但这样会影响全局不推荐。方法三在项目属性 - “调试” - “环境”中添加一行如PATHD:\Dev\curl-build\output\bin\release;%PATH%。这样只在VS启动调试时生效。配置预处理器定义可选但重要 为了让curl正确使用我们编译的SSL库通常需要在项目预处理器定义中添加CURL_STATICLIB。但是请注意这个宏的名字有点误导。当我们使用动态库DLL版本的curl时不应该定义CURL_STATICLIB。这个宏仅在链接静态库.lib版本的curl时才需要定义用于防止curl的头文件声明函数时使用错误的调用约定__declspec(dllimport)。对于动态库保持默认即可头文件会自动使用__declspec(dllimport)。定义错了会导致链接错误。4.3 编写测试代码验证配置完成后写一段简单的代码测试是否成功。#include iostream #include curl/curl.h // 确保能找到这个头文件 int main() { CURL* curl curl_easy_init(); if (curl) { std::cout libcurl version: curl_version() std::endl; curl_easy_cleanup(curl); return 0; } else { std::cerr Failed to initialize libcurl! std::endl; return -1; } }编译并运行。如果成功输出libcurl的版本信息其中应包含SSL字样证明OpenSSL支持已启用并且程序没有崩溃那么恭喜你curl库已经成功集成到你的项目中了。5. 编译过程中的常见问题与解决方案自己编译的过程很少一帆风顺下面是我在编译curl 7.84.0 with VS2019时遇到的一些典型问题及解决方法。5.1 依赖库路径错误或版本不匹配问题描述执行nmake命令时报错fatal error LNK1181: cannot open input file libssl.lib或cannot open include file openssl/ssl.h。原因分析这是最常见的问题。nmake找不到OpenSSL的头文件或库文件。原因可能是SSL_PATH参数设置错误指向的目录下没有include和lib子文件夹。使用的OpenSSL库位数不对用了32位的库编译64位的curl。OpenSSL库的版本不兼容比如curl可能需要1.1.x系列而你提供了3.0.x的库。解决方案仔细检查SSL_PATH指向的路径。确保路径中不包含中文或特殊字符。最好使用绝对路径。确认你下载的OpenSSL是“Win64”版本并且是VS2019对应的版本通常文件名或说明里会写。打开OpenSSL的lib文件夹查看库文件名。对于动态库通常叫libssl-1_1-x64.lib和libcrypto-1_1-x64.lib这是导入库。确保这些文件存在。有时预编译包提供的是libssl.lib和libcrypto.lib如果文件名不对可以尝试复制一份并重命名或者修改Makefile.vc中的库名不推荐新手。5.2 编译工具链或环境问题问题描述在“x64 Native Tools Command Prompt”中执行nmake提示‘nmake‘ 不是内部或外部命令也不是可运行的程序。原因分析虽然打开了正确的命令行工具但可能因为VS安装不完整或环境变量被意外修改导致nmake.exe不在当前路径下。解决方案在命令行中直接输入where nmake。如果找不到说明环境确实有问题。尝试在开始菜单中搜索“Developer Command Prompt for VS 2019”并打开这个也会设置环境变量。最根本的方法是修复或修改VS2019安装确保“使用C的桌面开发”工作负载下的“MSVC v142 - VS 2019 C x64/x86 build tools”组件被选中安装。问题描述编译过程中出现大量语法错误例如error C2065: ‘xxx‘: undeclared identifier但这些标识符明显是标准库或Windows SDK里的。原因分析可能是Windows SDK版本不匹配或者包含目录include paths顺序混乱。curl的构建脚本可能没有正确找到最新Windows SDK的头文件。解决方案确保VS2019安装了较新版本的Windows 10 SDK。可以通过Visual Studio Installer进行添加。这是一个比较棘手的问题。可以尝试在nmake命令中显式指定SDK版本但Makefile.vc可能不支持。一个变通方法是手动编辑winbuild目录下的Makefile.vc文件找到设置INCLUDE环境变量的地方确保Windows SDK的路径如C:\Program Files (x86)\Windows Kits\10\Include\10.0.xxxxx.0\um被正确包含。操作前建议备份原文件。5.3 链接阶段错误问题描述编译.c文件生成.obj成功但在链接link阶段失败报错如LNK2005: _malloc already defined in LIBCMT.lib或LNK2038: mismatch detected for ‘RuntimeLibrary‘。原因分析这是典型的运行时库CRT链接冲突。可能的原因有你的项目属性中设置的运行时库“C/C” - “代码生成” - “运行时库”与编译curl时使用的RTLIBCFG参数不一致。例如你的项目是/MDdDebug动态但curl库是用RTLIBCFGstatic静态CRT编译的。你项目中引用的其他第三方库使用了不同设置的CRT。解决方案统一运行时库设置这是最根本的解决方法。确保你的项目、以及所有你引用的第三方库包括curl都使用相同类型的CRT全是动态/MD//MDd或者全是静态/MT//MTd。对于curl通过RTLIBCFGdynamic对应/MD或/MDd或RTLIBCFGstatic对应/MT或/MTd来控制。强烈建议所有组件都使用动态CRT/MD或/MDd这是Windows平台现代软件开发的通用做法。检查你的项目属性确保Debug配置对应/MDdRelease配置对应/MD。然后重新用对应的DEBUGyes/no和RTLIBCFGdynamic参数编译curl。5.4 运行时问题DLL相关问题描述程序编译链接成功但运行时弹出错误对话框或控制台输出“无法启动此程序因为计算机中丢失 libcurl.dll”或“应用程序无法正常启动(0xc000007b)”。原因分析DLL未找到这是最直接的原因系统在可执行文件目录、PATH环境变量指定的目录中都找不到libcurl.dll以及它依赖的libssl-1_1-x64.dll等。DLL位数不匹配错误0xc000007b经常意味着尝试加载了一个不兼容的DLL例如32位程序加载了64位DLL或者反之。你的程序是x64的但libcurl.dll可能是x86的。解决方案确保DLL就位将编译输出的bin\release下的所有DLL文件复制到你的.exe文件所在的目录。这是最可靠的部署方式。检查位数使用Dependency WalkerDepends.exe或微软的dumpbin /headers libcurl.dll命令检查DLL的机器类型。对于64位DLL应该显示x64或8664 machine (x64)。同时检查你的项目属性中“配置管理器”里活动解决方案平台是否为x64。检查依赖链使用上述工具打开libcurl.dll查看它自身依赖哪些DLL。确保这些DLL如libssl-1_1-x64.dll,libcrypto-1_1-x64.dll,zlib1.dll,KERNEL32.dll,MSVCRT.dll等也都能被找到并且位数匹配。特别是MSVCRT相关的DLL如vcruntime140.dll如果编译时选择了动态CRT这些DLL也需要存在。它们通常由“Visual C Redistributable for Visual Studio 2019”提供可以在目标机器上安装或者随你的应用程序一起分发。6. 高级定制与优化建议当你成功完成了基础编译后可能还想根据项目需求进行一些定制化调整或者优化编译结果。6.1 功能定制启用或禁用特定协议与特性curl支持大量的协议和特性但并非所有项目都需要。在编译时禁用不需要的功能可以减小库的体积降低潜在的安全面。这需要通过修改Makefile.vc或使用更底层的配置方式来实现。一种常见的方法是直接编辑winbuild目录下的Makefile.vc文件但这对新手不友好且容易出错。更推荐的方式是使用curl源码根目录下的configure脚本需要配合类似Cygwin或MSYS2的环境生成Makefile但这在纯WindowsMSVC环境下比较复杂。对于Makefile.vc我们可以通过添加USE_开头的参数来粗略控制。例如在nmake命令后添加USE_IPV6no 禁用IPv6支持。USE_IDNno 禁用国际化域名支持。USE_LIBSSH2no 禁用SSH支持如果没指定WITH_SSH2默认就是no。但是Makefile.vc提供的开关有限。更细粒度的控制需要研究Makefile.vc内部或者使用CMake。如果你只需要HTTP/HTTPS那么默认编译加上SSL就已经足够了其他协议如FTP、SMTP等默认是开启的但对库大小影响不大。6.2 生成静态库Static Library的注意事项如果你选择编译静态库modestatic配置和使用上会有一些不同。编译命令将mode参数改为static即可。nmake /f Makefile.vc modestatic VC16 ... WITH_SSLstatic SSL_PATH...注意如果依赖库如OpenSSL也使用静态库那么WITH_SSL也应设为static。项目配置必须在项目的预处理器定义中添加CURL_STATICLIB。这个宏会改变curl头文件中函数的声明方式使其适合静态链接。在“附加依赖项”中除了要添加libcurl.lib还必须添加curl静态库所依赖的所有其他库。这包括OpenSSL的静态库libssl.lib,libcrypto.libWindows系统库ws2_32.libWinsock,crypt32.libCryptoAPI,wldap32.libLDAP等。 具体需要哪些库一个简单的方法是查看编译curl静态库时链接器link.exe的命令行输出里面会列出所有链接的库。或者你可以先尝试链接根据报错信息LNK2001: unresolved external symbol逐步添加缺失的库。优缺点再权衡静态库将所有代码打包进你的exe部署简单但会导致exe文件显著增大。更重要的是如果同一个进程中有多个模块如主exe和一个dll插件都静态链接了curl它们会各自拥有一份curl的全局状态如内存管理、SSL上下文等这可能会引发难以调试的问题。因此在大型或模块化项目中动态库DLL通常是更安全的选择。6.3 为生产环境优化编译选项我们之前使用的命令是基础编译。为了获得更优的性能和大小可以考虑以下调整启用编译器优化在Release版DEBUGno编译时MSVC默认会使用/O2最大化速度优化。这通常已经足够。你可以在nmake命令后添加CFLAGS/O2 /GL和LDFLAGS/LTCG来尝试全程序优化Link Time Code Generation这可能会进一步优化性能但会大大增加编译时间。禁用调试信息对于最终发布的版本如果不需要调试可以在编译命令中移除GEN_PDByes或者发布时不携带.pdb文件。压缩二进制大小添加链接器选项/OPT:REF消除未使用的函数/数据和/OPT:ICF折叠相同的COMDAT节是默认开启的。你还可以尝试在CFLAGS中添加/Os优选大小而不是/O2优选速度但这可能会影响性能。这些优化选项的添加需要谨慎并且最好通过修改Makefile.vc中的CFLAGS和LDFLAGS变量来实现。对于绝大多数应用使用默认的Release编译选项已经能产生非常高效的代码了。优化的首要原则是“满足需求即可”过度优化可能带来兼容性风险且收益有限。本文还有配套的精品资源点击获取