项目同时依赖gflags和glog时CMake构建失败的解决方法
问题
我有一个同时依赖gflags和glog的C++项目,相关代码及操作如下:
我的CMakeLists.txt
cmake_minimum_required(VERSION 3.23.2) project(demo) include(FetchContent) FetchContent_Declare(gflags URL https://github.com/gflags/gflags/archive/v2.2.2.zip URL_HASH SHA256=19713a36c9f32b33df59d1c79b4958434cb005b5b47dc5400a7a4b078111d9b5 ) FetchContent_MakeAvailable(gflags) include_directories(${gflags_BINARY_DIR}/include) FetchContent_Declare(glog URL https://github.com/google/glog/archive/v0.4.0.zip URL_HASH SHA256=9e1b54eb2782f53cd8af107ecf08d2ab64b8d0dc2b7f5594472f3bd63ca85cdc ) FetchContent_MakeAvailable(glog) include_directories(${glog_SOURCE_DIR}/src ${glog_BINARY_DIR}) add_executable(demo demo.cc) target_link_libraries(demo glog::glog)
我的demo.cc
#include <iostream> using namespace std; #include <glog/logging.h> int main(int argc, char** argv){ gflags::ParseCommandLineFlags(&argc, &argv, true); google::InitGoogleLogging(argv[0]); LOG(INFO) << "This is INFO log information"; return 0; }
构建命令及错误
执行构建命令:
mkdir -p build cd build cmake ..
执行后出现如下错误:
CMake Error in build/_deps/glog-src/CMakeLists.txt: export called with target "glog" which requires target "gflags_nothreads_static" that is not in this export set, but in multiple other export sets: .../build/_deps/gflags-build/gflags-nonamespace-targets.cmake, .../build/_deps/gflags-build/gflags-targets.cmake. An exported target cannot depend upon another target which is exported multiple times. Consider consolidating the exports of the "gflags_nothreads_static" target to a single export.
请问如何通过修改我自己的CMakeLists.txt来消除上述错误?
解决方法
错误根源是gflags 2.2.2版本默认会生成带命名空间和不带命名空间的两套导出目标,导致glog依赖的gflags目标被重复导出,触发CMake的检查错误。
修改CMakeLists.txt,在拉取gflags前添加set(gflags_NAMESPACE gflags),强制gflags只生成带命名空间的目标,避免重复导出:
cmake_minimum_required(VERSION 3.23.2) project(demo) include(FetchContent) # 强制gflags只生成带命名空间的目标,避免重复导出 set(gflags_NAMESPACE gflags) FetchContent_Declare(gflags URL https://github.com/gflags/gflags/archive/v2.2.2.zip URL_HASH SHA256=19713a36c9f32b33df59d1c79b4958434cb005b5b47dc5400a7a4b078111d9b5 ) FetchContent_MakeAvailable(gflags) FetchContent_Declare(glog URL https://github.com/google/glog/archive/v0.4.0.zip URL_HASH SHA256=9e1b54eb2782f53cd8af107ecf08d2ab64b8d0dc2b7f5594472f3bd63ca85cdc ) FetchContent_MakeAvailable(glog) add_executable(demo demo.cc) # 显式链接gflags目标,代码中直接调用了gflags API target_link_libraries(demo glog::glog gflags::gflags) # 使用target_include_directories替代全局include,避免污染全局路径 target_include_directories(demo PRIVATE ${gflags_BINARY_DIR}/include ${glog_SOURCE_DIR}/src ${glog_BINARY_DIR} )
另外补充两点优化:
- 替换全局
include_directories为target_include_directories,仅给当前目标添加包含路径,符合CMake现代实践。 - 显式添加
gflags::gflags到链接库列表,因为代码直接调用了gflags的API,需要明确依赖关系。
内容的提问来源于stack exchange,提问作者aban
相关产品推荐
相关产品推荐

