Search code examples
bazelgloggflags

Failure compiling glog with gflags support using Bazel


I'm getting a failure when I try to compile glog with gflags support using Bazel. A github repo reproducing this problem and showing the compilation error message is here: https://github.com/dionescu/bazeltrunk.git

I suspect that the problem occurs because glog is finding and using the "config.h" file published by gflags. However, I do not understand why this happens and why the current structure of the build files results in such errors. One solution I found was to provide my own BUILD file for gflags where the config was in a separate dependency (just how glog does it in my example).

I would appreciate any help with understanding the issue in this example.


Solution

  • The problem is that gflag's BUILD file is including its own config. Adding -H to glog.BUILD's copts yields:

    . 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
       ^
    

    If you take a look at gflag's config.h, it went with a not-very-helful approach of commenting out most of the config:

    // ---------------------------------------------------------------------------
    // 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
    ...
    

    So nothing is defined.

    Options:

    The easiest way is probably to generate the config.h in your glog.BUILD:

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

    This puts the .h file at a higher-precedence location than the gflags version.

    Alternatively, you could do something like this in the genrule, if you want to use your //third_party/glog/config.h (@// is shorthand for your project's repository):

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

    You'll have to add exports_files(['config.h']) to the third_party/glog/BUILD file, too.