Udostępnij za pośrednictwem


Przewodnik obsługi

W tym dokumencie wymieniono zestaw zasad, które należy zastosować podczas dodawania lub aktualizowania przepisu portu. Ma ona służyć roli podręcznika zasad Debiana, wytycznych konserwatora Homebrew i podręcznika homebrew formuły.

Ogólne cele projektowania rejestru

Porty w bieżącym punkcie odniesienia muszą być instalowane jednocześnie

Chcemy pokazać podrzędnym użytkownikom bibliotek w wyselekcjonowanym rejestrze, że kombinacja bibliotek w danym punkcie odniesienia, które publikujemy, została przetestowana pod kątem współpracy w co najmniej niektórych konfiguracjach. Zezwolenie na wykluczanie portów wzajemnie przerywa możliwość testowania takich konfiguracji, ponieważ liczba kompilacji niezbędnych do takich testów wzrośnie jako 2^number_of_such_cases. Ponadto instalowanie dodatkowych zależności jest zawsze uznawane za "bezpieczne": nie ma możliwości, aby port lub użytkownik końcowy stwierdził, że zależność nie jest zainstalowana w ich wymaganiach.

Jeśli chcesz przedstawić taką alternatywną sytuację dla użytkowników, rozważ opisanie sposobu, w jaki ktoś może utworzyć port nakładki implementujący alternatywny formularz z komentarzem portfile.cmake , zamiast dodawać dodatkowe porty nigdy nie wbudowane w ciągłą integrację rejestru nadzorowanego. Zobacz na przykład glad@0.1.36.

Przed wprowadzeniem rejestrów zaakceptowaliśmy kilka nietestowanych portów jako alternatyw, takich jak boringssl, które mogłyby ułatwić tworzenie portów nakładki. Nie jest to już akceptowane, ponieważ rejestry zezwalają na publikowanie tych nietestowanych portów bez modyfikowania nadzorowanego rejestru.

Struktura żądania ściągnięcia

Wprowadzanie oddzielnych żądań ściągnięcia na port

Jeśli to możliwe, należy oddzielić zmiany w wielu żądaniach ściągnięcia. Ułatwia to ich przegląd i zapobiega problemom z jednym zestawem zmian wstrzymywania każdej innej zmiany.

Unikaj trywialnych zmian w nietkniętych plikach

Na przykład należy unikać ponownego formatowania lub zmieniania nazw zmiennych w plikach portowych, które w przeciwnym razie nie mają powodu modyfikacji problemu. Jeśli jednak musisz zmodyfikować plik w podstawowym celu żądania ściągnięcia (aktualizowanie biblioteki), oczywiście korzystne zmiany, takie jak naprawianie literówek, są doceniane!

Sprawdzanie nazw w innych repozytoriach

Nazwy portów powinny podjąć próbę jednoznacznego określenia pakietu instalowanego przez port. W idealnym przypadku wyszukiwanie nazwy portu w wyszukiwarce powinno szybko prowadzić do odpowiedniego projektu. Dobrą usługą do sprawdzania wielu nazw pakietów w wielu repozytoriach jednocześnie jest Repology.

Projekty z krótkimi nazwami lub nazwane po typowych słowach mogą wymagać uściślania, szczególnie jeśli nie ma projektów z silnym skojarzeniem danego słowa. Na przykład port o nazwie ip nie jest akceptowalny, ponieważ prawdopodobnie wiele projektów będzie nazwanych podobnie.

Przykłady dobrych uściślaczów to:

  • Nazwa użytkownika lub organizacja właściciela repozytorium: google-cloud-cpp.
  • Nazwa zestawu bibliotek projektu jest częścią: boost-dll.

Typowe prefiksy i sufiksy używane przez projekty języka C++ i open source nie są prawidłowymi uściślaczami. Niektóre przykłady obejmują między innymi:

  • cpp,
  • free,
  • lib,
  • open,
  • Liczby

Na przykład podczas porównywania następujących nazw portów: ip-cppi libip ip5 usuwania nieprawidłowych uściślaczów wszystkie są one zredukowane do tej samej ściągnięcia (ip), a tym samym są uważane za takie same nazwy.

Wyjątkiem od tych wytycznych jest nazwa, które są silnie skojarzone z pojedynczym projektem. Na przykład: libpng, openssl i zlib.

Korzystanie z wersji roboczej żądania ściągnięcia w usłudze GitHub

Żądania ściągnięcia wersji roboczej w usłudze GitHub to doskonały sposób na uzyskanie informacji zwrotnych dotyczących ciągłej integracji lub opinii człowieka na temat pracy, która nie jest jeszcze gotowa do scalenia. Większość nowych reguł ściągnięcia powinna być otwierana jako wersje robocze i konwertowana na normalne żądania ściągnięcia po przejściu ciągłej integracji.

