Spec-Zone.ru › Bazel 6.0

Функции

Содержание

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

package

package(default_deprecation, default_testonly, default_visibility, features)

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

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

Аргументы

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

List of labels; optional

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

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

default_deprecation

String; optional

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

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

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

Конкретный пакет считается частью группы, если он соответствует атрибуту 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 #10395 GitHub issue #10395 для получения более подробной информации.

  3. Glob может соответствовать файлам в подкаталогах. А имена подкаталогов могут использовать шаблоны. Однако...
  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 не будет. Скрытые каталоги также сопоставляются аналогичным образом. Скрытые каталоги могут содержать файлы, которые не требуются в качестве входных данных, и могут увеличить количество ненужных файлов, сопоставленных с glob, и потребление памяти. Чтобы исключить скрытые каталоги, добавьте их в аргумент списка «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 и/или её дочерних компаний.

Последнее обновление 2022-12-19 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.0.0/reference/be/functions

Spec-Zone.ru

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