背景
由于c++项目需要通过https请求与后台通信,于是找到了curl这个c++开源库。
需要支持Windows平台和Linux系统,于是,先尝试在Windows上安装。
使用vcpkg工具安装
curl提供vcpkg的安装方式。这是首次使用vcpkg。上手如下:
1. 在E盘创建目录,vcpkg。进入cppkg目录。
2. 从githup上下载vcpkg工具,下载地址:git clone https://github.com/Microsoft/vcpkg.git
3. 进入vcpkg的目录,执行:
bootstrap.exe
自行完后,会生成 vcpkg.exe.
4. 在安装curl执行,先查看提供的curl库。
e:\vcpkg\vcpkg-master>vcpkg.exe search curl
azure-core-cpp[curl] Libcurl HTTP transport implementation
cfitsio[curl] UseCurl
cocoyaxi[libcurl] libcurl with OpenSSL support
configcat[network] Use built-in curl network adapter
cpr 1.10.5#2 C++ Requests is a simple wrapper around libcurl inspired by the excellent ...
cpr[ssl] Enable SSL support
curl 8.7.1 A library for transferring data with URLs
curl[brotli] brotli support (brotli)
curl[c-ares] c-ares support
curl[http2] HTTP2 support
curl[idn] Default IDN support
curl[idn2] idn2 support (libidn2)
curl[ldap] LDAP support
curl[mbedtls] SSL support (mbedTLS)
curl[non-http] Enables protocols beyond HTTP/HTTPS/HTTP2
curl[openssl] SSL support (OpenSSL)
curl[schannel] SSL support (Secure Channel)
curl[sectransp] SSL support (sectransp)
curl[ssh] SSH support via libssh2
curl[ssl] Default SSL backend
curl[sspi] SSPI support
curl[tool] Builds curl executable
curl[websockets] WebSocket support (experimental)
curl[winidn] WinIDN support
curl[winldap] Obsolete. Use feature 'ldap' instead.
curl[winssl] Legacy name for schannel
curl[wolfssl] SSL support (wolfSSL)
curl[zstd] ZStandard support (zstd)
curlpp 2018-06-15#9 C++ wrapper around libcURL
czmq[curl] Build with libcurl
gdal[curl] Enable CURL network support
juce[curl] Enable CURL support
libcurl-simple-https 2022-02-14 Very simple HTTPS interface built atop libcurl
librdkafka[curl] Build with curl
oatpp-curl 1.3.0#1 Oat++ Modern web framework curl module to use libcurl as a RequestExecutor...
poppler[curl] curl for poppler
restclient-cpp 2022-02-09 Simple REST client for C++. It wraps libcurl for HTTP requests.
vsgxchange[curl] Enable support for reading image and model files from http:// and https://
The result may be outdated. Run `git pull` to get the latest results.
If your port is not listed, please open an issue at and/or consider making a pull request. - https://github.com/Microsoft/vcpkg/issues
由于我们需要使用https,并且使用openssl库,所以应该安装curl[openssl].
接下来要确定编译的模式,包括架构、32位还是64位、静态链接还是动态链接、release还是debug。这些信息属于vcpkg的triplets。那么vcpkg支持哪些triplets呢?
Triplets的介绍参考微软官网:https://learn.microsoft.com/en-us/vcpkg/concepts/triplets
运行vcpkg help triplet查看环境支持的triplets:
e:\vcpkg\vcpkg-master>vcpkg help triplet
Built-in Triplets:
arm-neon-android
arm64-android
arm64-osx
arm64-uwp
arm64-windows
x64-android
x64-linux
x64-osx
x64-uwp
x64-windows-static
x64-windows
x86-windows
Community Triplets:
arm-android
arm-ios
arm-linux-release
arm-linux
arm-mingw-dynamic
arm-mingw-static
arm-uwp-static-md
arm-uwp
arm-windows-static
arm-windows
arm64-ios-release
arm64-ios-simulator-release
arm64-ios-simulator
arm64-ios
arm64-linux-release
arm64-linux
arm64-mingw-dynamic
arm64-mingw-static
arm64-osx-dynamic
arm64-osx-release
arm64-uwp-static-md
arm64-windows-static-md
arm64-windows-static-release
arm64-windows-static
arm64ec-windows
armv6-android
loongarch32-linux-release
loongarch32-linux
loongarch64-linux-release
loongarch64-linux
mips64-linux
ppc64le-linux-release
ppc64le-linux
riscv32-linux-release
riscv32-linux
riscv64-linux-release
riscv64-linux
s390x-linux-release
s390x-linux
wasm32-emscripten
x64-freebsd
x64-ios
x64-linux-dynamic
x64-linux-release
x64-mingw-dynamic
x64-mingw-static
x64-openbsd
x64-osx-dynamic
x64-osx-release
x64-uwp-static-md
x64-windows-release
x64-windows-static-md-release
x64-windows-static-md
x64-windows-static-release
x64-xbox-scarlett-static
x64-xbox-scarlett
x64-xbox-xboxone-static
x64-xbox-xboxone
x86-android
x86-freebsd
x86-ios
x86-linux
x86-mingw-dynamic
x86-mingw-static
x86-uwp-static-md
x86-uwp
x86-windows-static-md
x86-windows-static
x86-windows-v120
这些triplet是什么意思呢?在triplets文件夹中有所有列出来的triplet,随便找一个看看,例如:community/x64-windows-static-md-release.cmake。
set(VCPKG_TARGET_ARCHITECTURE x64)
set(VCPKG_CRT_LINKAGE dynamic)
set(VCPKG_LIBRARY_LINKAGE static)set(VCPKG_BUILD_TYPE release)
VCPKG_TARGET_ARCHITECTURE:这个不用解释。
VCPKG_CRT_LINKAGE:使用哪个运行库,对应vs选项MT、MTD、MD、MDD
VCPKG_LIBRARY_LINKAGE:生成动态库还是静态库
VCPKG_BUILD_TYPE:编译release还是debug。
Todo:我还有一个疑问,用哪个c++标准编译的?我安装的使用vs2019。
5. 编译静态连接的静态库
vcpkg install curl[openssl]:x86-windows-static-release
vcpkg在安装 过程中,会检查依赖的包,并自动下载,放在tools目录中。确实非常方便。
不过在我的使用场景中,有个问题,就是openssl的版本。我发现vcpkg自动下载的openssl是3.2.1版本。但是我其他项目使用的是1.1.1j版本,会不会冲突?如何避免冲突?这其实是包管理中非常重要的问题。为了方便,我都采用3.2.1版本的openssl。
编译完成之后,再installed/x64-windows-static-release目录中可以看到编译好的库。
https demo
库已经编译好,编一个demo试试。从网站上下载了一个demo:https://curl.se/libcurl/c/https.html,把网址修改为:https://www.baidu.com,并且不验证对方。编译时指定库的头文件目录和库目录,并连接库即可。我这里是把libs目录copy到工程的../../目录。
#添加库的头文件目录
include_directories(../../libs/include)
#添加库目录
link_directories(${PROJECT_SOURCE_DIR}/../../libs/lib)
#链接库
target_link_libraries(${PROJECT_NAME} WS2_32.LIB CRYPT32.LIB libcrypto libssl libcurl.lib zlib.lib)
编译,执行成功。
完整的demo代码如下:
#include <stdio.h>
#include <curl/curl.h>
int main(void)
{
CURL *curl;
CURLcode res;
curl_global_init(CURL_GLOBAL_DEFAULT);
curl = curl_easy_init();
if(curl) {
curl_easy_setopt(curl, CURLOPT_URL, "https://www.baidu.com");
#define SKIP_PEER_VERIFICATION
#ifdef SKIP_PEER_VERIFICATION
/*
* If you want to connect to a site who is not using a certificate that is
* signed by one of the certs in the CA bundle you have, you can skip the
* verification of the server's certificate. This makes the connection
* A LOT LESS SECURE.
*
* If you have a CA cert for the server stored someplace else than in the
* default bundle, then the CURLOPT_CAPATH option might come handy for
* you.
*/
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
#endif
#define SKIP_HOSTNAME_VERIFICATION
#ifdef SKIP_HOSTNAME_VERIFICATION
/*
* If the site you are connecting to uses a different host name that what
* they have mentioned in their server certificate's commonName (or
* subjectAltName) fields, libcurl refuses to connect. You can skip this
* check, but it makes the connection insecure.
*/
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
#endif
/* cache the CA cert bundle in memory for a week */
curl_easy_setopt(curl, CURLOPT_CA_CACHE_TIMEOUT, 604800L);
/* Perform the request, res gets the return code */
res = curl_easy_perform(curl);
/* Check for errors */
if(res != CURLE_OK)
fprintf(stderr, "curl_easy_perform() failed: %s\n",
curl_easy_strerror(res));
/* always cleanup */
curl_easy_cleanup(curl);
}
curl_global_cleanup();
return 0;
}