Aby uzyskać więcej informacji na temat żądań ściągnięcia wersji roboczej usługi GitHub, zobacz Wprowadzenie do wersji roboczej żądań ściągnięcia.

Pliki portów

Unikaj przestarzałych funkcji pomocnika

Obecnie następujące pomocniki są przestarzałe:

Niektóre funkcje pomocnika zastępczego znajdują się w "portach narzędzi", aby umożliwić konsumentom przypięcie ich zachowania w określonych wersjach, aby umożliwić blokowanie zachowania pomocników w określonej wersji. Porty narzędzi należy dodać do portu "dependencies"w następujący sposób:

{
  "name": "vcpkg-cmake",
  "host": true
},
{
  "name": "vcpkg-cmake-config",
  "host": true
}

Unikaj nadmiernego komentarza w plikach portów

W idealnym przypadku pliki portów powinny być krótkie, proste i jak najbardziej deklaratywne. Usuń wszelkie komentarze płyt kotłowych wprowadzone przez create polecenie przed przesłaniem żądania ściągnięcia.

Porty nie mogą być zależne od ścieżki

Porty nie mogą zmieniać ich zachowania na podstawie tego, które porty są już zainstalowane w postaci, która spowoduje zmianę zawartości instalowanej przez port. Na przykład podane:

> vcpkg install a
> vcpkg install b
> vcpkg remove a

oraz

> vcpkg install b

pliki zainstalowane przez b program muszą być takie same, niezależnie od wpływu poprzedniej ainstalacji programu . Oznacza to, że porty nie mogą próbować wykrywać, czy coś znajduje się w zainstalowanym drzewie przez inny port przed podjęciem pewnych działań. Określoną i typową przyczyną takiego zachowania "zależnego od ścieżki" opisano poniżej w sekcji "Podczas definiowania funkcji jawnie kontrolować zależności".

Unikatowa reguła przypisywania portów

W całym systemie vcpkg nie ma dwóch portów, które użytkownik będzie używać współbieżnie, może dostarczyć ten sam plik. Jeśli port spróbuje zainstalować plik już dostarczony przez inny plik, instalacja zakończy się niepowodzeniem. Jeśli port chce użyć niezwykle pospolitej nazwy nagłówka, na przykład należy umieścić te nagłówki w podkatalogu, a nie w include.

Ta właściwość jest regularnie sprawdzana przez przebiegi ciągłej integracji, które próbują zainstalować wszystkie porty w rejestrze, co zakończy się niepowodzeniem FILE_CONFLICTS , jeśli dwa porty zapewniają ten sam plik.

Dodawanie eksportów narzędzia CMake w nieoficjalnej przestrzeni nazw

Podstawowym rozwiązaniem projektowym vcpkg jest nie tworzenie "blokady" dla użytkowników. W systemie kompilacji nie powinno istnieć różnice między biblioteką z systemu i w zależności od biblioteki z programu vcpkg. W tym celu unikamy dodawania eksportów lub obiektów docelowych CMake do istniejących bibliotek o "oczywistej nazwie", aby umożliwić nadrzędnym dodawanie własnych oficjalnych eksportów CMake bez konfliktu z vcpkg.

W tym celu wszystkie konfiguracje narzędzia CMake, które eksportują porty, które nie znajdują się w bibliotece nadrzędnej, powinny mieć unofficial- prefiks. Wszystkie dodatkowe elementy docelowe powinny znajdować się w unofficial::<port>:: przestrzeni nazw.

Oznacza to, że użytkownik powinien zobaczyć:

  • find_package(unofficial-<port> CONFIG) jako sposób uzyskiwania w pakiecie unique-to-vcpkg
  • unofficial::<port>::<target> jako wyeksportowany element docelowy z tego portu.

Przykłady:

  • brotliunofficial-brotli tworzy pakiet, tworząc docelowy unofficial::brotli::brotlielement .

Każdy port musi podać plik o nazwie copyright w folderze ${CURRENT_PACKAGES_DIR}/share/${PORT}. Jeśli zawartość licencji pakietu jest dostępna w jego plikach źródłowych, ten plik powinien zostać utworzony przez wywołanie metody vcpkg_install_copyright(). vcpkg_install_copyright w razie potrzeby zawiera także wiele plików praw autorskich.

vcpkg_install_copyright(FILE_LIST "${SOURCE_PATH}/LICENSE")

Starszą metodą ręcznego tworzenia tego pliku jest wbudowane file polecenie CMake. Jest to odradzane na rzecz vcpkg_install_copyright nowych portów, ale nadal jest dozwolone.

file(INSTALL "${SOURCE_PATH}/LICENSE" DESTINATION "${CURRENT_PACKAGES_DIR}/share/${PORT}" RENAME copyright)

