Spec-Zone.ru › Bazel 6.2

Функции

Содержание

  • 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

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

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 объявляет группу пакетов под названием «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. Также могут быть указаны лицензии.

Пример

В следующем примере экспортируется 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 путях, эти сегменты разделены /. Сегменты могут содержать символ * подстановки: это соответствует любому подстроке в сегменте пути (включая пустую подстроку), за исключением разделителя каталогов /. Этот символ подстановки может использоваться несколько раз в одном сегменте пути. Кроме того, символ подстановки ** может соответствовать нулю или более полным сегментам пути, но он должен быть объявлен как самостоятельный сегмент пути.

Примеры:
END_OF_DOCUMENT_MARKER
  • 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 для получения более подробной информации.

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

    Например, выражение шаблона **/*.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) вместо использования просто «*» для шаблона 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 для разработчиков. Java — зарегистрированный товарный знак Oracle и/или её дочерних компаний.

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

Spec-Zone.ru

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