Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the proper way to optionally compile a library with a build flag (to place in `target_compatible_with`)?

Suppose I have a library implementation that I only want to compile when the user specifies it at build time.

Should I use the features flag?

If so, how could I use the features flag to constrain compilation like you can with target_compatible_with in cc_library, cc_test, and cc_binary?

If not, what is the best way to constrain this? Adjusting the platforms flag disturbs default platform detection.

like image 630
Robbie Avatar asked Sep 04 '25 16:09

Robbie


2 Answers

Sounds like you want a user-defined build setting that is a command-line flag. The easiest way is to use one of the common build settings rules, and instantiate it in a BUILD file (call it flags/BUILD for this example):

load("@bazel_skylib//rules:common_settings.bzl", "bool_flag")
bool_flag(
    name = "flag",
    build_setting_default = False,
    visibility = ["//visibility:public"],
)

Then you can set it from the command line with --//flags:flag. If you want a less ugly syntax, build setting aliases are also available.

Once you have something which can trigger a config_setting, making an optional library is pretty straightforwards. First you want to disable the library itself when the flag isn't set:

config_setting(
    name = "have_flag",
    flag_values = {
        "//flags:flag": "true",
    },
)

cc_library(
    name = "sometimes",
    target_compatible_with = select({
        ":have_flag": [],
        "//conditions:default": ["@platforms//:incompatible"],
    }),
)

Anything marked as requiring @platforms//:incompatible will never be compatible with any real platform, so this will skip the library when you bazel build //... without the flag and make it an error for anything to depend on it.

I'm guessing you have other targets that depend on this library when enabled, which can be handled similarly:

cc_binary(
    name = "thing",
    deps = [
        "//:something_else",
    ] + select({
        ":have_flag": [":sometimes"],
        "//conditions:default": [],
    }),
)

If you want to define a preprocessor macro to tell the dependent code whether to use the optional dependency (or swap out source files, or change link options, etc), then you can use select like that for copts, defines, srcs, and most of the other cc_library/cc_binary attributes.

like image 86
Brian Silverman Avatar answered Sep 07 '25 09:09

Brian Silverman


Make use of the tag manual, e.g.:

cc_test(name = "my_test"
        ...
        tags = ["manual"]
)
like image 41
Vertexwahn Avatar answered Sep 07 '25 11:09

Vertexwahn



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!