Search code examples
bazel

Bazel select() based on build config


I am trying to provide some preprocessor definitions at compile time based on whether the user runs bazel test or bazel build.

Specifically, I want to have a conditional dependency of a cc_library.deps and a conditional definition in cc_library.defines.

I found that select() is the way to go but I cannot figure out how to know what action the user runs.


Solution

  • I'm not aware of any way to detect the current command (build vs test) using select(), but I think you can achieve something similar with custom keys.

    You could define a config_setting block like the following:

    # BUILD
    config_setting(
      name = "custom",
      values = {
        "define": "enable_my_flag=true"
      }
    )
    

    and use it in your library to control the defines:

    # BUILD - continued
    cc_library(
      name = "mylib",
      hdrs = ["mylib.h"],
      srcs = ["mylib.cc"],
      defines = select({
        ":custom": ["MY_FLAG"],
        "//conditions:default": [],
      })
    )
    

    Now building the library using bazel build :mylib will result in the default case - no defines to be present, but if you build using bazel build :mylib --define enable_my_flag=true then the other branch will be selected and MY_FLAG will be defined.

    This can be easily extended to the test case, for example by adding the --define to your .bazelrc:

    # .bazelrc
    test --define enable_my_flag=true
    

    Now every time you run bazel test :mylib_test the define flag will be appended and the library will be built with MY_FLAG defined.

    Out of curiosity why do you want to run the test on a library built with a different set of defines/dependencies? That might defeat the purpose of the test since in the end you're testing something different from the library you're going to use.