使用Bazel使用gflags支持编译glog失败

使用Bazel使用gflags支持编译glog失败,bazel,glog,gflags,Bazel,Glog,Gflags,当我尝试使用Bazel编译带有gflags支持的glog时,我失败了。再现此问题并显示编译错误消息的github repo如下所示: 我怀疑出现问题是因为glog正在查找并使用gflags发布的“config.h”文件。但是,我不理解为什么会发生这种情况,以及为什么构建文件的当前结构会导致此类错误。我发现的一个解决方案是为gflags提供我自己的构建文件,其中配置位于单独的依赖项中(在我的示例中,glog就是这样做的) 如果您能帮助我理解本例中的问题,我将不胜感激。问题在于gflag的构建文件包

当我尝试使用Bazel编译带有gflags支持的glog时,我失败了。再现此问题并显示编译错误消息的github repo如下所示:

我怀疑出现问题是因为glog正在查找并使用gflags发布的“config.h”文件。但是,我不理解为什么会发生这种情况,以及为什么构建文件的当前结构会导致此类错误。我发现的一个解决方案是为gflags提供我自己的构建文件,其中配置位于单独的依赖项中(在我的示例中,glog就是这样做的)


如果您能帮助我理解本例中的问题,我将不胜感激。

问题在于gflag的构建文件包含了自己的配置文件。将
-H
添加到glog.BUILD的
copts
生成:

. external/glog_archive/src/utilities.h
.. external/glog_archive/src/base/mutex.h
... bazel-out/local-fastbuild/genfiles/external/com_github_gflags_gflags/config.h
In file included from external/glog_archive/src/utilities.h:73:0,
                 from external/glog_archive/src/utilities.cc:32:
external/glog_archive/src/base/mutex.h:147:3: error: #error Need to implement mutex.h for your architecture, or #define NO_THREADS
 # error Need to implement mutex.h for your architecture, or #define NO_THREADS
   ^
如果你看一看gflag的config.h,它使用了一种不太有用的方法来注释大部分配置:

// ---------------------------------------------------------------------------
// System checks

// Define if you build this library for a MS Windows OS.
//cmakedefine OS_WINDOWS

// Define if you have the <stdint.h> header file.
//cmakedefine HAVE_STDINT_H

// Define if you have the <sys/types.h> header file.
//cmakedefine HAVE_SYS_TYPES_H
...
这使.h文件的优先级高于gflags版本

或者,如果您想使用您的
//third\u party/glog/config.h
@/
是项目存储库的缩写),您可以在genrule中执行类似操作:


您还必须将
导出文件(['config.h'])
添加到
第三方/glog/BUILD
文件中。

谢谢,克里斯蒂娜!我仍然不明白的是,为什么gflags的config.h文件对glog是可见的。gflags cc library规则具有includes=[“include/”],其config.h不在“include/”目录中,因此我不希望它对其他第三方软件包可见。相反,我希望glog能够找到并使用我在glog.BUILD(“//external:glog_config”)中给出的配置。如果repo中每个第三方库的每个配置对所有其他第三方库都是可见的,那么我们将陷入混乱。那么,我在这里遗漏了什么呢?cc_库文档提到,“编译.cc文件可能会在可传递的deps闭包中包含hdrs中的任何头文件或任何cc_库中的任何SRC。”因此,也许这就是glog可以看到gflags配置文件的原因?使用deps指定配置是错误的做法,因为无法保证优先于其他3p库中的配置文件?
includes
是关于Bazel在命令行上生成的-I路径,它不会影响公开的文件。gflag的config.h是由构建规则生成的,因此它最终位于bazel genfiles/external/com\u github\u gflags\u gflags/config.h中。因为您依赖于
@com\u github\u gflags\u gflags
中的任何内容,
genfiles/external/com\u github\u gflags\u gflags
被添加到
-I
路径中(因此您可以从该存储库的根目录中引用include)。而config.h位于
:gflags
目标的源代码中,因此如果它在沙箱中可用。
genrule(
    name = "config",
    outs = ["config.h"],
    cmd = "cd external/glog_archive; ./configure; cd ../..; cp external/glog_archive/src/config.h $@",
    srcs = glob(["**"]),
)

# Then add the generated config to your glog target.
cc_library(
    name = "glog",
    srcs = [...],
    hdrs = [
        ":config.h",
        ...
genrule(
    name = "config",
    outs = ["config.h"],
    cmd = "cp $(location @//third_party/glog:config.h) $@",
    srcs = ["@//third_party/glog:config.h"],
)