Spec-Zone.ru › Bazel 6.3

Функции

Содержание

  • package
  • группа_пакетов
  • exports_files
  • glob
  • select
  • подпакеты

package

package(default_deprecation, default_testonly, default_visibility, features)

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

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

Аргументы

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

List of labels; optional

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

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

default_deprecation

String; optional

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

default_testonly

Boolean; optional; default is False except as noted

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

В пакетах под 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 объявление определяет группу пакетов под названием "tropical", содержащую тропические фрукты.

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. Также можно указать licenses.

Пример

Следующий пример экспортирует 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 GitHub issue #10395 для получения дополнительной информации.

  3. Глобы могут соответствовать файлам в подкаталогах. И имена подкаталогов могут быть шаблонами. Однако...
  4. Метки не допускаются через границу пакета, и glob не соответствует файлам в подпакетах.

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

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

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

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

Примеры Glob

Создать 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 не будут включены. Если вы хотите включить эти файлы, используйте рекурсивный glob (**).

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

Примеры рекурсивных Glob

Заставить тест зависеть от всех 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/**"],
    ),
)

Примеры расширенных Glob

Создать отдельное 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-07-25 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.3.0/reference/be/functions

Spec-Zone.ru

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