CMake复用Bazel构建的glog/gflags依赖时编译报错,如何解决?
问题描述
我有一个基于Bazel的简单项目,使用glog(依赖gflags),执行bazel build main可以成功构建二进制文件。现在想在CMake项目中复用Bazel构建生成的glog和gflags的头文件与库文件,但直接引入Bazel构建输出的虚拟头文件目录后出现编译错误。
Bazel项目代码
WORKSPACE文件
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") http_archive( name = "com_github_gflags_gflags", sha256 = "34af2f15cf7367513b352bdcd2493ab14ce43692d2dcd9dfc499492966c64dcf", strip_prefix = "gflags-2.2.2", urls = ["https://github.com/gflags/gflags/archive/v2.2.2.tar.gz"], ) http_archive( name = "com_github_google_glog", sha256 = "122fb6b712808ef43fbf80f75c52a21c9760683dae470154f02bddfc61135022", strip_prefix = "glog-0.6.0", urls = ["https://github.com/google/glog/archive/v0.6.0.zip"], )
BUILD文件
cc_binary( name = "main", srcs = ["main.cpp"], deps = [ "@com_github_google_glog//:glog", ] )
main.cpp文件
#include <glog/logging.h> int main() { LOG(INFO) << "Hello, World!"; return 0; }
CMake尝试代码
cmake_minimum_required(VERSION 3.20) project(btest) set(CMAKE_CXX_STANDARD 14) include_directories(/path/to/bazel-out/darwin-fastbuild/bin/external/com_github_google_glog/_virtual_includes/glog) include_directories(/path/to/bazel-out/darwin-fastbuild/bin/external/com_github_gflags_gflags/_virtual_includes/gflags) add_executable(main main.cpp)
编译报错信息
In file included from ../main.cpp:1: /path/to/bazel-out/darwin-fastbuild/bin/external/com_github_google_glog/_virtual_includes/glog/glog/logging.h:122:17: error: incomplete type in call to object of type 'struct GLOG_EXPORT' LogMessageTime();
解决方法
1. 放弃使用Bazel虚拟头文件目录
Bazel生成的_virtual_includes目录是为自身构建流程设计的,里面的头文件经过预处理,缺失完整的类型定义,直接给CMake使用必然导致编译错误。必须改用原始依赖源码的头文件和Bazel编译产出的库文件。
2. 提取正确的头文件与库文件
- 头文件:从Bazel下载的依赖源码目录获取,默认路径为
bazel-<你的项目名>/external/com_github_google_glog/src和bazel-<你的项目名>/external/com_github_gflags_gflags/src。 - 库文件:Bazel编译好的静态/动态库位于
bazel-out/darwin-fastbuild/bin/external/com_github_google_glog/libglog.a(或.dylib/.so)、bazel-out/darwin-fastbuild/bin/external/com_github_gflags_gflags/libgflags.a路径下。
3. 修改CMakeLists.txt
调整后的CMake配置如下:
cmake_minimum_required(VERSION 3.20) project(btest) set(CMAKE_CXX_STANDARD 14) # 添加原始依赖的头文件目录 include_directories(/path/to/bazel-<你的项目名>/external/com_github_google_glog/src) include_directories(/path/to/bazel-<你的项目名>/external/com_github_gflags_gflags/src) # 链接Bazel编译好的库文件 add_executable(main main.cpp) target_link_libraries(main /path/to/bazel-out/darwin-fastbuild/bin/external/com_github_google_glog/libglog.a /path/to/bazel-out/darwin-fastbuild/bin/external/com_github_gflags_gflags/libgflags.a )
4. 更便捷的替代方案:用Bazel生成CMake导入配置
如果不想手动复制文件,可以借助Bazel规则生成CMake可识别的导入文件:
- 在Bazel的BUILD文件中加载相关规则,添加
cmake_export_all_build_files()配置,或使用@rules_foreign_cc//tools:cmake.bzl工具导出依赖。 - 执行
bazel build @com_github_google_glog//:glog_cmake_export(具体目标名需根据规则调整)生成CMake配置文件,之后在CMake中用find_package()直接导入依赖。
内容的提问来源于stack exchange,提问作者jeffreyveon
相关产品推荐
相关产品推荐