Jeśli zawartość licencji w nadrzędnych plikach źródłowych nie jest w postaci tekstowej (np. pliku PDF), copyright powinna zawierać wyjaśnienie, w jaki sposób użytkownik może znaleźć wymagania licencyjne. Jeśli to możliwe, powinien również zawierać link do oryginalnych plików źródłowych wskazujących to, aby użytkownicy mogli sprawdzić, czy jest aktualna.

file(WRITE "${CURRENT_PACKAGES_DIR}/share/${PORT}/copyright" [[As of 2023-07-25, according to
https://github.com/GPUOpen-LibrariesAndSDKs/display-library/blob/master/Public-Documents/README.md#end-user-license-agreement
this software is bound by the "SOFTWARE DEVELOPMENT KIT LICENSE AGREEMENT" PDF located at
https://github.com/GPUOpen-LibrariesAndSDKs/display-library/blob/master/Public-Documents/ADL%20SDK%20EULA.pdf
]])

Ograniczenia wersji w portach

Należy unikać ograniczeń wersji na portach, ponieważ mogą one utrudniać niezależną ewolucję projektów. Dodanie takich ograniczeń jest dopuszczalne tylko wtedy, gdy istnieje dobrze udokumentowane uzasadnienie, takie jak sprawdzona niezgodność z określonymi wcześniejszymi wersjami. Te ograniczenia nie powinny być wykorzystywane jedynie do utrzymania równoważności z niezależnymi projektami.

Funkcje

Nie używaj funkcji do implementowania alternatyw

Funkcje muszą być traktowane jako funkcje addytywne. W przypadku port[featureA] instalacji i port[featureB] instalacji port[featureA,featureB] należy zainstalować program . Ponadto, jeśli drugi port zależy od i trzeci port zależy od [featureA] [featureB], instalacja zarówno drugiego, jak i trzeciego portu powinna mieć spełnione zależności.

Biblioteki w tej sytuacji muszą wybrać jedną z dostępnych opcji wyrażoną w narzędziu vcpkg, a użytkownicy, którzy chcą innego ustawienia, muszą teraz używać portów nakładki.

Istniejące przykłady nie zostaną dziś zaakceptowane w celu zachowania zgodności z poprzednimi wersjami:

  • libgit2, libzipopen62541 wszystkie mają funkcje do wybierania zaplecza TLS lub kryptografii. curl ma różne opcje zaplecza kryptograficznego, ale umożliwia wybór między nimi w czasie wykonywania, co oznacza, że powyższy zestaw jest utrzymywany.
  • darknet ma opencv2, opencv3funkcje do kontrolowania wersji opencv do użycia dla jego zależności.

Funkcja może korzystać z funkcji w wersji zapoznawczej lub beta

Niezależnie od powyższego, jeśli istnieje gałąź w wersji zapoznawczej lub podobna, w której funkcja w wersji zapoznawczej ma duże prawdopodobieństwo, że nie zakłóca działania funkcji innych niż wersja zapoznawcza (na przykład brak usuwania interfejsu API), funkcja jest akceptowalna do modelowania tego ustawienia.

Przykłady:

  • Zestawy SDK platformy Azure (formularza azure-Xxx) mają public-preview funkcję.
  • imguiexperimental-docking ma funkcję, która angażuje swoją gałąź dokowania w wersji zapoznawczej, która używa zatwierdzenia scalania dołączonego do każdej z ich publicznych numerowanych wersji.

Funkcje domyślne powinny włączać zachowania, a nie interfejsy API

Jeśli użytkownik jest zależny bezpośrednio od biblioteki, może łatwo wyświetlić listę żądanych funkcji (library[feature1,feature2]). Jeśli jednak użytkownik nie wie , że korzysta z biblioteki, nie może wymienić tych funkcji. Jeśli ta ukryta biblioteka jest podobna libarchive do tego, gdzie funkcje dodają dodatkowe algorytmy kompresji (a tym samym zachowania) do istniejącego interfejsu ogólnego, funkcje domyślne oferują sposób zapewnienia, że odpowiednio funkcjonalna biblioteka przechodnia jest tworzona, nawet jeśli końcowy użytkownik nie nazywa go bezpośrednio.

Jeśli funkcja dodaje dodatkowe interfejsy API (lub pliki wykonywalne lub pliki binarne biblioteki) i nie modyfikuje zachowania istniejących interfejsów API, powinno być domyślnie wyłączone. Jest to spowodowane tym, że każdy użytkownik, który może chcieć korzystać z tych interfejsów API, może łatwo wymagać go za pośrednictwem bezpośredniego odwołania.

W razie wątpliwości nie oznaczaj funkcji jako domyślnej.

Nie używaj funkcji do kontrolowania alternatyw w opublikowanych interfejsach

Jeśli użytkownik portu zależy tylko od podstawowych funkcji tego portu, z dużym prawdopodobieństwem nie może zostać przerwany przez włączenie funkcji. Jest to jeszcze ważniejsze, gdy alternatywa nie jest bezpośrednio kontrolowana przez użytkownika, ale przez ustawienia kompilatora, takie jak /std:c++17 / -std=c++17.

