You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用CMake为C++项目正确链接nghttp2 asio库

CMake配置nghttp2库依赖解决方案

问题根因

你遇到的链接错误核心原因有两个:

  1. nghttp2::asio_http2::server 等Asio封装的接口实现不在核心的libnghttp2库中,而是在独立的libnghttp2_asio库中,你原来的配置仅链接了nghttp2核心库,缺少asio封装库的链接。
  2. nghttp2源码默认不会编译Asio组件,如果你使用本地子模块编译的方式,需要手动开启编译开关。

两种优雅配置方案

方案1:使用系统预安装的nghttp2(推荐)

这种方案不需要编译nghttp2子模块,运行效率更高,配置更简洁:

  1. 先确保你的系统已经正确安装nghttp2的asio组件:
    • 源码编译nghttp2时需添加--enable-asio-lib编译参数
    • Ubuntu/Debian可直接安装apt install libnghttp2-dev
  2. 修改CMakeLists.txt配置,替换原来的nghttp2子模块相关配置:
# 新增PkgConfig依赖用于查找nghttp2_asio
find_package(PkgConfig REQUIRED)
pkg_check_modules(NGHTTP2_ASIO REQUIRED libnghttp2_asio)

# 添加编译定义,对应你手动编译时的-DBOOST_LOG_DYN_LINK参数
target_compile_definitions(${PROJECT_NAME} PRIVATE BOOST_LOG_DYN_LINK)

# 引入nghttp2_asio头文件和库路径
target_include_directories(${PROJECT_NAME} PRIVATE ${NGHTTP2_ASIO_INCLUDE_DIRS})
target_link_directories(${PROJECT_NAME} PRIVATE ${NGHTTP2_ASIO_LIBRARY_DIRS})

# 链接nghttp2_asio和缺失的OpenSSL::SSL库
target_link_libraries(${PROJECT_NAME}
        PRIVATE Threads::Threads
        PRIVATE Boost::system
        PRIVATE Boost::thread
        PRIVATE Boost::log
        PRIVATE OpenSSL::Crypto
        PRIVATE OpenSSL::SSL
        PRIVATE ${NGHTTP2_ASIO_LIBRARIES}
)
  1. 删掉原来的set(NGHTTP2_SRC_DIR lib/nghttp2)、add_subdirectory、链接nghttp2的相关代码即可。

方案2:使用本地lib目录下的nghttp2子模块编译

如果你需要随项目一起编译nghttp2,可使用该方案:

  1. 在add_subdirectory之前开启nghttp2的asio编译开关,修改nghttp2相关配置为:
# 开启nghttp2 asio组件编译
set(ENABLE_ASIO_LIB ON CACHE BOOL "Build nghttp2 asio library" FORCE)
# 可选:如果不需要静态库可关闭,减少编译时间
set(ENABLE_STATIC_LIB OFF CACHE BOOL "" FORCE)

set(NGHTTP2_SRC_DIR lib/nghttp2)
add_subdirectory(${NGHTTP2_SRC_DIR})

target_compile_definitions(${PROJECT_NAME} PRIVATE BOOST_LOG_DYN_LINK)
# 直接链接nghttp2子模块导出的nghttp2_asio目标
target_link_libraries(${PROJECT_NAME} PUBLIC nghttp2_asio OpenSSL::SSL)
  1. 删掉原来链接nghttp2核心库的配置即可。

其他需要修正的配置

  • 你原来的CMake配置仅链接了OpenSSL::Crypto,缺少手动编译时的-lssl对应的OpenSSL::SSL依赖,需要补上否则会出现SSL相关接口的链接错误。
  • 你原来配置中的target_include_directories指向的include目录在你的项目结构中不存在,没用的话可以直接删掉,避免后续编译出现路径警告。

内容的提问来源于stack exchange,提问作者user16516564

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 18:27:04