Spec-Zone.ru › Bazel 6.1

Функции

Содержание

  • пакет
  • группа пакетов
  • экспортируемые файлы
  • glob
  • select
  • подпакеты

пакет

package(default_deprecation, default_testonly, default_visibility, features)

Эта функция объявляет метаданные, которые применяются к каждой последующей команде в пакете. Она используется не более одного раза в пакете (файл BUILD).

Функция package() должна вызываться сразу после всех инструкций load() в верхней части файла, перед любой командой.

Аргументы

Атрибут Описание
default_visibility

List of labels; optional

По умолчанию, видимость правил в данном пакете.

Каждое правило в этом пакете имеет видимость, указанную в этом атрибуте, если не указано иное в атрибуте visibility правила. Более подробную информацию о синтаксисе этого атрибута см. в документации visibility. По умолчанию, видимость пакета не применяется к экспортируемым файлам.

default_deprecation

String; optional

Устанавливает значение сообщения по умолчанию deprecated для всех правил в этом пакете.

default_testonly

Boolean; optional; default is False except as noted

Устанавливает значение свойства по умолчанию только для тестов для всех правил в этом пакете.

В пакетах под javatests значение по умолчанию равно 1.

features

List strings; optional

Устанавливает различные флаги, которые влияют на семантику этого файла BUILD.

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

Примеры

Объявление ниже указывает, что правила в данном пакете видимы только членам группы пакетов //foo:target. Индивидуальные объявления видимости в правиле, если они присутствуют, переопределяют это указание.
package(default_visibility = ["//foo:target"])

Группа пакетов

package_group(name, packages, includes)

Эта функция определяет набор пакетов и связывает метку с набором. Метка может быть использована в атрибутах visibility.

Группы пакетов в основном используются для управления видимостью. Публичный целевой объект может быть использован в каждом пакете дерева проекта. Закрытый целевой объект может быть использован только в его собственном пакете (не подпакетах). Между этими крайностями цель может разрешить доступ к собственному пакету плюс любой из пакетов, описанных одной или несколькими группами пакетов. Более подробное объяснение системы видимости см. в атрибуте visibility.

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

Группы пакетов технически являются целевыми объектами, но не создаются правилами и сами по себе не имеют защиты видимости.

Аргументы

Атрибут Описание
name

Name; required

Уникальное имя для данного объекта.

packages

List of strings; optional

Список нулевых или более спецификаций пакетов.

Каждая строка спецификации пакета может иметь один из следующих форматов:

  1. Полное имя пакета без репозитория, начинающееся с двойного слеша. Например, //foo/bar указывает пакет с таким именем и который находится в том же репозитории, что и группа пакетов.
  2. Как выше, но с последующим /.... Например, //foo/... указывает набор //foo и всех его подпакетов. //... указывает все пакеты в текущем репозитории.
  3. Строки public или private, которые соответственно указывают все пакеты или ни один пакет. (Этот формат требует флага --incompatible_package_group_has_public_syntax).

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