Istniejące przykłady nie zostaną dziś zaakceptowane w celu zachowania zgodności z poprzednimi wersjami:

  • redis-plus-plus[cxx17] steruje poliwypełnieniem, ale nie piecze ustawienia w zainstalowanym drzewie.
  • ace[wchar] zmienia wszystkie interfejsy API tak, aby akceptowały const wchar_t* zamiast const char*.

Funkcja może zastąpić polyfills aliasami, pod warunkiem że wymiana jest pieczona w zainstalowanym drzewie

Niezależnie od powyższych, porty mogą usuwać wielowypełnienia z funkcją, o ile:

  1. Włączenie funkcji powoduje zmianę wielowypełnień na aliasy jednostki poliwypełnionej
  2. Stan poliwypełniania jest upieczony w zainstalowanych nagłówkach, tak aby niezgodność ABI błędy środowiska uruchomieniowego "niemożliwe" są mało prawdopodobne
  3. Użytkownik portu może napisać kod, który działa w obu trybach, na przykład przy użyciu definicji typu, która jest poliwypełniana lub nie

Przykład:

  • abseil[cxx17] zmiany absl::string_view w zamiany lub std::string_view; poprawka implementuje wymaganie pieczenia.

Jeśli kluczowe jest uwidocznienie bazowych alternatyw, zalecamy udostępnienie komunikatów w czasie kompilacji, aby poinstruować użytkownika o tym, jak skopiować port do prywatnej nakładki:

set(USING_DOG 0)
message(STATUS "This version of LibContoso uses the Kittens backend. To use the Dog backend instead, create an overlay port of this with USING_DOG set to 1 and the `kittens` dependency replaced with `dog`.")
message(STATUS "This recipe is at ${CMAKE_CURRENT_LIST_DIR}")
message(STATUS "See the overlay ports documentation at https://github.com/microsoft/vcpkg/blob/master/docs/specifications/ports-overlay.md")

Techniki kompilacji

Nie używaj zależności od dostawcy

Nie używaj osadzonych kopii bibliotek. Wszystkie zależności powinny być podzielone i spakowane oddzielnie, aby można je było aktualizować i konserwować.

Preferuj korzystanie z narzędzia CMake

Jeśli dostępnych jest wiele systemów kompilacji, preferuj korzystanie z narzędzia CMake. Ponadto, jeśli jest to konieczne, można łatwiej i bardziej konserwować ponowne zapisywanie alternatywnych systemów kompilacji w narzędziu CMake przy użyciu file(GLOB) dyrektyw.

Przykłady: abseil

Wybieranie plików binarnych statycznych lub udostępnionych

Podczas kompilowania bibliotek vcpkg_cmake_configure() CMake zostanie przekazana poprawna wartość na BUILD_SHARED_LIBS podstawie żądanego wariantu użytkownika.

Możesz obliczyć alternatywne parametry konfiguracji przy użyciu polecenia string(COMPARE EQUAL "${VCPKG_LIBRARY_LINKAGE}" ...).

# portfile.cmake

string(COMPARE EQUAL "${VCPKG_LIBRARY_LINKAGE}" "static" KEYSTONE_BUILD_STATIC)
string(COMPARE EQUAL "${VCPKG_LIBRARY_LINKAGE}" "dynamic" KEYSTONE_BUILD_SHARED)

vcpkg_cmake_configure(
    SOURCE_PATH ${SOURCE_PATH}
    OPTIONS
        -DKEYSTONE_BUILD_STATIC=${KEYSTONE_BUILD_STATIC}
        -DKEYSTONE_BUILD_SHARED=${KEYSTONE_BUILD_SHARED}
)

Jeśli biblioteka nie oferuje opcji konfigurowania w celu wybrania wariantu kompilacji, kompilacja musi zostać poprawiona. Podczas stosowania poprawek do kompilacji należy zawsze próbować zmaksymalizować przyszłą konserwację portu. Zazwyczaj oznacza to zminimalizowanie liczby wierszy, które należy dotknąć, aby rozwiązać problem.

Przykład: stosowanie poprawek biblioteki CMake w celu uniknięcia tworzenia niechcianych wariantów

Na przykład podczas stosowania poprawek biblioteki opartej na narzędziu CMake może wystarczyć dodanie EXCLUDE_FROM_ALL do niechcianych obiektów docelowych i opakowywanie install(TARGETS ...) wywołania w elemecie if(BUILD_SHARED_LIBS). Będzie to krótsze niż zawijanie lub usuwanie każdego wiersza, który wspomina o niechcianym wariantie.

W przypadku projektu CMakeLists.txt z następującą zawartością:

add_library(contoso SHARED contoso.c)
add_library(contoso_static STATIC contoso.c)

install(TARGETS contoso contoso_static EXPORT ContosoTargets)

