Search code examples
bazel

conditional new_local_library in Bazel WORKSPACE


I've got some pre-built 3rd party libraries that I have to include in my Bazel build. So I have something like this in my WORKSPACE:

new_local_repository(
   name = "thirdparty",
   path = ".install/OSX/DEBUG",
   build_file = "bazel/BUILD.third_party",
)

And the BUILD.third_party looks like:

cc_library(
    name = "glog",
    srcs = ["glog/0.3.5.r1/lib/libglog.a"],
    hdrs = glob([
       "glog/0.3.5.r1/include/**"
    ]),
   visibility = ["//visibility:public"],
   includes = [
      "glog/0.3.5.r1/include"
   ]
)

The issue is that the OSX/DEBUG part of the path in the new_local_repository rule needs to depend on the current platform and the compilation_mode (e.g. I want to link in a release build of glog if the compilation_mode == opt). However, as I understanding the new_local_repository rule must be evaluated during the loading phase and the command line options and other configuration information isn't available at that point. Similarly select expressions aren't available in WORKSPACE files. Is there any way to do this?

Edit

I found a way that should work but there appears to be a bug in Bazel. Here's my bug report: https://github.com/bazelbuild/bazel/issues/10400


Solution

  • You can do that by flipping it around: write separate new_local_repository rules and a select where they're used.

    For example, two repositories in WORKSPACE, with the same build_file:

    new_local_repository(
       name = "thirdparty_debug",
       path = ".install/OSX/DEBUG",
       build_file = "bazel/BUILD.third_party",
    )
    new_local_repository(
       name = "thirdparty_release",
       path = ".install/OSX/RELEASE",
       build_file = "bazel/BUILD.third_party",
    )
    

    Then, use an additional "forwarding" library which depends on relevant library in the appropriate repository. Like this:

    cc_library(
        name = "glog",
        deps = select({
            "a_config_setting_for_opt": ["@thirdparty_release//:glog"],
            "//conditions:default": ["@thirdparty_debug//:glog"],
        }),
        visibility = ["//visibility:public"],
    )
    

    BUILD.third_party could look the same as your example. It might be worth restricting the visibility to only the forwarding target's package to avoid accidental direct dependencies though.