Группа пакетов содержит любой пакет, который соответствует как минимум одной из его положительных спецификаций и ни одной из отрицательных. Например, значение [//foo/..., -//foo/tests/...] включает все подпакеты //foo , которые также не являются подпакетами //foo/tests. (//foo включается, а //foo/tests – нет.)

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

Если этот атрибут отсутствует, он эквивалентен пустому списку, что также эквивалентно списку, содержащему только private.

Примечание: До Bazel 6.0, спецификация //... имела устаревшее поведение, эквивалентное public. Это поведение исправлено, когда --incompatible_fix_package_group_reporoot_syntax включен, что является значением по умолчанию после Bazel 6.0.

Примечание: До Bazel 6.0, при сериализации этого атрибута как части bazel query --output=proto (или --output=xml), ведущие косые черты опускаются. Например, //pkg/foo/... будет выводиться как \"pkg/foo/...\". Это поведение исправлено, когда --incompatible_package_group_includes_double_slash включен, что является значением по умолчанию после Bazel 6.0.

includes

List of labels; optional

Другие группы пакетов, включенные в эту.

Метки в этом атрибуте должны ссылаться на другие группы пакетов. Пакеты в указанных группах пакетов считаются частью этой группы пакетов. Это транзитивное — если группа пакетов a включает группу пакетов b, и b включает группу пакетов c, то каждый пакет в c также будет членом a.

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

Примеры

Следующее объявление package_group описывает группу пакетов под названием "тропические" , содержащую тропические фрукты.

package_group(
    name = "tropical",
    packages = [
        "//fruits/mango",
        "//fruits/orange",
        "//fruits/papaya/...",
    ],
)

Следующие объявления описывают группы пакетов вымышленного приложения:

package_group(
    name = "fooapp",
    includes = [
        ":controller",
        ":model",
        ":view",
    ],
)

package_group(
    name = "model",
    packages = ["//fooapp/database"],
)

package_group(
    name = "view",
    packages = [
        "//fooapp/swingui",
        "//fooapp/webui",
    ],
)

package_group(
    name = "controller",
    packages = ["//fooapp/algorithm"],
)

Экспортируемые файлы

exports_files([label, ...], visibility, licenses)

exports_files() указывает список файлов, принадлежащих этому пакету, которые экспортируются в другие пакеты.

Файл BUILD пакета может ссылаться непосредственно на исходные файлы, принадлежащие другому пакету, только если они явно экспортированы с помощью инструкции exports_files(). Подробнее о видимости файлов.

В качестве устаревшего поведения, также файлы, упомянутые как входные данные в правило, экспортируются с видимость по умолчанию до тех пор, пока не включен флаг --incompatible_no_implicit_file_export. Однако не следует полагаться на это поведение, и от него следует активно переходить.

Аргументы

Аргумент представляет собой список имен файлов в текущем пакете. Также можно указать объявление видимости; в этом случае файлы будут видны для указанных целей. Если видимость не указана, файлы будут видны каждому пакету, даже если в функции package была указана видимость по умолчанию для пакета. Также можно указать лицензии.

Пример

В следующем примере экспортируется golden.txt, текстовый файл из пакета test_data, чтобы другие пакеты могли использовать его, например, в атрибуте data тестов.

# from //test_data/BUILD

exports_files(["golden.txt"])

glob

glob(include, exclude=[], exclude_directories=1, allow_empty=True)

Glob — вспомогательная функция, которая находит все файлы, соответствующие определенным шаблонам путей, и возвращает новый, изменяемый, отсортированный список их путей. Glob ищет файлы только в собственном пакете и ищет только исходные файлы (не сгенерированные файлы и другие цели).

Метка исходного файла включается в результат, если путь файла, относительный к пакету, соответствует любому из шаблонов в include и ни одному из шаблонов в exclude.

Список include и exclude содержит шаблоны путей, относительные к текущему пакету. Каждый шаблон может состоять из одного или нескольких сегментов пути. Как обычно в Unix путях, эти сегменты разделены /. Сегменты могут содержать символ * подстановочный символ: это соответствует любой подстроке в сегменте пути (даже пустой подстроке), за исключением разделителя каталога /. Этот символ подстановки может использоваться несколько раз в одном сегменте пути. Кроме того, символ ** подстановки может соответствовать нулю или более полным сегментам пути, но он должен быть объявлен как отдельный сегмент пути.

Примеры:
  • foo/bar.txt точно соответствует файлу foo/bar.txt в этом пакете
  • foo/*.txt соответствует каждому файлу в каталоге foo/, если файл заканчивается на .txt (если foo/ не является подпакетом)
  • foo/a*.htm* соответствует каждому файлу в каталоге foo/ который начинается с a, затем имеет произвольную строку (может быть пустой), затем .htm, и заканчивается другой произвольной строкой; например, foo/axx.htm и foo/a.html или foo/axxx.html
  • **/a.txt соответствует каждому файлу a.txt в каждом подкаталоге этого пакета
  • **/bar/**/*.txt соответствует каждому файлу .txt в каждом подкаталоге этого пакета, если хотя бы один каталог на результирующем пути называется bar, например, xxx/bar/yyy/zzz/a.txt или bar/a.txt (пожалуйста, помните, что ** также соответствует нулю сегментам) или bar/zzz/a.txt
  • ** соответствует каждому файлу в каждом подкаталоге этого пакета
  • foo**/a.txt — неверный шаблон, поскольку ** должен стоять сам по себе как сегмент

Если аргумент exclude_directories включен (установлен в 1), файлы типа каталог будут исключены из результатов (по умолчанию 1).

Если аргумент allow_empty установлен в False, функция glob выдаст ошибку, если результат в противном случае будет пустым списком.

Существуют несколько важных ограничений и замечаний:

  1. Так как glob() выполняется во время оценки файла BUILD, glob() соответствует только файлам в вашем дереве исходного кода, никогда не сгенерированным файлам. Если вы создаёте целевой объект, который требует как исходных, так и сгенерированных файлов, вы должны добавить явный список сгенерированных файлов в glob. См. пример ниже с :mylib и :gen_java_srcs.

  2. Если у правила то же имя, что и у сопоставленного исходного файла, правило будет «затенять» файл.

    Чтобы понять это, помните, что glob() возвращает список путей, поэтому использование glob() в атрибуте других правил (например, srcs = glob(["*.cc"])) имеет тот же эффект, что и явное перечисление сопоставленных путей. Если, например, glob() возвращает ["Foo.java", "bar/Baz.java"], но в пакете также есть правило с именем «Foo.java» (что разрешено, хотя Bazel выводит предупреждение об этом), то потребитель glob() будет использовать правило «Foo.java» (его результаты), а не файл «Foo.java». См. GitHub issue #10395 https://github.com/bazelbuild/bazel/issues/10395#issuecomment-583714657 для получения более подробной информации.

  3. Шаблоны могут соответствовать файлам в подкаталогах. Имена подкаталогов могут быть шаблонами.
  4. Метки не могут пересекать границы пакета, и шаблон не находит файлы в подпакетах.

    Например, выражение шаблона **/*.cc в пакете x не включает x/y/z.cc, если x/y существует как пакет (либо как x/y/BUILD, либо где-то ещё в пути пакетов). Это означает, что результат выражения шаблона фактически зависит от наличия файлов BUILD — то есть, то же выражение шаблона включало бы x/y/z.cc, если бы не было пакета под названием x/y или он был помечен как удалённый с помощью флага --deleted_packages.

  5. Вышеуказанное ограничение относится ко всем выражениям шаблонов, независимо от того, какие символы подстановки они используют.
  6. Скрытый файл с именем, начинающимся с ., полностью совпадает как с **, так и с * шаблонами. Если вы хотите сопоставить скрытый файл с составным шаблоном, ваш шаблон должен начинаться со .. Например, * и .*.txt будут соответствовать .foo.txt, но *.txt не будет. Скрытые каталоги также соответствуют аналогичным образом. Скрытые каталоги могут содержать файлы, которые не требуются как входные данные, и могут увеличить количество излишне сопоставленных файлов и потребление памяти. Чтобы исключить скрытые каталоги, добавьте их в аргумент списка исключений.
  7. Символ подстановки «**» имеет один частный случай: шаблон "**" не соответствует пути каталога пакета. То есть, glob(["**"], exclude_directories = 0) соответствует всем файлам и каталогам, строго находящимся в текущем каталоге пакета (но, конечно, не заходя в каталоги подпакетов — см. предыдущее примечание об этом).

В общем случае вы должны попытаться указать соответствующее расширение (например, *.html) вместо использования простого «*» для шаблона. Более явное имя является самодокументирующим и гарантирует, что вы случайно не сопоставите резервные файлы или файлы автосохранения emacs/vi/….

При написании правил сборки вы можете перечислить элементы шаблона. Это позволяет генерировать отдельные правила для каждого входного элемента, например.

См. раздел «расширенный пример шаблона» ниже.

Примеры шаблонов

Создайте библиотеку Java, созданную из всех файлов java в этом каталоге и всех файлов, сгенерированных правилом :gen_java_srcs.

java_library(
    name = "mylib",
    srcs = glob(["*.java"]) + [":gen_java_srcs"],
    deps = "...",
)

genrule(
    name = "gen_java_srcs",
    outs = [
        "Foo.java",
        "Bar.java",
    ],
    ...
)

Включите все файлы txt в каталоге testdata, кроме experimental.txt. Обратите внимание, что файлы в подкаталогах testdata не будут включены. Если вы хотите, чтобы эти файлы были включены, используйте рекурсивный шаблон (**).

sh_test(
    name = "mytest",
    srcs = ["mytest.sh"],
    data = glob(
        ["testdata/*.txt"],
        exclude = ["testdata/experimental.txt"],
    ),
)

Примеры рекурсивных шаблонов

Зависимость теста должна быть от всех файлов txt в каталоге testdata и всех его подкаталогов (и их подкаталогов и так далее). Подкаталоги, содержащие файл BUILD, игнорируются. (См. ограничения и замечания выше).

sh_test(
    name = "mytest",
    srcs = ["mytest.sh"],
    data = glob(["testdata/**/*.txt"]),
)

