C++ cpr网络库在MinGW-w64 gcc Windows下的编译配置与TaoToken接入实践

发布时间:2026/10/9 20:31:14
C++ cpr网络库在MinGW-w64 gcc Windows下的编译配置与TaoToken接入实践 1. Windows 下用 MinGW-w64 gcc 编译 cpr 网络库到底难在哪如果你在 Windows 上写 C又想发 HTTP 请求cpr 是个很顺手的选择——它的接口几乎照搬 Python 的 requestscpr::Get、cpr::Post一行就能发请求。但真正动手编译时很多人会卡在同一个地方MinGW-w64 gcc 环境下cpr 依赖 libcurl 和 OpenSSL而这两个库在 Windows 上并不像 Linux 那样apt install就完事。CMake 找不到头文件、链接阶段报undefined reference to curl_easy_init、OpenSSL 路径识别失败几乎是必经之路。这篇就聚焦 Windows 平台用 MinGW-w64 gcc 编译 cpr 的完整流程把依赖库链接和 CMake 配置这两块讲透。我会给出可以直接复制的 CMakeLists 配置、编译命令以及一段验证 HTTP 请求的测试代码。最后演示怎么把 API 端点改到 TaoToken 统一 Key 通道完成一次真实的连通性验证——这样你编译出来的 cpr 不只是能跑 demo而是能直接对接大模型接口。适合谁看在 Windows 上用 MinGW-w64 写 C、需要 HTTP 客户端、又不想被 Visual Studio 绑定的人。如果你用的是 MSVC流程会简单一些但本文的 CMake 配置思路同样有参考价值。先说清楚整体链路cpr 本身是个薄封装底层调用 libcurllibcurl 要支持 HTTPS就得链接 OpenSSL或 Schannel。所以编译 cpr 本质上是三件事——准备好 curl 和 OpenSSL 的库文件、让 CMake 找到它们、把 cpr 编成静态库或动态库供你的项目链接。MinGW-w64 的坑主要出在第二步和第三步路径写法、库文件名、链接顺序。我试过直接拿官网的源码包丢进 CMake GUI 点 Configure结果 OPENSSL 找不到、CURL 找不到报错刷了一屏。后来把依赖一个个手动指定才通。下面按顺序来你跟着做基本能一次过。2. 编译前的依赖准备与 TaoToken 接入前置在动手编译之前先把需要的东西备齐。cpr 的源码里有个opt目录专门用来放第三方依赖这是官方推荐的放置方式能省掉很多路径配置的麻烦。你需要准备这几样cpr 库本体从 GitHub 仓库下载源码压缩包解压后得到cpr-master目录。libcurl 的 Windows 预编译包注意要选和 MinGW-w64 匹配的版本通常用 MinGW 编译的 curl 包里面会有include和lib两个目录。OpenSSL 的 Windows 预编译包同样要 MinGW 版本或者用 MSYS2 里pacman -S mingw-w64-x86_64-openssl装出来的也行。mongoose 这个库 cpr 的测试会用到从 GitHub 下载后解压。把这些依赖解压后按 cpr 的约定放进cpr-master/opt下对应的子目录。curl 放进opt/libcurlOpenSSL 放进opt/opensslmongoose 放进opt/mongoose。目录结构大致是这样cpr-master/ ├── opt/ │ ├── libcurl/ │ │ ├── include/ │ │ └── lib/ │ ├── openssl/ │ │ ├── include/ │ │ └── lib/ │ └── mongoose/ ├── include/ ├── cpr/ └── CMakeLists.txt放好之后还要确认你的 MinGW-w64 工具链在 PATH 里。打开命令行敲gcc --version和cmake --version能输出版本号就说明环境没问题。我用的 gcc 是 8.1.0 x64 版本cmake 是 3.x版本不用太新够用就行。接下来是 TaoToken 的前置准备。TaoToken 是一个统一的大模型 API 接入通道你注册后拿到一个 API Key就能通过同一个端点调用不同厂商的模型。对本文来说它的作用是给我们一个真实的 HTTPS 接口来验证 cpr 编译结果——毕竟编译完总得发个请求确认能用。你需要做两件事一是到官网 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 注册账号二是进控制台 https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 创建一个 API Key。这个 Key 后面会写进测试代码里。API 的基础地址是 https://taotoken.net/api注意这个地址不带 UTM 参数是纯接口地址。提示API Key 属于敏感信息测试代码里建议用环境变量读取别直接硬编码提交到仓库。本文为了演示方便会写在代码里你实际用时记得改掉。依赖和 Key 都备齐后就可以进入 CMake 配置环节了。这一步是整个流程里最容易出问题的下一节详细说。3. 可复制的 CMakeLists 配置与编译命令这一节是核心。cpr 自带的 CMakeLists 在 MinGW-w64 下经常找不到依赖与其在 GUI 里一项项改不如直接写一个自己的 CMakeLists把路径和链接关系写死可控性最高。先看一个最小可用的 CMakeLists.txt放在你的项目根目录假设 cpr 源码在third_party/cpr-mastercmake_minimum_required(VERSION 3.10) project(cpr_demo CXX) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) # 依赖路径按你的实际解压位置改 set(CURL_ROOT ${CMAKE_SOURCE_DIR}/third_party/cpr-master/opt/libcurl) set(OPENSSL_ROOT ${CMAKE_SOURCE_DIR}/third_party/cpr-master/opt/openssl) # 头文件目录 include_directories( ${CURL_ROOT}/include ${OPENSSL_ROOT}/include ${CMAKE_SOURCE_DIR}/third_party/cpr-master/include ) # 库文件目录 link_directories( ${CURL_ROOT}/lib ${OPENSSL_ROOT}/lib ) # 把 cpr 源码直接编进来避免单独编译安装 file(GLOB_RECURSE CPR_SOURCES ${CMAKE_SOURCE_DIR}/third_party/cpr-master/cpr/*.cpp ) add_library(cpr STATIC ${CPR_SOURCES}) target_include_directories(cpr PUBLIC ${CMAKE_SOURCE_DIR}/third_party/cpr-master/include ${CURL_ROOT}/include ${OPENSSL_ROOT}/include ) # 链接 curl 和 openssl注意顺序 target_link_libraries(cpr PUBLIC curl ssl crypto ws2_32 crypt32 wldap32 normaliz ) add_executable(cpr_demo main.cpp) target_link_libraries(cpr_demo PRIVATE cpr)几个关键点解释一下。ws2_32、crypt32、wldap32是 Windows 下 curl 依赖的系统库漏掉会报一堆undefined reference。normaliz是 curl 在 Windows 上可能用到的库有些版本需要。链接顺序上curl 要放在 ssl 和 crypto 前面否则静态链接时符号解析会失败。如果你不想把 cpr 源码编进项目也可以先单独编译 cpr 生成静态库。用 CMake 命令行方式cd cpr-master mkdir build cd build cmake -G MinGW Makefiles \ -DCMAKE_BUILD_TYPERelease \ -DCURL_INCLUDE_DIR../opt/libcurl/include \ -DCURL_LIBRARY../opt/libcurl/lib/libcurl.a \ -DOPENSSL_INCLUDE_DIR../opt/openssl/include \ -DOPENSSL_SSL_LIBRARY../opt/openssl/lib/libssl.a \ -DOPENSSL_CRYPTO_LIBRARY../opt/openssl/lib/libcrypto.a \ -DCPR_BUILD_TESTSOFF \ .. mingw32-make -j4注意-DCPR_BUILD_TESTSOFFcpr 的测试依赖 mongoose关掉能省不少事。-G MinGW Makefiles指定生成器别用默认的否则可能生成 Visual Studio 工程。编译过程中如果报Could NOT find OpenSSL就是路径没指对检查OPENSSL_INCLUDE_DIR是否指向了包含openssl/ssl.h的那层目录。如果报undefined reference to __imp_curl_easy_init说明链接的是动态库的导入库但没找到对应的 dll换成静态库.a文件即可。编译完成后build/lib下会有libcpr.a把它和 curl、openssl 的静态库一起链接到你的项目就行。下面给一个完整的链接命令示例g main.cpp -o demo.exe \ -I./cpr-master/include \ -I./cpr-master/opt/libcurl/include \ -I./cpr-master/opt/openssl/include \ -L./cpr-master/build/lib \ -L./cpr-master/opt/libcurl/lib \ -L./cpr-master/opt/openssl/lib \ -lcpr -lcurl -lssl -lcrypto \ -lws2_32 -lcrypt32 -lwldap32 -lnormaliz \ -static-libgcc -static-libstdc-static-libgcc -static-libstdc是为了避免运行时缺 GCC 的 dll发布时更省心。4. 验证 HTTP 请求与 TaoToken 连通性测试编译通过只是第一步得发个真实请求确认。先写一个最简单的测试请求一个公开接口确认 cpr 基本功能正常#include cpr/cpr.h #include iostream int main() { auto r cpr::Get(cpr::Url{https://httpbin.org/get}); std::cout status: r.status_code std::endl; std::cout body: r.text.substr(0, 200) std::endl; return 0; }编译运行后如果输出status: 200说明 cpr 和 HTTPS 都正常。如果报 SSL 相关错误多半是 OpenSSL 没链接对或者证书路径有问题。接下来把端点换成 TaoToken验证统一 Key 通道。TaoToken 的接口兼容 OpenAI 格式所以用 cpr 发一个 chat completions 请求即可#include cpr/cpr.h #include nlohmann/json.hpp #include iostream using json nlohmann::json; int main() { const char* api_key std::getenv(TAOTOKEN_API_KEY); if (!api_key) { std::cerr 请设置 TAOTOKEN_API_KEY 环境变量 std::endl; return 1; } json payload { {model, gpt-4o-mini}, {messages, { {{role, user}, {content, 用一句话说明什么是HTTP}} }}, {max_tokens, 100} }; auto r cpr::Post( cpr::Url{https://taotoken.net/api/v1/chat/completions}, cpr::Header{ {Content-Type, application/json}, {Authorization, std::string(Bearer ) api_key} }, cpr::Body{payload.dump()}, cpr::Timeout{30000} ); std::cout status: r.status_code std::endl; if (r.status_code 200) { auto resp json::parse(r.text); std::cout resp[choices][0][message][content] std::endl; } else { std::cout error: r.text std::endl; } return 0; }这里用到了 nlohmann/json 来构造和解析 JSON它是个 header-only 库下载一个json.hpp放进 include 目录就行。编译时加上-I./include。运行前设置环境变量set TAOTOKEN_API_KEY你的Key demo.exe如果返回 200 并打印出模型回复说明整条链路通了cpr 编译正确、HTTPS 正常、TaoToken 的 Key 通道可用。如果返回 401检查 Key 是否正确、有没有多余空格。如果返回 404检查 URL 路径是不是/api/v1/chat/completions。注意TaoToken 的模型 ID 要填它支持的名称具体可以在模型对话页面 https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 查看可用列表。填错模型名会返回 400。5. 编译与请求常见报错排查这一节把实际会遇到的报错列出来对照着查。报错一Could NOT find CURL (missing: CURL_LIBRARY CURL_INCLUDE_DIR)CMake 没找到 curl。解决方法是显式指定路径在 cmake 命令里加-DCURL_INCLUDE_DIR.../include -DCURL_LIBRARY.../lib/libcurl.a。注意CURL_LIBRARY要指向具体的库文件不是目录。报错二undefined reference to curl_easy_init链接阶段找不到 curl 符号。原因通常是链接顺序不对或者链接的是导入库而非静态库。把-lcurl放在-lssl -lcrypto前面并确认用的是.a静态库。如果用的是.dll.a导入库运行时还需要对应的 dll 在 PATH 里。报错三local proxy failed或连接超时cpr 默认会读取系统代理设置。如果你的环境有代理配置但代理不可用请求会失败。可以在代码里显式禁用代理auto r cpr::Get( cpr::Url{https://taotoken.net/api/v1/models}, cpr::Proxies{{http, }, {https, }} );或者在系统环境变量里清掉HTTP_PROXY、HTTPS_PROXY。报错四error: reading choices或 JSON 解析失败请求返回了非 200但代码直接去解析choices字段。先判断r.status_code 200再解析否则打印r.text看服务端返回的错误信息。常见的是 401Key 无效或 400请求体格式错误。报错五OAuth 或认证失败如果返回 401 且提示认证问题检查Authorization头格式是不是Bearer key中间有一个空格。cpr 的 Header 是std::map重复的 key 会被覆盖别写错。报错六cannot find -lnormaliz有些 curl 版本不需要 normaliz。如果链接报这个错把-lnormaliz去掉再试。反之如果报其他 Windows 库缺失按报错提示补上对应的-l参数。报错七CMake 生成的是 Visual Studio 工程没指定-G MinGW MakefilesCMake 默认用了 VS 生成器。重新执行 cmake 时加上生成器参数并清空 build 目录。排查时有个通用技巧把CMAKE_VERBOSE_MAKEFILE设为 ON能看到完整的编译和链接命令哪一步出错一目了然。cmake -G MinGW Makefiles -DCMAKE_VERBOSE_MAKEFILEON ..6. 把 cpr 接入长期编码工作流的建议编译通了、请求也验证过了接下来是怎么把它用顺。如果你打算在项目里长期用 cpr 对接大模型接口有几个实践建议。第一把 API Key 和 Base URL 抽成配置。别硬编码在源码里用环境变量或配置文件读取。TaoToken 的 Base URL 是https://taotoken.net/api所有模型共用这一个端点换模型只改model字段这对写多模型对比的代码特别方便。第二封装一个薄客户端。cpr 的接口已经很简洁但每次手写 Header 和 JSON 还是啰嗦。可以封一个ChatClient类构造时传入 Key提供chat(prompt)方法内部处理请求和错误。这样业务代码里只有一行调用。第三注意超时和重试。大模型接口响应可能较慢cpr::Timeout设 30 秒比较稳妥。网络抖动时加重试逻辑cpr 本身不提供重试需要自己包一层循环。第四静态链接发布。用-static-libgcc -static-libstdc加上静态链接 curl 和 openssl生成的 exe 不依赖额外 dll拷到别的机器直接能跑。代价是体积大一些但省心。如果你需要管理多个项目的 Key或者想用 Coding Plan 的方式统一管理调用额度可以到 https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 看看。对于需要频繁调用模型的编码场景统一通道比每个项目单独配 Key 要清爽得多。最后说个实际踩过的坑MinGW-w64 的版本和 curl 预编译包的版本要匹配32 位对 32 位64 位对 64 位。混用会在链接时报架构不匹配的错误而且报错信息不明显容易查半天。编译前先确认gcc -dumpmachine的输出和 curl 包的架构对上。整套流程走下来从依赖准备到编译再到请求验证顺利的话半小时内能搞定。卡住的地方基本都在 CMake 找依赖和链接顺序上对照第 5 节的报错表查大部分问题能定位。编译好的 cpr 静态库可以复用下次新项目直接链接就行不用重新编。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询