I'm trying to conditionally compile a C++ library with bazel depending on if a particular flag is set when building/running one of the target that use the library or the library itself.
My library has something like:
//libraryheader.hpp
#ifdef MY_MACRO
#pragma message("MY_MACRO is defined")
//do something
#else
// do something else
#endif
Here's what I've tried. The BUILD file looks something like
#BUILD
load("@bazel_skylib//rules:common_settings.bzl", "string_flag")
use_the_feature_macro = string_flag(
name = "use_the_feature",
build_setting_default = "",
)
cc_library(
name = "my_library",
testonly = True,
srcs = [
"somefile.cpp",
],
hdrs = [
"libraryheader.hpp",
],
copts = select({
":use_the_feature_macro": ["-DMY_MACRO"],
"//conditions:default": [],
}),
data = [],
visibility = ["//path/to/smth:__subpackages__"],
deps = [
"//path/to/smth:targ1",
...
],
)
When trying to build with a command like bazel build --use_the_feature //path/to:my_library I keep getting errors about the unrecognized option. I've also tried with `bazel build --//path/to:use_feature //path/to:my_library but it doesn't work. Still unrecognised option
ERROR: --use_the_feature :: Unrecognized option: --use_the_feature
What I whish to achieve is to be able to conditionally compile the library both when compiling the library by itself or when compiling a target that uses the library. For now, looking at the bazel documentation I don't know if I should use string_flag or config_setting and the examples on their github are quite difficult to understand.
What you seem to be missing is a
config_settingthat depends on the flag value, which then you can use in yourselect().Here is a complete working example:
Then you can use
bazel build --//:use_the_feature=yes :my_libraryto build with the macro. There's nothing special about the word "yes", you can enable macros one-by-one this way, or you can switch to using abool_flagif you want a single toggle.For completeness, here are the remaining files needed for the build:
MODULE.bazellibraryheader.hppsomefile.cppcan be empty.