Spec-Zone.ru › Bazel 6.4

Функции

Содержание

  • 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

Устанавливает значение по умолчанию для 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

Группы пакетов в первую очередь используются для управления видимостью. Публично видимая цель может быть использована в любом пакете в дереве исходных кодов. Приватно видимая цель может быть использована только в рамках своего собственного пакета (не подпакетов). Между этими крайностями, цель может разрешить доступ к своему пакету плюс любым из пакетов, описанных одним или несколькими группами пакетов. Более подробное объяснение системы видимости см. в атрибуте 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 https://github.com/bazelbuild/bazel/issues/10395#issuecomment-583714657 для получения более подробной информации.

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

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 Developers. Java является зарегистрированным товарным знаком Oracle и/или её дочерних компаний.

Последнее обновление 2023-10-20 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.4.0/reference/be/functions

Spec-Zone.ru

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