install(EXPORT ContosoTargets
  FILE ContosoTargets
  NAMESPACE contoso::
  DESTINATION share/contoso)

install(TARGETS) Tylko wiersz musi zostać poprawiony.

add_library(contoso SHARED contoso.c)
add_library(contoso_static STATIC contoso.c)

if(BUILD_SHARED_LIBS)
  set_target_properties(contoso_static PROPERTIES EXCLUDE_FROM_ALL 1)
  install(TARGETS contoso EXPORT ContosoTargets)
else()
  set_target_properties(contoso PROPERTIES EXCLUDE_FROM_ALL 1)
  install(TARGETS contoso_static EXPORT ContosoTargets)
endif()

install(EXPORT ContosoTargets
  FILE ContosoTargets
  NAMESPACE contoso::
  DESTINATION share/contoso)

Podczas definiowania funkcji jawne kontrolowanie zależności

Podczas definiowania funkcji, która przechwytuje opcjonalną zależność, upewnij się, że zależność nie będzie używana przypadkowo, gdy funkcja nie jest jawnie włączona.

set(CMAKE_DISABLE_FIND_PACKAGE_ZLIB ON)
set(CMAKE_REQUIRE_FIND_PACKAGE_ZLIB OFF)
if ("zlib" IN_LIST FEATURES)
  set(CMAKE_DISABLE_FIND_PACKAGE_ZLIB OFF)
  set(CMAKE_REQUIRE_FIND_PACKAGE_ZLIB ON)
endif()

vcpkg_cmake_configure(
  SOURCE_PATH ${SOURCE_PATH}
  OPTIONS
    -DCMAKE_DISABLE_FIND_PACKAGE_ZLIB=${CMAKE_DISABLE_FIND_PACKAGE_ZLIB}
    -DCMAKE_REQUIRE_FIND_PACKAGE_ZLIB=${CMAKE_REQUIRE_FIND_PACKAGE_ZLIB}
)

Poniższy fragment kodu jest vcpkg_check_features() równoważny.

vcpkg_check_features(OUT_FEATURE_OPTIONS FEATURE_OPTIONS
  FEATURES
    "zlib"    CMAKE_REQUIRE_FIND_PACKAGE_ZLIB
  INVERTED_FEATURES
    "zlib"    CMAKE_DISABLE_FIND_PACKAGE_ZLIB
)

vcpkg_cmake_configure(
    SOURCE_PATH ${SOURCE_PATH}
    OPTIONS
      ${FEATURE_OPTIONS}
)

ZLIB w fragmencie kodu jest uwzględniana wielkość liter. Aby uzyskać więcej informacji, zobacz dokumentację CMAKE_DISABLE_FIND_PACKAGE_<PackageName> i CMAKE_REQUIRE_FIND_PACKAGE_<PackageName> .

Biblioteka jest uważana za powodującą konflikt, jeśli wykonuje dowolną z następujących czynności:

  • Definiować main
  • Definiowanie malloc
  • Definiowanie symboli zadeklarowanych również w innych bibliotekach

Biblioteki powodujące konflikt są zwykle zgodne z projektem i nie są uznawane za wadę. Ponieważ niektóre systemy kompilacji łączą się ze wszystkimi elementami w katalogu lib, powinny one zostać przeniesione do podkatalogu o nazwie manual-link.

Wersje

Postępuj zgodnie z typowymi konwencjami dla "version" pola

Podczas tworzenia nowego portu postępuj zgodnie z konwencją przechowywania wersji używaną przez autora pakietu. Podczas aktualizowania portu kontynuuj korzystanie z tej samej konwencji, chyba że nadrzędne polecenie mówi inaczej. Pełne wyjaśnienie naszych konwencji można znaleźć w naszej dokumentacji dotyczącej przechowywania wersji.

Jeśli nadrzędne wydanie nie zostało opublikowane od jak na chwilę, nie zmieniaj schematu version-date przechowywania wersji portu na , aby uzyskać najnowsze zmiany. Te zatwierdzenia mogą obejmować zmiany, które nie są gotowe do produkcji. Zamiast tego poproś repozytorium nadrzędne o opublikowanie nowej wersji.

"port-version" Zaktualizuj pole w pliku manifestu wszystkich zmodyfikowanych portów

Narzędzie vcpkg używa tego pola do określenia, czy dany port jest nieaktualny i powinien zostać zmieniony za każdym razem, gdy zachowanie portu ulegnie zmianie.

Nasza konwencja polega na użyciu "port-version" pola dla zmian w porcie, które nie zmieniają wersji nadrzędnej, i zresetowania "port-version" z powrotem do zera po wprowadzeniu aktualizacji do nadrzędnej wersji.

