Spec-Zone.ru › Bazel 7.0

Функции

Содержание

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

package

package(default_deprecation, default_package_metadata, default_testonly, default_visibility, features)

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

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

Аргументы

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

Псевдоним для default_package_metadata.

default_visibility

Список меток; значение по умолчанию []

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

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

default_deprecation

Строка; значение по умолчанию ""

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

default_package_metadata

Список меток; значение по умолчанию []

Устанавливает список целевых объектов метаданных по умолчанию, которые применяются ко всем другим целевым объектам в пакете. Обычно это целевые объекты, связанные с объявлением пакетов и лицензий с открытым исходным кодом. См. rules_license для примеров.

default_testonly

Булево значение; значение по умолчанию False за исключением случаев, когда указано иначе

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

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

features

Список строк; значение по умолчанию []

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

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

Примеры

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

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

package_group(name, packages, includes)

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

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

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

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

Аргументы

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

Имя; обязательно

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

packages

Список строк; значение по умолчанию []

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

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

  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

Список меток; значение по умолчанию []

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

Метки в этом атрибуте должны ссылаться на другие группы пакетов. Пакеты в ссылках на группы пакетов считаются частью этой группы пакетов. Это транзитивно — если группа пакетов 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

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 для получения дополнительной информации.

  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 не будет. Скрытые каталоги также соответствуют этому же способу. Скрытые каталоги могут содержать файлы, которые не требуются в качестве входных данных, и могут увеличить количество ненужных файлов, сопоставленных glob, и потребление памяти. Чтобы исключить скрытые каталоги, добавьте их в аргумент списка «исключение».
  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-12-11 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/7.0.0/reference/be/functions

Spec-Zone.ru

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