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-cpp
i 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:
vcpkg_extract_source_archive_ex()
należy zastąpić obsługiwanym przeciążeniemvcpkg_extract_source_archive()
(zARCHIVE
)- Przestarzałe przeciążenie
vcpkg_extract_source_archive()
elementu bezARCHIVE
powinno zostać zastąpione przez obsługiwane przeciążenie za pomocą poleceniaARCHIVE
. vcpkg_apply_patches()
argumenty powinny zostać zastąpionePATCHES
argumentami pomocników "wyodrębniania" (np.vcpkg_from_github()
)vcpkg_build_msbuild()
element powinien zostać zastąpiony przezvcpkg_install_msbuild()
vcpkg_copy_tool_dependencies()
element powinien zostać zastąpiony przezvcpkg_copy_tools()
vcpkg_configure_cmake
element powinien zostać zastąpiony przezvcpkg_cmake_configure()
po usunięciuPREFER_NINJA
vcpkg_build_cmake
element powinien zostać zastąpiony przezvcpkg_cmake_build()
vcpkg_install_cmake
element powinien zostać zastąpiony przezvcpkg_cmake_install()
vcpkg_fixup_cmake_targets
element powinien zostać zastąpiony przezvcpkg_cmake_config_fixup
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 a
instalacji 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-vcpkgunofficial::<port>::<target>
jako wyeksportowany element docelowy z tego portu.
Przykłady:
brotli
unofficial-brotli
tworzy pakiet, tworząc docelowyunofficial::brotli::brotli
element .
Instalowanie pliku praw autorskich
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
,libzip
open62541
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
maopencv2
,opencv3
funkcje 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ę. imgui
experimental-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 nie mogą dodawać interfejsów API
Funkcje domyślne mają na celu zapewnienie, że w przypadku klientów, którzy nie wiedzą, że korzysta z niej rozsądnie funkcjonalna kompilacja biblioteki. Jeśli nie wiedzą, że korzystają z biblioteki, nie mogą wiedzieć o wyświetlaniu listy funkcji. Na przykład libarchive
uwidacznia funkcje, które umożliwiają korzystanie z algorytmów kompresji do istniejącego interfejsu ogólnego. Jeśli nie utworzono żadnej z takich funkcji, biblioteka może nie mieć żadnego narzędzia.
Należy dokładnie rozważyć, czy funkcja powinna być włączona domyślnie, ponieważ wyłączenie funkcji domyślnych jest złożone.
Wyłączenie funkcji domyślnej jako użytkownika przejściowego wymaga:
- Wszyscy klienci jawnie wyłączają funkcje domyślne za pośrednictwem
"default-features": false
funkcji lub dołączają[core]
je do listy funkcji w wierszu polecenia. - Nazewnictwo zależności przechodniej w
vcpkg install
wierszu polecenia lub jako zależność bezpośrednia w manifeście najwyższego poziomu
Jeśli funkcja dodaje dodatkowe interfejsy API, pliki wykonywalne lub inne pliki binarne w rejestrze programu vcpkg domyślnie muszą być wyłączone. 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łyconst wchar_t*
zamiastconst 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:
- Włączenie funkcji powoduje zmianę wielowypełnień na aliasy jednostki poliwypełnionej
- Stan poliwypełniania jest upieczony w zainstalowanych nagłówkach, tak aby niezgodność ABI błędy środowiska uruchomieniowego "niemożliwe" są mało prawdopodobne
- 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]
zmianyabsl::string_view
w zamiany lubstd::string_view
; poprawka implementuje wymaganie pieczenia.
Zalecane rozwiązania
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>
.
Umieszczanie bibliotek powodujących konflikt w manual-link
katalogu
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żnego0
wartoś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 na1
.
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
#include
s. - 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")
luboption(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 parametruFORCE
doset()
. Aby uzyskać więcej informacji, zobacz dokumentację narzędzia CMakeset
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 vcpkg
wbudowanych ł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 vcpkg
zmiennych , 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.cmake
pliki i CMakeLists.txt
mają 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_NAME
nie będą poprawne.
Pliki Portfile mają bezpośredni dostęp do zmiennych ustawionych w pliku potrójnym, ale CMakeLists.txt
nie (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ń.