Na przykład:

  • Wersja pakietu Zlib jest obecnie 1.2.1, bez jawnego "port-version" (równoważnego 0wartości )."port-version"
  • Odkryliśmy, że wdrożono niewłaściwy plik praw autorskich i naprawiono to w pliku portfile.
  • Należy zaktualizować "port-version" pole w pliku manifestu na 1.

Aby uzyskać więcej informacji, zobacz dokumentację dotyczącą przechowywania wersji.

Aktualizowanie plików wersji we versions/ wszystkich zmodyfikowanych portach

Narzędzie vcpkg używa zestawu plików metadanych do zasilania funkcji przechowywania wersji. Te pliki znajdują się w następujących lokalizacjach:

  • ${VCPKG_ROOT}/versions/baseline.json, (ten plik jest wspólny dla wszystkich portów) i
  • ${VCPKG_ROOT}/versions/${first-letter-of-portname}-/${portname}.json (jeden na port).

Na przykład w przypadku zlib odpowiednich plików:

  • ${VCPKG_ROOT}/versions/baseline.json
  • ${VCPKG_ROOT}/versions/z-/zlib.json

Oczekujemy, że za każdym razem, gdy zaktualizujesz port, zaktualizujesz również jego pliki wersji.

Zalecaną metodą aktualizacji tych plików jest uruchomienie x-add-version polecenia, np.:

vcpkg x-add-version zlib

Jeśli aktualizujesz jednocześnie wiele portów, możesz zamiast tego uruchomić następujące polecenie:

vcpkg x-add-version --all

aby zaktualizować pliki dla wszystkich zmodyfikowanych portów jednocześnie.

Uwaga

Te polecenia wymagają zatwierdzenia zmian w portach przed ich uruchomieniem. Przyczyną jest to, że algorytm SHA usługi Git katalogu portów jest wymagany w tych plikach wersji. Nie martw się jednak, x-add-version polecenie wyświetli ostrzeżenie, jeśli masz lokalne zmiany, które nie zostały zatwierdzone.

Aby uzyskać więcej informacji, zobacz Dokumentację dotyczącą przechowywania wersji i Tworzenie rejestrów.

Stosowanie poprawek

vcpkg to rozwiązanie do tworzenia pakietów, a nie ostateczni właściciele wdrażanych składników. W niektórych przypadkach musimy zastosować poprawki, aby poprawić zgodność składników z platformami lub zgodność składników ze sobą.

  • Chcemy uniknąć poprawek, które:
    • nadrzędne nie zgadzałoby się z
    • powodować luki w zabezpieczeniach lub awarie
    • Nie jesteśmy w stanie utrzymywać aktualizacji wersji nadrzędnych
    • są wystarczająco duże, aby spowodować splątanie licencji za pomocą samego repozytorium vcpkg

Powiadamianie właścicieli nadrzędnych o odpowiednich poprawkach nadrzędnych

Jeśli poprawka może być przydatna przez nadrzędną treść, należy powiadomić nadrzędną zawartość poprawki. (Poprawki, które stosują zachowanie specyficzne dla programu vcpkg, niezwiązane z nadrzędnym działaniem, takie jak devendoring zależności, nie wymagają powiadomienia).

Aby uniknąć sytuacji, w których nadrzędny element nie zgadza się z poprawką, poczekamy co najmniej 30 dni, aby zastosować takie poprawki.

Pominiemy ten okres oczekiwania, jeśli mamy wysoką pewność, że zmiana jest poprawna. Przykłady poprawek o wysokiej pewności obejmują, ale nie są ograniczone do:

  • Akceptacja nadrzędnego jako poprawki (na przykład scalanie kopii zapasowej określonej zmiany z żądania ściągnięcia w górę).
  • Dodawanie brakujących #includes.
  • Małe i oczywiste poprawki kodu produktu (na przykład inicjowanie niezainicjowanej zmiennej).
  • Wyłączanie nieistotnych składników w vcpkg kompilacji, takich jak testy lub przykłady.

Preferuj opcje stosowania poprawek

Preferowane jest ustawienie opcji w wywołaniu w celu vcpkg_configure_xyz() zastąpienia poprawek ustawień bezpośrednio.

Typowe opcje, które pozwalają uniknąć stosowania poprawek:

  • [MSBUILD] <PropertyGroup> ustawienia wewnątrz pliku projektu można zastąpić za pomocą /p: parametrów
  • [CMAKE] Wywołania w skryptach narzędzia CMake można wyłączyć find_package(XYz) za pośrednictwem polecenia -DCMAKE_DISABLE_FIND_PACKAGE_XYz=ON
  • [CMAKE] Zmienne pamięci podręcznej (zadeklarowane jako set(VAR "value" CACHE STRING "Documentation") lub option(VAR "Documentation" "Default Value")) można przesłonić, przekazując je tylko w wierszu polecenia jako -DVAR:STRING=Foo. Jednym z możliwych wyjątków jest przekazanie parametru FORCE do set(). Aby uzyskać więcej informacji, zobacz dokumentację narzędzia CMake set

