Поделиться через


Концепция: функции

Функции

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

По проектированию функции должны соответствовать следующим принципам:

  • Аддитивный: включение функции должно предоставлять новые функциональные возможности в противном случае отсутствуют в пакете без отключения других функций.
  • Неисключаемый: включение функции не должно препятствовать установке других компонентов.

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

Функции могут иметь следующие последствия для зависимостей пакета:

  • Добавьте новые зависимости, включая зависимости от других функций из того же пакета.
  • Включите новые функции для существующих зависимостей.

Набор доступных функций определяется полем"features".

Пример 1. Несколько форматов файлов

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

{
  "name": "my-image-lib",
  "version": "0.1",
  "features": {
    "png": { "description": "Support PNG files", "dependencies": ["libpng"]},
    "jpeg": { "description": "Support JPEG files", "dependencies": ["libjpeg-turbo"]},
    "tiff": { "description": "Support TIFF files", "dependencies": ["libtiff"]},
  }
}

Функции по умолчанию

Функции по умолчанию — это набор функций для автоматической активации, если проект верхнего уровня явно не запрашивает сборку без них. Функции по умолчанию предназначены для обеспечения минимального уровня функциональности независимо от того, насколько сложно и настраивается граф зависимостей проекта.

Примечание.

Функции по умолчанию не предназначены для моделирования "курирования" или "предложений".

Например, рассмотрим библиотеку "extract-any" , которая поддерживает более 10 различных форматов архива, в том числе несколько, которые являются довольно неясными. Так как они являются необязательными, если ни один из них не выбран, библиотека не работает: она не может извлекать файлы.

Функции по умолчанию гарантируют, что пользователь, который просто добавляет "extract-any" в список зависимостей в их vcpkg.json работе, получит базовый уровень функциональности, например автоматически выбирать .zip и .tar.gz декомпрессоры.

Пример 2. Функции по умолчанию в действии

При добавлении "extract-any"vcpkg.json пользователем функций без указания функций функции по умолчанию (например, поддержка .zip и .tar.gz форматы) автоматически включаются, обеспечивая основные функциональные возможности.

{
  "name": "my-application",
  "version": "0.15.2",
  "dependencies": [
    "extract-any"
  ]
}

Если пользователь хочет явно отключить функции по умолчанию, он может сделать это, добавив "default-features": false в зависимость:

{
  "name": "my-application",
  "version": "0.15.2",
  "dependencies": [
    {
      "name": "extract-any",
      "default-features": false
    }
  ]
}

Кроме того, при использовании vcpkg в классическом режиме можно отключить функции по умолчанию с помощью core функции. Например, vcpkg install extract-any[core] устанавливается extract-any без каких-либо компонентов по умолчанию, так как [core] явным образом исключает их.

Дополнительные сведения проверка см. в статье о функциях по умолчанию.

Разрешение зависимостей

При использовании vcpkg разрешение зависимостей играет важную роль, особенно при работе с функциями, имеющими взаимозависимости. Чтобы проиллюстрировать, рассмотрим следующий сценарий, включающий библиотеку обработки изображений:

{
  "name": "my-image-lib",
  "version": "0.1",
  "features": {
    "png": { "description": "Support PNG files", "dependencies": ["libpng"]},
    "jpeg": { "description": "Support JPEG files", "dependencies": ["libjpeg-turbo"]},
    "tiff": { "description": "Support TIFF files", "dependencies": ["libtiff"]},
  }
}

В сценариях, когда различные библиотеки зависят от различных функций общей библиотеки, vcpkg гарантирует, что рассматриваются все необходимые функции и зависимости. Например, если library-a требуется png функция и library-b требуется jpeg эта функцияmy-image-lib, граф зависимостей будет выглядеть следующим образом:

{
  "name": "library-a",
  "version": "1",
  "dependencies": [{"name": "my-image-lib", "features": ["png"]}]
}
{
  "name": "library-b",
  "version": "1",
  "dependencies": [{"name": "my-image-lib", "features": ["jpeg"]}]
}
{
  "name": "project-using-a-and-b",
  "version": "1",
  "dependencies": [
    "library-a",
    "library-b"
  ]
}

При разрешении этих зависимостей vcpkg объединяет все необходимые функции и зависимости для формирования комплексного плана установки. В этом примере проект в зависимости от обоих library-a и library-b приведет к плану установки, включающем оба PNG варианта и JPEG поддержку my-image-lib, но не TIFF:

libjpeg-turbo[core]
libpng[core]
library-a[core]
library-b[core]
my-image-lib[core,png,jpeg]

Этот механизм гарантирует, что сборка my-image-lib оптимизирована для необходимых функций, обеспечивая поддержку PNG и JPEG при этом исключая ненужную TIFF поддержку.

Расширенное использование

Если один репозиторий содержит несколько отдельных компонентов сборки, таких как клиентские и серверные приложения с общим кодом, разработчики каждого фрагмента могут избежать установки дорогостоящих зависимостей, необходимых другим частям.

{
  "name": "my-game",
  "dependencies": ["grpc"],
  "features": {
    "client": { "description": "Client Game Executable", "dependencies": ["sdl2", "bullet3"]},
    "server": { "description": "Multiplayer Server Executable", "dependencies": ["proxygen"]},
    "tests": { "description": "Build tests", "dependencies": ["gtest"] }
  }
}

Затем отдельные разработчики могут выбрать компоненты для установки:

Дополнительные сведения см. в следующих разделах: