【问题标题】:Failure compiling glog with gflags support using Bazel使用 Bazel 使用 gflags 支持编译 glog 失败
【发布时间】:2017-07-09 22:32:25
【问题描述】:

当我尝试使用 Bazel 编译带有 gflags 支持的 glog 时失败了。重现此问题并显示编译错误消息的 github 存储库在这里:https://github.com/dionescu/bazeltrunk.git

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

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

【问题讨论】:

    标签: bazel glog gflags


    【解决方案1】:

    问题在于 gflag 的 BUILD 文件包含它自己的配置。将 -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
    ...
    

    所以没有定义任何东西。

    选项:

    最简单的方法可能是在你的 glog.BUILD 中生成 config.h:

    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",
            ...
    

    这会将 .h 文件置于比 gflags 版本更高的优先级位置。

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

    genrule(
        name = "config",
        outs = ["config.h"],
        cmd = "cp $(location @//third_party/glog:config.h) $@",
        srcs = ["@//third_party/glog:config.h"],
    )
    

    您还必须将exports_files(['config.h']) 添加到third_party/glog/BUILD 文件中。

    【讨论】:

    • 谢谢,克里斯蒂娜!我仍然不明白为什么 glogs 的 config.h 文件对 glog 是可见的。 gflags cc 库规则有 include = ["include/"],它的 config.h 不在 "include/" 目录中,所以我不希望它对其他第三方包可见。相反,我希望 glog 能够找到并使用我在 glog.BUILD ("//external:glog_config") 中提供的配置。如果 repo 中每个第三方库的每个配置都对所有其他 third_party 库可见,那么我们就会一团糟。那么我在这里错过了什么?
    • cc_library 文档提到“.cc 文件的编译可能会在传递 deps 闭包中传递地包含任何 cc_library 中的 hdrs 或 srcs 中的任何头文件。”所以也许这就是为什么 glog 可以看到 gflags 配置文件的原因?使用 deps 来指定配置是不好的做法,因为您不能保证优先于其他 3p 库中的配置文件?
    • includes 是关于 Bazel 在命令行上生成的 -I 路径,它不会影响暴露的文件。 gflag 的 config.h 是由构建规则生成的,因此它最终位于 bazel-genfiles/external/com_github_gflags_gflags/config.h 中。因为您依赖于来自@com_github_gflags_gflags 的任何内容,所以genfiles/external/com_github_gflags_gflags 被添加到-I 路径中(因此您可以从该存储库的根目录中引用包含)。并且 config.h 在 :gflags 目标的源中,所以如果它在沙箱中可用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-10
    • 1970-01-01
    • 2014-06-28
    • 2011-11-30
    • 2010-12-01
    相关资源
    最近更新 更多