Каков правильный способ необязательной компиляции библиотеки с флагом сборки (для размещения в «target_compatible_with»)?

#c #build #bazel #bazel-rules

Вопрос:

Предположим, у меня есть реализация библиотеки, которую я хочу скомпилировать только тогда, когда пользователь укажет ее во время сборки.

Должен ли я использовать features флаг?

Если да, то как я могу использовать флаг функций для ограничения компиляции, как это можно сделать с target_compatible_with помощью in cc_library , cc_test , и cc_binary ?

Если нет, то как лучше всего это ограничить? Настройка platforms флага нарушает обнаружение платформы по умолчанию.

Ответ №1:

Похоже, вам нужен пользовательский параметр сборки, который является флагом командной строки. Самый простой способ-использовать одно из общих правил настройки сборки и создать его экземпляр в файле СБОРКИ (назовите его flags/BUILD в этом примере).:

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

Затем вы можете установить его из командной строки с --//flags:flag помощью . Если вам нужен менее уродливый синтаксис, также доступны псевдонимы параметров сборки.

Как только у вас есть что-то, что может вызвать настройку конфигурации, создание дополнительной библиотеки довольно просто. Сначала вы хотите отключить саму библиотеку, если флаг не установлен:

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

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

Все, что помечено как требующее @platforms//:incompatible , никогда не будет совместимо с какой-либо реальной платформой, поэтому при bazel build //... отсутствии флага библиотека будет пропущена, и это приведет к ошибке, если что-либо будет зависеть от нее.

Я предполагаю, что у вас есть другие цели, которые зависят от этой библиотеки, когда она включена, и с которыми можно обращаться аналогичным образом:

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

Если вы хотите определить макрос препроцессора, чтобы указать зависимому коду, следует ли использовать необязательную зависимость (или поменять местами исходные файлы, или изменить параметры ссылок и т. Д.), То вы можете использовать select это для copts , defines , srcs , и большинства других cc_library cc_binary атрибутов/.

Ответ №2:

Используйте тег manual , например:

 cc_test(name = "my_test"
        ...
        tags = ["manual"]
)