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

CMake链接依赖GRPC的库时出现链接错误,求正确处理方式

问题描述

我有一个依赖GRPC第三方库的应用,用Make构建时,通过pkg-config --libs protobuf grpc++ grpc能正常完成链接。但切换到CMake+Vcpkg构建后,链接第三方库时出现大量未定义引用错误,示例错误如下:

In function `absl::lts_20220623::MutexLock::MutexLock(absl::lts_20220623::Mutex*)':
[build] (.text._ZN4absl12lts_202206239MutexLockC2EPNS0_5MutexE[_ZN4absl12lts_202206239MutexLockC5EPNS0_5MutexE]+0x26): undefined reference to `absl::lts_20220623::Mutex::Lock()'

目前我通过在target_link_libraries中直接添加pkg-config --libs protobuf grpc++ grpc的输出解决了问题,相关CMake配置如下:

target_include_directories(
....
/workspace/third_party/centos/grpc_1480/lib
....
)
target_link_libraries(kv-validation_lib PRIVATE fmt::fmt 
    libkv.a 
    libkvproto.a 
    yaml-cpp
    -lpthread 
    ${_REFLECTION}
    ${_GRPC_GRPCPP}
    ${_PROTOBUF_LIBPROTOBUF}
    stdc++fs
    <pkg-config --libs protobuf grpc++ grpc GOES HERE AND FIXES IT>
)

但这只是临时的hack方案。作为CMake新手,我想咨询:

  1. 如何正确告知CMake链接指定位置的库?
  2. 是否存在${_ABSL}这类可用的标志?
  3. 应该如何使用CMake的函数调用pkg-config文件?

我曾尝试使用${ABSL}标志但无效,已参考过Stack Overflow上的相关问题。

解决方案

1. 正确链接指定位置的库

不要直接在target_include_directories中填写库路径,推荐用find_library精准定位自定义路径下的库文件,再通过变量链接,这样更清晰且能处理库不存在的错误:

# 定位grpc相关库
find_library(GRPC_LIB grpc PATHS /workspace/third_party/centos/grpc_1480/lib NO_DEFAULT_PATH)
find_library(GRPCPP_LIB grpc++ PATHS /workspace/third_party/centos/grpc_1480/lib NO_DEFAULT_PATH)
find_library(PROTOBUF_LIB protobuf PATHS /workspace/third_party/centos/grpc_1480/lib NO_DEFAULT_PATH)
# 定位报错涉及的absl库
find_library(ABSL_MUTEX_LIB absl_mutex PATHS /workspace/third_party/centos/grpc_1480/lib NO_DEFAULT_PATH)
find_library(ABSL_BASE_LIB absl_base PATHS /workspace/third_party/centos/grpc_1480/lib NO_DEFAULT_PATH)

# 链接时使用找到的库变量
target_link_libraries(kv-validation_lib PRIVATE
    fmt::fmt 
    libkv.a 
    libkvproto.a 
    yaml-cpp
    -lpthread 
    ${_REFLECTION}
    ${GRPCPP_LIB}
    ${GRPC_LIB}
    ${PROTOBUF_LIB}
    ${ABSL_MUTEX_LIB}
    ${ABSL_BASE_LIB}
    stdc++fs
)

如果不想逐个定位,也可以用link_directories指定库搜索路径,但优先级低于find_library的定位结果:

link_directories(/workspace/third_party/centos/grpc_1480/lib)

2. 关于ABSL相关标志

CMake没有默认的${_ABSL}或${ABSL}变量,除非你自己定义,或者通过find模块、pkg-config导入。

  • 如果是Vcpkg安装的absl,它会提供CMake目标(比如absl::base、absl::mutex),可以直接链接:
    find_package(absl REQUIRED)
    target_link_libraries(kv-validation_lib PRIVATE absl::mutex absl::base)
    
    但必须保证Vcpkg的absl版本和第三方库依赖的版本完全匹配,否则仍会出现链接错误。
  • 如果第三方库用的是自定义编译的absl(比如报错中的lts_20220623版本),就需要像上面那样用find_library手动定位对应的absl库文件。

3. CMake调用pkg-config的正确方式

CMake提供pkg_check_modules函数来规范调用pkg-config,不需要手动执行命令:

# 导入protobuf、grpc++、grpc的pkg-config配置,生成PkgConfig::GRPC目标
pkg_check_modules(GRPC REQUIRED IMPORTED_TARGET protobuf grpc++ grpc)

# 链接时直接使用导入的目标
target_link_libraries(kv-validation_lib PRIVATE
    fmt::fmt 
    libkv.a 
    libkvproto.a 
    yaml-cpp
    -lpthread 
    ${_REFLECTION}
    PkgConfig::GRPC
    stdc++fs
)

pkg_check_modules会自动处理头文件路径、链接库、编译选项,比手动粘贴命令输出更可靠。如果自定义库的pkg-config文件不在默认搜索路径,可以通过PATHS参数指定:

pkg_check_modules(GRPC REQUIRED IMPORTED_TARGET protobuf grpc++ grpc
    PATHS /workspace/third_party/centos/grpc_1480/lib/pkgconfig
)

需要确保目标目录下存在protobuf.pc、grpc++.pc、grpc.pc这些pkg-config配置文件。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 21:13:24