Создайте библиотеку, созданную из всех файлов java в этом каталоге и всех подкаталогах, за исключением тех, чья структура пути включает каталог с именем testing. Этот шаблон следует избегать, если это возможно, так как он может уменьшить инкрементальность сборки и, следовательно, увеличить время сборки.

java_library(
    name = "mylib",
    srcs = glob(
        ["**/*.java"],
        exclude = ["**/testing/**"],
    ),
)

Примеры расширенных шаблонов

Создайте отдельное правило genrule для *_test.cc в текущем каталоге, которое подсчитывает количество строк в файле.

# Conveniently, the build language supports list comprehensions.
[genrule(
    name = "count_lines_" + f[:-3],  # strip ".cc"
    srcs = [f],
    outs = ["%s-linecount.txt" % f[:-3]],
    cmd = "wc -l $< >$@",
 ) for f in glob(["*_test.cc"])]

Если файл BUILD выше находится в пакете //foo и пакет содержит три соответствующих файла, a_test.cc, b_test.cc и c_test.cc, то запуск bazel query '//foo:all' покажет все сгенерированные правила:

$ bazel query '//foo:all' | sort
//foo:count_lines_a_test
//foo:count_lines_b_test
//foo:count_lines_c_test

select

select(
    {conditionA: valuesA, conditionB: valuesB, ...},
    no_match_error = "custom message"
)