Preferuj pobieranie zatwierdzonych poprawek zaewidencjonowanie ich w porcie

Jeśli można uzyskać zatwierdzony lub scalony plik poprawki z nadrzędnego źródła, porty powinny próbować je pobrać i zastosować zamiast mieć je w ramach plików portów. Ten proces jest preferowany, ponieważ:

  • Potwierdza, że nadrzędne zmiany poprawek zostały zaakceptowane
  • Upraszcza proces przeglądania przez przesunięcie nadrzędnego strumienia onus
  • Zmniejsza rozmiar repozytorium vcpkg dla użytkowników, którzy nie korzystają z poprawki
  • Unika konfliktów licencji z repozytorium vcpkg

Poprawki należy pobrać ze stabilnego punktu końcowego, aby uniknąć konfliktów SHA. Podczas pobierania plików poprawek z żądania ściągnięcia lub zatwierdzenia z usług GitHub i GitLab ?full_index=1 parametr powinien zostać dołączony do adresu URL pobierania.

Przykłady:

  • https://github.com/google/farmhash/pull/40.diff?full_index=1
  • https://github.com/linux-audit/audit-userspace/commit/f8e9bc5914d715cdacb2edc938ab339d5094d017.patch?full_index=1
  • https://gitlab.kitware.com/paraview/paraview/-/merge_requests/6375.diff?full_index=1

Preferuj stosowanie poprawek przesłonięć VCPKG_<VARIABLE> wartości

Niektóre zmienne poprzedzone prefiksem VCPKG_<VARIABLE> mają odpowiednik CMAKE_<VARIABLE>. Jednak nie wszystkie z nich są przekazywane do wewnętrznej kompilacji pakietu (zobacz implementacja: łańcuch narzędzi systemu Windows).

Rozważmy następujący przykład:

set(VCPKG_C_FLAGS "-O2 ${VCPKG_C_FLAGS}")
set(VCPKG_CXX_FLAGS "-O2 ${VCPKG_CXX_FLAGS}")

Użycie vcpkgwbudowanych łańcuchów narzędzi działa, ponieważ wartość parametru VCPKG_<LANG>_FLAGS jest przekazywana do odpowiedniej CMAKE_LANG_FLAGS zmiennej. Jednak niestandardowy łańcuch narzędzi, który nie jest świadomy vcpkgzmiennych , nie będzie przekazywać ich dalej.

W związku z tym zaleca się stosowanie poprawek systemu kompilacji bezpośrednio podczas ustawiania polecenia CMAKE_<LANG>_FLAGS.

Minimalizuj poprawki

Podczas wprowadzania zmian w bibliotece staraj się zminimalizować ostateczną różnicę. Oznacza to, że podczas wprowadzania zmian wpływających na region nie należy ponownie sformatować nadrzędnego kodu źródłowego. Podczas wyłączania warunkowego lepiej jest dodać AND FALSE element lub && 0 do warunku niż usunąć każdy wiersz warunkowy. Jeśli duży region musi być wyłączony, jest krótszy, aby dodać if(0) region lub #if 0 wokół niego zamiast usuwać każdy wiersz w poprawce.

Nie dodawaj poprawek, jeśli port jest nieaktualny i aktualizowanie portu do nowszej wersji rozwiąże ten sam problem. Narzędzie vcpkg preferuje aktualizowanie portów za pośrednictwem poprawek nieaktualnych wersji.

Pomaga to zachować rozmiar repozytorium vcpkg w dół, a także zwiększa prawdopodobieństwo, że poprawka zostanie zastosowana do przyszłych wersji kodu.

Nie implementuj funkcji w poprawkach

Celem stosowania poprawek w narzędziu vcpkg jest zapewnienie zgodności z kompilatorami, bibliotekami i platformami. Nie należy implementować nowych funkcji zamiast stosować odpowiednią procedurę open source (przesyłanie problemu/żądania ściągnięcia itp.).

Domyślnie nie kompiluj testów/dokumentacji/przykładów

Podczas przesyłania nowego portu sprawdź wszelkie opcje, takie jak BUILD_TESTS lub WITH_TESTS lub POCO_ENABLE_SAMPLES i upewnij się, że dodatkowe pliki binarne są wyłączone. Minimalizuje to czas kompilacji i zależności dla przeciętnego użytkownika.

Opcjonalnie możesz dodać test funkcję, która umożliwia kompilowanie testów, jednak nie powinna ona znajdować się na Default-Features liście.

Umożliwianie istniejącym użytkownikom biblioteki przełączania się do programu vcpkg

Nie dodawaj CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS

O ile autor biblioteki nie korzysta już z niej, nie powinniśmy używać tej funkcji narzędzia CMake, ponieważ współdziała ona źle z szablonami języka C++ i przerywa działanie niektórych funkcji kompilatora. Biblioteki, które nie udostępniają pliku .def i nie używają deklaracji __declspec() po prostu nie obsługują udostępnionych kompilacji dla systemu Windows i powinny być oznaczone jako takie z vcpkg_check_linkage(ONLY_STATIC_LIBRARY).

