Przeczytaj w języku angielskim

Udostępnij za pośrednictwem


Koncepcja: funkcje

Funkcje

Funkcje reprezentują zestawy funkcji, zachowania i zależności, które można selektywnie dodać do pakietu lub projektu podczas instalacji.

Zgodnie z projektem funkcje powinny być zgodne z następującymi zasadami:

  • Addytywne: włączenie funkcji powinno spowodować brak nowej funkcjonalności w przeciwnym razie w pakiecie bez wyłączania innych funkcji.
  • Nie wykluczające się: włączenie funkcji nie powinno uniemożliwiać instalowania innych funkcji.

Funkcje nie powinny być używane do definiowania alternatywnych zestawów funkcji. Na przykład biblioteka grafiki nie powinna używać funkcji do wyboru między ekskluzywnymi zapleczami grafiki, ponieważ nie jest możliwe zainstalowanie wszystkich z nich w tym samym czasie.

Funkcje mogą mieć następujący wpływ na zależności pakietu:

  • Dodaj nowe zależności, w tym zależności od innych funkcji z tego samego pakietu.
  • Włącz nowe funkcje na istniejących zależnościach.

Zestaw dostępnych funkcji jest definiowany "features" przez pole .

Przykład 1. Wiele formatów plików

Biblioteka manipulowania obrazami może na przykład obsługiwać kilka różnych typów obrazów w zależności od różnych zestawów innych bibliotek.

{
  "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"]},
  }
}

Funkcje domyślne

Funkcje domyślne to zestaw funkcji do automatycznego aktywowania, jeśli projekt najwyższego poziomu nie zażąda jawnie kompilacji bez nich. Funkcje domyślne mają zapewnić minimalny poziom funkcjonalności niezależnie od tego, jak złożony i dostosowywalny jest wykres zależności projektu.

Uwaga

Funkcje domyślne nie są przeznaczone do modelowania "curation" ani "sugestii".

Rozważmy na przykład bibliotekę "extract-any" , która obsługuje ponad 10 różnych formatów archiwum, w tym kilka, które są dość niejasne. Ponieważ wszystkie są opcjonalne, jeśli żadna z nich nie jest wybrana, biblioteka nie jest funkcjonalna: nie może wyodrębnić żadnych plików.

Funkcje domyślne zapewniają, że użytkownik, który po prostu dodaje "extract-any" się do listy zależności w swoich vcpkg.json aplikacjach, uzyska poziom podstawowej funkcjonalności, na przykład automatycznie wybierając .zip i .tar.gz dekompresory.

Przykład 2. Domyślne funkcje w działaniu

Gdy użytkownik dodaje "extract-any" się do nich vcpkg.json bez określania funkcji, funkcje domyślne (np. obsługa .zip i .tar.gz formaty) są automatycznie uwzględniane, zapewniając podstawowe funkcje.

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

Jeśli użytkownik chce jawnie wyłączyć funkcje domyślne, może to zrobić, dodając "default-features": false do zależności:

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

Alternatywnie, jeśli używasz narzędzia vcpkg w trybie klasycznym, możesz wyłączyć funkcje domyślne za pośrednictwem core funkcji. Na przykład vcpkg install extract-any[core] instaluje extract-any się bez żadnych domyślnych funkcji, ponieważ [core] jawnie je wyklucza.

Aby uzyskać więcej informacji, zapoznaj się z artykułem dotyczącym funkcji domyślnych.

Rozwiązywanie zależności

W przypadku korzystania z narzędzia vcpkg rozpoznawanie zależności odgrywa kluczową rolę, zwłaszcza w przypadku pracy z funkcjami, które mają współzależności. Aby zilustrować, rozważmy następujący scenariusz obejmujący bibliotekę manipulowania obrazami:

{
  "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"]},
  }
}

W scenariuszach, w których różne biblioteki zależą od różnych funkcji wspólnej biblioteki, program vcpkg zapewnia, że wszystkie wymagane funkcje i zależności są brane pod uwagę. Jeśli na przykład library-a wymaga png funkcji i library-b wymaga jpeg funkcji z my-image-libprogramu , graf zależności będzie wyglądać następująco:

{
  "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"
  ]
}

Po rozwiązaniu tych zależności program vcpkg łączy wszystkie niezbędne funkcje i zależności w celu utworzenia kompleksowego planu instalacji. W tym przykładzie projekt jest zależny od library-a library-b planu instalacji, który obejmuje zarówno PNG program , jak i JPEG obsługę programu my-image-lib, ale nie TIFF:

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

Ten mechanizm zapewnia, że kompilacja my-image-lib programu jest zoptymalizowana pod kątem wymaganych funkcji, zapewniając obsługę PNG i JPEG jednocześnie wykluczając niepotrzebne TIFF wsparcie.

Użycie zaawansowane

Gdy pojedyncze repozytorium zawiera kilka oddzielnych składników do kompilacji, takich jak aplikacje klienckie i serwerowe z kodem udostępnionym, deweloperzy każdego elementu mogą chcieć uniknąć instalowania kosztownych zależności wymaganych przez inne elementy.

{
  "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"] }
  }
}

Następnie indywidualni deweloperzy mogą wybrać funkcje do zainstalowania:

Aby uzyskać więcej informacji, zobacz następujące zasoby: