目录

1、引言

2、直接编译libcurl工程,提示找不到ssh.h

3、下载并编译libssh2开源代码,部署到libcurl目录中

4、获取openssl开源库的头文件和库文件,部署到libcurl目录中

5、将编译好的libcurl拿到测试项目中测试

6、使用CMake工具手动生成VS工程文件,可以轻易地编译出libcurl库

7、总结


libcurl是一个免费开源的网络传输库(the multiprotocol file transfer library),支持ftp、ftps、http、https、telnet、ldap、pop3、smtp、rtmp、rtsp、smb等多种协议。libcurl中封装了支持这些协议的网络通信模块,支持跨平台,支持Windows,Unix,Linux等多个操作系统。libcurl提供了一套统一样式的API接口,我们不用关注各种协议下网络通信的实现细节,只需要调用这些API就能轻松地实现基于这些协议的数据通信。本文我们来详细讲述一下如何编译开源的libcurl库。

1、引言

之前开发的一个工具软件中有个发送告警邮件的功能,最开始试图通过socket套接字去实现邮件的发送,先是和邮件服务器建立连接,然后进行SMTP邮件的协商,协商完成后将邮件发送出去。结果联调测试时遇到了一堆问题,各种网络异常没有得到很好的处理,导致发送邮件功能根本没法使用。

后来想到了libcurl开源库,该库中封装了smtp邮件协议的所有功能,从连接到协议协商,再到邮件数据的发送,提供一套完整、可靠、稳定的邮件发送机制。于是想去下载libcurl的开源代码,手动将库编译出来,然后再拿到工具软件中使用,同时也正好熟悉一下libcurl开源库的编译过程。

