网络库集成:使用FetchContent下载Boost.Asio、libcurl、cpp-httplib
做C++网络编程,选库是个头疼事。Boost.Asio功能全但重,libcurl老牌稳定,cpp-httplib轻量现代。我个人的习惯是,根据项目场景混着用。但不管用哪个,集成到CMake里都得花点功夫。
今天咱们就聊聊,怎么用FetchContent把这仨网络库一键拉下来,不用手动下载、不用系统安装,干净又省心。
为什么选这三个库?
先说说我的选择逻辑。你想想看,一个正经的网络模块,通常需要三样东西:
- 异步IO能力 —— Boost.Asio 是这方面的标杆
- HTTP客户端请求 —— libcurl 支持各种协议,稳如老狗
- 轻量HTTP服务端 —— cpp-httplib 头文件即用,写个REST API分分钟
我在项目中遇到过好几次,团队里有人手动下载了某个库的旧版本,结果跟编译器不兼容,折腾了两天。用FetchContent统一管理版本,这种坑就再也没踩过。
FetchContent 集成 Boost.Asio
Boost.Asio 比较特殊,它本身是Boost的一部分。但好消息是,Boost现在支持单独拉取Asio模块了。我们只需要拉 boost-asio 和它依赖的 boost-system、boost-core 等几个子模块。
include(FetchContent)
FetchContent_Declare(
boost-asio
GIT_REPOSITORY https://github.com/boostorg/asio.git
GIT_TAG boost-1.84.0
GIT_SHALLOW TRUE
)
FetchContent_Declare(
boost-system
GIT_REPOSITORY https://github.com/boostorg/system.git
GIT_TAG boost-1.84.0
GIT_SHALLOW TRUE
)
FetchContent_Declare(
boost-core
GIT_REPOSITORY https://github.com/boostorg/core.git
GIT_TAG boost-1.84.0
GIT_SHALLOW TRUE
)
FetchContent_MakeAvailable(boost-asio boost-system boost-core)
GIT_SHALLOW TRUE 只拉最新提交,能省下不少下载时间。我第一次拉Boost全量包等了半小时,后来改用浅克隆,十几秒搞定。
集成之后,在CMakeLists.txt里链接:
target_link_libraries(my_app PRIVATE
Boost::asio
Boost::system
)
嗯,这里要注意一点:Boost.Asio 在C++17以上版本可以不用Boost.System,直接用 <system_error> 标准库。但为了兼容老项目,我一般还是带着。
FetchContent 集成 libcurl
libcurl 的集成稍微麻烦点,因为它依赖 OpenSSL 或 mbedTLS 等加密库。不过我们可以用 CURL_USE_OPENSSL 选项来控制。
FetchContent_Declare(
curl
GIT_REPOSITORY https://github.com/curl/curl.git
GIT_TAG curl-8_6_0
GIT_SHALLOW TRUE
)
set(BUILD_CURL_EXE OFF CACHE BOOL "" FORCE)
set(BUILD_TESTING OFF CACHE BOOL "" FORCE)
set(CURL_USE_OPENSSL ON CACHE BOOL "" FORCE)
set(HTTP_ONLY ON CACHE BOOL "" FORCE)
FetchContent_MakeAvailable(curl)
CURL_USE_OPENSSL,避免跨平台时行为不一致。曾经有个项目在Linux上跑得好好的,搬到Windows上SSL握手全挂了,就是因为这个。
链接方式:
target_link_libraries(my_app PRIVATE CURL::libcurl)
FetchContent 集成 cpp-httplib
cpp-httplib 是最省心的,纯头文件库,一行代码都不用配。
FetchContent_Declare(
cpp-httplib
GIT_REPOSITORY https://github.com/yhirose/cpp-httplib.git
GIT_TAG v0.14.3
GIT_SHALLOW TRUE
)
FetchContent_MakeAvailable(cpp-httplib)
使用的时候,直接 #include "httplib.h" 就行。不过要注意,如果你要用SSL功能,得先定义 CPPHTTPLIB_OPENSSL_SUPPORT 宏。
target_compile_definitions(my_app PRIVATE CPPHTTPLIB_OPENSSL_SUPPORT)
target_link_libraries(my_app PRIVATE
cpp-httplib
OpenSSL::SSL
OpenSSL::Crypto
)
完整集成示例
下面是一个完整的CMakeLists.txt,把三个库一次性拉下来:
cmake_minimum_required(VERSION 3.14)
project(NetworkDemo CXX)
set(CMAKE_CXX_STANDARD 17)
include(FetchContent)
# ---- Boost.Asio ----
FetchContent_Declare(
boost-asio
GIT_REPOSITORY https://github.com/boostorg/asio.git
GIT_TAG boost-1.84.0
GIT_SHALLOW TRUE
)
FetchContent_Declare(
boost-system
GIT_REPOSITORY https://github.com/boostorg/system.git
GIT_TAG boost-1.84.0
GIT_SHALLOW TRUE
)
FetchContent_Declare(
boost-core
GIT_REPOSITORY https://github.com/boostorg/core.git
GIT_TAG boost-1.84.0
GIT_SHALLOW TRUE
)
# ---- libcurl ----
set(BUILD_CURL_EXE OFF)
set(BUILD_TESTING OFF)
set(CURL_USE_OPENSSL ON)
set(HTTP_ONLY ON)
FetchContent_Declare(
curl
GIT_REPOSITORY https://github.com/curl/curl.git
GIT_TAG curl-8_6_0
GIT_SHALLOW TRUE
)
# ---- cpp-httplib ----
FetchContent_Declare(
cpp-httplib
GIT_REPOSITORY https://github.com/yhirose/cpp-httplib.git
GIT_TAG v0.14.3
GIT_SHALLOW TRUE
)
FetchContent_MakeAvailable(
boost-asio boost-system boost-core
curl
cpp-httplib
)
add_executable(my_app main.cpp)
target_link_libraries(my_app PRIVATE
Boost::asio
Boost::system
CURL::libcurl
cpp-httplib
)
集成架构图
下面这张图展示了三个网络库在项目中的角色和依赖关系:
避坑指南
集成过程中有几个容易踩的坑,我挨个说说:
- 版本冲突: 如果项目里已经用了Boost其他模块,拉Boost.Asio时要注意版本一致。我曾经把Asio拉了1.84,但其他Boost模块是1.80,结果编译报了一堆模板错误。
- SSL证书路径: libcurl在Linux上默认找
/etc/ssl/certs,但有些容器镜像里没有。记得用CURLOPT_CAINFO指定证书路径。 - cpp-httplib的线程安全: 它的HTTP服务端默认是单线程的。如果你要处理高并发,记得设置
svr.new_task_queue = [] { return new httplib::ThreadPool(8); }; - GitHub访问问题: 如果网络环境不好,可以考虑用Gitee镜像或者提前下载好源码包,用
URL参数指定本地路径。
cmake/fetch_dependencies.cmake 文件,把所有FetchContent声明都放进去。主CMakeLists.txt里只用一行 include(cmake/fetch_dependencies.cmake) 就搞定了。这样结构清晰,也好维护。
好了,三个网络库的集成方法都讲完了。说白了就是三步:声明、配置、链接。你只要把版本号和编译选项调对,剩下的FetchContent全帮你搞定。下次再有人问你「怎么在CMake里加网络库」,你可以直接把这篇甩给他。
公众号:蓝海资料掘金营,微信deep3321