select() — вспомогательная функция, которая делает атрибут правила настраиваемым. Он может заменить правую часть почти любого присваивания атрибута, так что его значение зависит от флагов Bazel, передаваемых по командной строке. Вы можете использовать это, например, для определения зависимостей, специфичных для платформы, или для вставки различных ресурсов в зависимости от того, строится ли правило в режиме «разработчик» или «релиз».

Основное использование:

sh_binary(
    name = "mytarget",
    srcs = select({
        ":conditionA": ["mytarget_a.sh"],
        ":conditionB": ["mytarget_b.sh"],
        "//conditions:default": ["mytarget_default.sh"]
    })
)

Это делает атрибут srcs правила sh_binary настраиваемым, заменяя его обычное присваивание списка меток на вызов select, который сопоставляет условия конфигурации с соответствующими значениями. Каждое условие — ссылка на метку config_setting или constraint_value, которая «соответствует», если конфигурация целевого объекта соответствует ожидаемому набору значений. Тогда значение mytarget#srcs становится тем списком меток, который соответствует текущему вызову.

Примечания:

  • На любом вызове выбирается ровно одно условие.
  • Если несколько условий соответствуют, и одно является специализацией других, то специализация имеет приоритет. Условие B считается специализацией условия A, если B имеет все те же флаги и значения ограничений, что и A, плюс некоторые дополнительные флаги или значения ограничений. Это также означает, что разрешение специализаций не предназначено для создания порядка, как показано в Примере 2 ниже.
  • Если несколько условий соответствуют, и ни одно не является специализацией остальных, Bazel завершается с ошибкой.
  • Специальная псевдометка //conditions:default считается соответствующей, если ни одно другое условие не соответствует. Если это условие отсутствует, какое-то другое правило должно соответствовать, чтобы избежать ошибки.
  • select может быть вставлен внутри более крупного присваивания атрибута. Таким образом, srcs = ["common.sh"] + select({ ":conditionA": ["myrule_a.sh"], ...}) и srcs = select({ ":conditionA": ["a.sh"]}) + select({ ":conditionB": ["b.sh"]}) являются допустимыми выражениями.
  • select работает со многими, но не со всеми, атрибутами. Несовместимые атрибуты помечены nonconfigurable в их документации.
  • подпакеты

    subpackages(include, exclude=[], allow_empty=True)

    subpackages() — вспомогательная функция, аналогичная glob(), которая выводит список подпакетов вместо файлов и каталогов. Она использует те же шаблоны путей, что и glob(), и может соответствовать любому подпакету, являющемуся непосредственным потомком текущего файла BUILD. См. glob для подробного объяснения и примеров шаблонов включения и исключения.

    Полученный отсортированный список подпакетов содержит пути, относящиеся к текущему загружаемому пакету, которые соответствуют заданным шаблонам в include и не соответствуют шаблонам в exclude.

    Пример

    Следующий пример выводит все непосредственные подпакеты для пакета foo/BUILD

    # The following BUILD files exist:
    # foo/BUILD
    # foo/bar/baz/BUILD
    # foo/sub/BUILD
    # foo/sub/deeper/BUILD
    #
    # In foo/BUILD a call to
    subs = subpackages(include = ["**"])
    
    # results in subs == ["sub", "bar/baz"]
    #
    # 'sub/deeper' is not included because it is a subpackage of 'foo/sub' not of
    # 'foo'
    

    В общем случае предпочтительно, чтобы вместо непосредственного вызова этой функции пользователи использовали модуль «subpackages» из skylib.

За исключением случаев, оговорённых в ином порядке, содержимое этой страницы лицензируется в соответствии с лицензией Creative Commons Attribution 4.0, а примеры кода лицензируются в соответствии с лицензией Apache 2.0. Подробности см. в Политике Google для разработчиков. Java — зарегистрированный товарный знак Oracle и/или её аффилированных организаций.

Последнее обновление 2023-03-15 UTC.

Licensed under the Creative Commons Attribution 4.0 License, and code samples are licensed under the Apache 2.0 License.
https://bazel.build/versions/6.1.0/reference/be/functions

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API