关于发送告警邮件的项目,可以查看之前写的文章:(下列文章中提供免费C++源码项目下载

IPC摄像头在线状态ping检测与告警邮件发送项目总结(提供源码下载)https://blog.csdn.net/chenlycly/article/details/120690137

2、直接编译libcurl工程,提示找不到ssh.h

到libcurl的官网上下载libcurl源码。我下载的是2022年5月11日发布的curl 7.83.1版本。解压后,打开curl-7.83.1\projects\Windows目录,该目录中保存了支持Widnows平台上的Visual Studio编译的工程文件,提供了对多个Visual Studio版本的支持:

此处我是用Visual Studio 2010编译的,所以选择VC10目录。打开VC10目录,双击curl-all.sln解决方案文件启动VS2010打开解决方案,该解决方案中包含了curl和libcurl两个工程,libcurl是动态库工程,我们编译该工程就可以了。

在libcurl源代码根路径中提供了CMakeLists.txt文件,如果开源库中不提供支持Visual Studio编译的工程文件,我们可以对CMakeLists.txt文件使用CMAKE工具,生成指定版本的Visual Studio工程文件。注意在使用CMake工具时,开源代码的所在路径必须是全英文的,不能包含中文,否则CMake工具会将路径中的中文字符识别位乱码,导致生成Visual Studio工程文件失败。

启动对libcurl工程的编译后,就报错了,如下所示:

1>------ 已启动生成: 项目: libcurl, 配置: DLL Release - DLL OpenSSL Win32 ------
1>生成启动时间为 2022/5/17 16:32:39。
1>InitializeBuildStatus:
1>  正在创建“..\..\..\..\build\Win32\VC10\DLL Release - DLL OpenSSL\lib\libcurl.unsuccessfulbuild”,因为已指定“AlwaysCreate”。
1>ClCompile:
1>  x509asn1.c
1>  wolfssl.c
1>  vtls.c
1>e:\开源库集合\curl-7.83.1\lib\vssh/ssh.h(28): fatal error C1083: 无法打开包括文件:“libssh2.h”: No such file or directory
1>  sectransp.c
1>e:\开源库集合\curl-7.83.1\lib\vssh/ssh.h(28): fatal error C1083: 无法打开包括文件:“libssh2.h”: No such file or directory
1>  schannel_verify.c

提示找不到ssh.h。从解决方案配置中看到了libssh2库的身影,应该是当前的libcurl库使用了开源的libssh2库,于是去下载libssh2开源库代码,一是拿到libssh2库的头文件,二是将libssh2库的库文件编译出来,libcurl链接时肯定要用到libssh2库的。

3、下载并编译libssh2开源代码,部署到libcurl目录中

SSH为Secure Shell的缩写,专为远程登录会话和其他网络服务提供安全性的协议。利用 SSH 协议可以有效防止远程管理过程中的信息泄露问题。SSH1由于存在安全漏洞,所以产生了更为安全的SSH2,开源libssh2库实现了SSH2协议。

到libssh2官网上下载libssh2源码,解压后打开根路径,发现根路径下有个win32文件夹,点进去后看到Visual Studio相关的工程文件,如下所示:

工程文件是VC++6.0版本的,直接将工程文件拖到VS2010中,将工程文件升级到VS2010版本,然后发起编译,很快就编译完成了。

查看了一下libssh2工程的属性,发现该工程编译出来的是静态库,不是动态库,如下所示:

因为此处生成的是libssh2静态库,所以我们在libcurl的解决方案配置中选择“DLL Release - DLL OpenSSL”工程选项:

这个选项是使用libssh2静态库的。而DLL Release - DLL OpenSSL - DLL LibSSH2选项中则使用的是libssh2动态库,所以我们要使用前者。

于是将libssh2库目录中的include头文件以及编译出来的静态库拷贝到libcurl的工程目录curl-7.83.1中。我们在curl-7.83.1目录中创建一个名叫libssh2文件夹,然后在该文件夹中创建一个用来存放头文件的include文件夹和一个用来存放libssh2静态库的lib文件夹,如下:

于是我们到libcurl的工程属性中修改一下配置,首先修改引用libssh2\include下头文件的路径(包含头文件):

然后修改引用libssh2\lib目录下的libssh2.lib文件的路径(链接时引入的.lib文件):

于是继续编译libcurl工程,结果又提示找不到ssl.h头文件:

1>------ 已启动生成: 项目: libcurl, 配置: DLL Release - DLL OpenSSL Win32 ------
1>生成启动时间为 2022/5/17 17:01:17。
1>InitializeBuildStatus:
1>  正在对“..\..\..\..\build\Win32\VC10\DLL Release - DLL OpenSSL\lib\libcurl.unsuccessfulbuild”执行 Touch 任务。
1>ClCompile:
1>  x509asn1.c
1>  wolfssl.c
1>  vtls.c
1>  sectransp.c
1>  schannel_verify.c
1>  schannel.c
1>  rustls.c
1>  openssl.c
1>..\..\..\..\lib\vtls\openssl.c(63): fatal error C1083: 无法打开包括文件:“openssl/ssl.h”: No such file or directory
1>  nss.c
1>  mbedtls_threadlock.c

应该是和libssh2库一样,也需要获取openssl开源库的头文件和库文件。

4、获取openssl开源库的头文件和库文件,部署到libcurl目录中

到curl-7.83.1目录中去搜索,也找不到ssl.h文件。那应该是要去下载openssl开源库的源码并编译。到openssl官网上将源码下载下来,解压后在根路径中没有找到Windows平台编译专用的Visual Studio的工程文件,而libcurl和libssh2源码中是有专用的Visual Studio工程文件的。如果要手动编译openssl,则需要安装perl工具,然后通过perl去执行代码的编译,这个过程略显复杂。

我们可以到第三方网站上去下载别人已经编译好的openssl库,比如:

Win32/Win64 OpenSSL Installer for Windows - Shining Light Productionshttp://slproweb.com/products/Win32OpenSSL.html打开页面后,将页面向下拉动找到下载链接,我们的软件是32位的,所以选择32位版本的openssl即可。但下载链接比较多,我们只需要选择Win32 OpenSSL v3.0.3 Light版本即可,点击MSI按钮,下载MSI安装包:

然后执行该MSI安装包,这样就能把openssl头文件和库文件释放到目标路径中。然后打开安装目录查看安装的内容,从include路径中取出所有头文件,从lib路径中取出用于链接的.lib库,从bin路径中取出libssl-3.dll及其依赖的库。

lib路径中的文件比较多:

我们只需要取出libcurl链接时要用的libssl.lib库文件即可。

bin路径下的文件也比较多,除了要拿openssl库的主文件libssl-3.dll,还要取出哪些libssl-3.dll库依赖的dll文件呢?其实很简单,我们只需要使用Dependency Walker工具打开libssl-3.dll文件,看看libssl-3.dll依赖哪些dll库,如下所示:

除去libssl-3.dll依赖的一些系统库之外,我们看到了libssl-3.dll依赖了libcrypto-3.dll库,

在这个地方有个细节需要注意一下,Dependency Walker工具在Win10系统中打开dll很慢,等待的时间会比较长,估计得等1分钟左右,使用时要去耐心等待一会,等待Dependency Walker打开dll库完成,估计是因为Dependency Walker对Win10的兼容性不好导致打开dll文件很慢的。

和libssh2库处理类似,我们也在curl-7.83.1目录的根目录中创建一个openssl目录,在该目录再创建一个存放openssl头文件夹include,再创建一个存放.lib和.dll文件的lib路径。然后从之前Win32 OpenSSL v3.0.3 Light的安装目录中将相关文件拷贝过去。

接下来,我们到libcurl的工程属性中修改一下配置,首先修改引用openssl\include下的头文件路径(包含头文件):

然后修改引用openssl\lib目录下的libssl.lib文件的路径(链接时引入的.lib文件):

于是再编译libcurl工程,结果还是报找不到ssl.h头文件的错误:

1>------ 已启动生成: 项目: libcurl, 配置: DLL Release - DLL OpenSSL Win32 ------
1>生成启动时间为 2022/5/17 17:01:17。
1>InitializeBuildStatus:
1>  正在对“..\..\..\..\build\Win32\VC10\DLL Release - DLL OpenSSL\lib\libcurl.unsuccessfulbuild”执行 Touch 任务。
1>ClCompile:
1>  x509asn1.c
1>  wolfssl.c
1>  vtls.c
1>  sectransp.c
1>  schannel_verify.c
1>  schannel.c
1>  rustls.c
1>  openssl.c
1>..\..\..\..\lib\vtls\openssl.c(63): fatal error C1083: 无法打开包括文件:“openssl/ssl.h”: No such file or directory
1>  nss.c
1>  mbedtls_threadlock.c

后来查阅代码得知,代码中引用ssl.h头文件的地方,都加上了openssl相对路径,如下:

为了解决这个问题,我们再在include中添加一个openssl子文件夹,将所有openssl的头文件都搞到这个openssl子文件夹中存放,然后libcurl就能编译通过了。

5、将编译好的libcurl拿到测试项目中测试

将编译好的release版本的libcurl库及其依赖的几个库,拷贝到之前编写的包含发送邮件的程序中编译,运行测试程序,打开邮箱参数设置窗口,如下所示:

在邮箱参数设置窗口中填写好163邮箱SMTP服务器地址及端口、发送邮件地址和接收邮件通知的接收邮件地址,点击“发送接收邮件”按钮,发送测试邮件。经验证,是可以将测试邮件发出去的:

目标邮箱中也是能收到邮件的,邮件内容也是正确的。

至于如何开通发送邮件中的SMTP服务,可以参见之前写的这篇文章:

VC++调用libcurl开源库实现发送邮件的功能(附源码)https://blog.csdn.net/chenlycly/article/details/121318616

6、使用CMake工具手动生成VS工程文件,可以轻易地编译出libcurl库

libcurl开源代码的根目录中就有个CMakeLists.txt文件,该文件中配置了生成Windows平台上的Visual Studio工程文件的相关内容,于是使用CMake工具尝试自行生成VS工程文件。

CMake 是一个跨平台的开源构建系统,通过读取放置在每个源码根目录中的配置文件CMakeLists.txt中的内容,生成指定平台的标准构建文件,比如为 Unix 平台生成makefiles文件(用GCC编译),为 Windows平台的MSVC(Microsoft Visual Studio C++)生成 projects/workspaces(用Visual Studio编译)或makefile文件(用nmake编译)。

打开CMake工具后,先设置libcurl源码的根路径,然后再设置生成的Visual Studio工程文件的目录:

然后点击Generate按钮,弹出选择哪种解决方案:

此处我们需要使用VS2010,所生成VC++工程文件的时间比较长,大概需要等待几分钟时间,生成完成后,我们打开对应的目录,如下所示:

打开后编译libcurl工程即可,编译速度很快。根据编译时打印的信息得知,该种方式下使用的是wolfssl,没有使用openssl,libcurl的目录中也找不到openssl的头文件,所以通过CMake工具生成的VS工程编译时不需要libssh2和openssl开源库了,如下:

根据编译输出的路径,可以到对应的路径中找到生成的libcurl库文件:libcurl_imp.lib和libcurl.dll。

相比于上面那种编译libssh2开源库及获取openssl库的方式,这种方式要简单的多。将libcurl_imp.lib和libcurl.dll拿到测试工具的工程中测试,也是能正常发送邮件的。

7、总结

上面使用了两个途径去编译libcurl库。一种是使用libcurl开源库自带的VS工程去编译,但要先去编译libssh2开源库,然后去获取openssl开源库的头文件及库文件,最后再来编译libcurl工程。另一种方式是使用CMake工具,输入CMakeLists.txt,即可自动生成VC的工程,可以直接编译出libcurl库,不需要再去编译libssh2和openssl库。经测试,这两种方式编译出来的库都是可用的,都能将测试邮件发送出去。

【C++进阶】详解C++开源网络传输库libcurl的编译过程相关推荐

  1. 基于linux-2.6.34内核编译详解,Linux 2.6、4.3内核编译过程的感受与总结

    8种机械键盘轴体对比 本人程序员,要买一个写代码的键盘,请问红轴和茶轴怎么选? 之前编译过2.4.10版本的内核,很好编译,中间曾经漏下了SCSI low-level drivers下的BusLogi ...

  2. 2接口详解_TS入门笔记2——TS接口进阶详解

    TS入门笔记--TS接口进阶详解 一.为什么需要接口? let obj:object; // 定义了一个只能保存对象的变量 // obj = 1; // obj = "123"; ...

  3. ubuntu下sed命令详解 - Dicky - 开源中国社区

    ubuntu下sed命令详解 - Dicky - 开源中国社区 ubuntu下sed命令详解 - Dicky - 开源中国社区 ubuntu下sed命令详解     7人收藏此文章, 我要收藏 发表于 ...

  4. 【React】 详解下一代开源混合应用框架Reapp

    详解下一代开源混合应用框架Reapp reapp官网 转载于:https://www.cnblogs.com/dongdong230/p/4314978.html

  5. 深度学习网络模型——RepVGG网络详解、RepVGG网络训练花分类数据集整体项目实现

    深度学习网络模型--RepVGG网络详解.RepVGG网络训练花分类数据集整体项目实现 0 前言 1 RepVGG Block详解 2 结构重参数化 2.1 融合Conv2d和BN 2.2 Conv2 ...

  6. linux上 arm开发环境搭建,详解 LINUX下QT For ARM开发环境搭建过程

    LINUX下QT For ARM开发环境搭建过程是本文介绍的内容,不多说,先来看内容.在PC上,我们需要得到两个版本的Qt,分别是:Qt-4.5.2和QtEmbedded-4.5.2-arm.前者包括 ...

  7. winform访问被拒绝_详解C#对路径...的访问被拒绝解决过程

    用C#想写一个直接将数据库查询得到的datatable,直接导出为csv格式的文件,拷贝到导出的操作类后,一直catch到的错误提示是对路径的泛微被拒绝,一直排查原因,发现原来:FileStream( ...

  8. Redis基础与高可用集群架构进阶详解

    一.NoSQL简介 1.问题引入 每年到了过年期间,大家都会自觉自发的组织一场活动,叫做春运!以前我们买票都是到火车站排队,后来呢,有了 12306,有了它以后就更方便了,我们可以在网上买票,但是带来 ...

  9. 【笔记】IP地址详解、Linux网络及常用命令

    IP地址 IP地址基本概念 IP地址(Internet Protocol Address)是指互联网协议地址,又译为网际协议地址.IP地址在网络层将不同的物理网络地址统一到了全球唯一的IP地址上(屏蔽 ...

最新文章

  1. 干货!机器学习中,如何优化数据性能
  2. is this mysql server_Mysql:is not allowed to connect to this MySQL server
  3. JavaScript的表单事件
  4. Codeforces Round #635 (Div. 2) D. Xenia and Colorful Gems 暴力 + 二分
  5. 休眠:在sqlRestriction上使用联接表别名
  6. WinPcap笔记(3):获取已安装设备的详细信息
  7. xss跨站脚本攻击_网络安全xss跨站脚本攻击原理
  8. javascript : instanceof,typeof,constructor
  9. vue中实现国际化--语言切换(转载)
  10. 《ActionScript 3.0基础教程》——2.2 显示队列概述
  11. 《我和PIC单片机:基于PIC18》——2.2 MPLAB IDE集成开发环境
  12. 服务器数据恢复建议_raid磁盘阵列OFFLINE后的应急处理方案
  13. 获取input输入值和获取form表单中的组件输入值区别
  14. android icon背景透明,Android 图标去白色背景换成透明 用Photoshop实现
  15. PC时代的20位英雄
  16. NSArray进行汉字排序
  17. Linux应用程序动态更改用户ID
  18. IDEA中maven使用tomcat插件,tomcat并没有启动,无tomcat日志信息
  19. 浅析智能网联产业发展与变化趋势
  20. 解决“System.Data.OracleClient 需要 Oracle 客户端软件 version 8.1.7 或更高版本”的问题

热门文章

  1. 【检测技术课案】直流低电阻测试仪的设计与制作(一)
  2. 【MapGIS精品教程】009:空间缓冲区分析案例教程
  3. JAVA端实现支付宝付款
  4. Ubuntu复制文件到指定文件夹
  5. 一个初级小萝卜头的感想
  6. 安装ubuntu卡在检测硬盘_转载:如何在Ubuntu下监视硬盘状态
  7. 【无标题】类模板定义实例化
  8. 音频监控叫好又叫座 核心部件拾音器怎么装?
  9. cvs add: added independently by second party 问题解决
  10. 该出手时就出手,风风火火挂QQ