Nie zmieniaj nazw plików binarnych poza nazwami nadanymi przez nadrzędny

Oznacza to, że jeśli biblioteka nadrzędna ma różne nazwy w wersji i debugu (libx a libxd), biblioteka debugowania nie powinna być zmieniana na libx. Na odwrót, jeśli biblioteka nadrzędna ma taką samą nazwę w wersji i debugu, nie powinniśmy wprowadzać nowej nazwy.

Ważne zastrzeżenie:

  • Często należy zmienić nazwy wariantów statycznych i udostępnionych na wspólny schemat. Dzięki temu konsumenci mogą używać nazwy pospolitej i ignorować powiązania podrzędnego. Jest to bezpieczne, ponieważ udostępniamy tylko jeden naraz.

Jeśli biblioteka generuje pliki integracji narzędzia CMake (foo-config.cmake), zmiana nazwy należy wykonać za pomocą poprawek kompilacji narzędzia CMake zamiast po prostu wywoływać file(RENAME) archiwa wyjściowe/jednostki LIB.

Na koniec pliki DLL w systemie Windows nigdy nie powinny być zmieniane po kompilacji, ponieważ przerywa generowane elementy LIB.

Manifesty

Wymagamy sformatowania pliku manifestu. Użyj następującego polecenia, aby sformatować wszystkie pliki manifestu:

> vcpkg format-manifest --all

Trojaczki

Obecnie nie akceptujemy żądań dodawania trójek nieuwzwiązanych ze społecznością. Podwyższenie poziomu od społeczności do pełnego stanu potrójnego opiera się głównie na budżecie sprzętu do testowania takich trojaków i będzie napędzany przez metryki przesłane przez vcpkg, aby zmaksymalizować prawdopodobieństwo, że ludzie rzeczywiście korzystają, jest w pełni przetestowany.

Dodamy trojaczki społeczności, jeśli:

  • Wykazano, że ludzie będą rzeczywiście korzystać z tej trójki społeczności; i
  • nie wiemy, że taka trójka jest złamana.

Na przykład nie dodaliśmy trypletu https://github.com/microsoft/vcpkg/pull/29034 , ponieważ autor po prostu próbował "ukończyć zestaw", zamiast wskazywać, że rzeczywiście użyje takiego elementu, a my nie dodaliśmy dynamicznego systemu Linux, dopóki rozwiązanie patchelf nie spowoduje utworzenia wyników przeniesienia.

Przydatne uwagi dotyczące implementacji

Pliki portów są uruchamiane w trybie skryptu

Chociaż portfile.cmakepliki i CMakeLists.txtmają wspólną składnię i podstawowe konstrukcje języka CMake (aka "Scripting Commands"), pliki portfile są uruchamiane w trybie skryptu, podczas gdy CMakeLists.txt pliki są uruchamiane w trybie projektu. Najważniejszą różnicą między tymi dwoma trybami jest to, że "Tryb skryptu" nie ma koncepcji "Łańcuch narzędzi", "Język" i "Cel". Wszelkie zachowania, w tym polecenia skryptów, które zależą od tych konstrukcji (np. CMAKE_CXX_COMPILER, CMAKE_EXECUTABLE_SUFFIX, ), CMAKE_SYSTEM_NAMEnie będą poprawne.

Pliki Portfile mają bezpośredni dostęp do zmiennych ustawionych w pliku potrójnym, ale CMakeLists.txtnie (chociaż często występuje tłumaczenie, które występuje — VCPKG_LIBRARY_LINKAGE w porównaniu z BUILD_SHARED_LIBS).

Kompilacje Portfile i Project wywoływane przez pliki portów są uruchamiane w różnych procesach. Koncepcyjnie:

+----------------------------+       +------------------------------------+
| CMake.exe                  |       | CMake.exe                          |
+----------------------------+       +------------------------------------+
| Triplet file               | ====> | Toolchain file                     |
| (x64-windows.cmake)        |       | (scripts/buildsystems/vcpkg.cmake) |
+----------------------------+       +------------------------------------+
| Portfile                   | ====> | CMakeLists.txt                     |
| (ports/foo/portfile.cmake) |       | (buildtrees/../CMakeLists.txt)     |
+----------------------------+       +------------------------------------+

Aby określić hosta w pliku portfile, standardowe zmienne CMake są poprawne (CMAKE_HOST_WIN32).

Aby określić obiekt docelowy w pliku portfile, należy użyć zmiennych potrójnych vcpkg (VCPKG_CMAKE_SYSTEM_NAME).

Zapoznaj się również z naszą dokumentacją triplet, aby uzyskać pełne wyliczenie możliwych ustawień.