Notatka
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
W tym dokumencie opisano zasady, wytyczne i najlepsze rozwiązania, które należy stosować podczas współtworzenia programu vcpkg.
Ma ona pełnić tę samą rolę co:
- Podręcznik zasad Debiana,
- Wytyczne dotyczące konserwacji oprogramowania Homebrew i
- Podręcznik Formuły Homebrewa.
Wyselekcjonowane cele projektowania rejestru
Porty muszą być instalowane jednocześnie
Port zawarty w rejestrze kuratorskim musi zostać pomyślnie skompilowany w obecności wszystkich pozostałych portów w rejestrze. Wszystkie kombinacje portów są regularnie testowane przez zautomatyzowany system CI vcpkg.
Port nie może wykonywać żadnych z następujących czynności:
- Zainstaluj pliki powodujące konflikt z innym portem.
- Zainstaluj symbole i definicje należące do innego pakietu, z wyjątkiem bibliotek o wąskim zakresie, jawnie dowiązanych, opisanych w artykule Umieść biblioteki powodujące konflikt w
manual-linkkatalogu. - Przetestuj obecność lub brak innego portu. Z wyjątkiem deklarowania zależności.
Wyjątki są tworzone dla:
- Porty zastępujące inny port w oficjalnym charakterze. Obejmuje to przypadki, w których:
- Ten sam projekt publikuje komponent następczy.
- Inny projekt przejmuje utrzymanie porzuconego komponentu, w tym poprzez utworzenie forka.
- Inny projekt publikuje komponent następczy.
- Porty, w których nie nakładają się platformy. Na przykład zamiennik tylko dla systemu Windows dla składnika systemu Linux, który nie obsługuje systemu Windows.
- Porty, które poprzedzają tę politykę i mają znaczącą liczbę użytkowników i współautorów.
Osoby odpowiedzialne za program vcpkg oceniają wyjątki objęte zasadą praw nabytych indywidualnie. Na przykład boringssl został dodany przed udostępnieniem rejestrów niestandardowych i pozostanie w rejestrze wyselekcjonowanych, ponieważ nadal ma znaczących użytkowników, mimo że openssl jest dostawcą kanonicznym rodziny rozwidlenia OpenSSL. Sama wcześniejsza akceptacja nie gwarantuje wyjątku.
Nie można zaakceptować portów, które nie są zgodne z zasadami, do rejestru wyselekcjonowanych.
Napiwek
Jeśli nie można uwzględnić portu w rejestrze wybranym, rozważ opublikowanie rejestru niestandardowego lub użycie portu nakładkowego.
Porty muszą być testowane w co najmniej jednej oficjalnej trójce
Wszystkie porty w zatwierdzonym rejestrze muszą być testowane w CI dla co najmniej jednej oficjalnej triplet.
Wyjątki są tworzone dla:
- Tymczasowe okoliczności, takie jak:
- Port nie kompiluje się bez aktualizacji infrastruktury CI.
- Port nie kompiluje się z powodu niedawnej zmiany powodującej niezgodność w zależności nadrzędnej i trwa rozwiązywanie tej sytuacji.
- Porty, które poprzedzają tę politykę i mają znaczącą liczbę użytkowników i współautorów.
Nowe porty, których nie można przetestować w co najmniej jednym oficjalnym zestawie trzech parametrów, nie są akceptowane w kuratorowanym rejestrze. Istniejące porty, które nie są już zgodne z tymi zasadami i nie kwalifikują się do wyjątku wymienionego powyżej, są usuwane z rejestru. Jeśli na przykład testowanie ciągłej integracji zostało wyłączone we wszystkich oficjalnych trójkach obsługiwanych przez port i nie ma zastosowania żaden wyjątek, port zostanie usunięty z listy.
Napiwek
Jeśli nie można uwzględnić portu w rejestrze wybranym, rozważ opublikowanie rejestru niestandardowego lub użycie portu nakładkowego.
Spakietowane komponenty powinny być stabilne i aktywnie utrzymywane
Komponenty opublikowane w wyselekcjonowanym rejestrze muszą być aktywnie utrzymywane. Porty dla nieaktywnych składników mogą zostać usunięte z listy.
Składnik jest uznawany za nieaktywny, jeśli:
- Jego opiekunowie uznali komponent za porzucony.
- Jego repozytorium źródłowe jest zarchiwizowane lub nie akceptuje już kontrybutów.
- Osoby odpowiedzialne za utrzymanie nie odpowiadają ani nie są osiągalne.
- Nie wprowadzono znaczących zmian w długim czasie.
Robi się wyjątki dla podstawowych składników, które są uważane za dojrzałe i stabilne i nie są często zmieniane.
Na przykład: zlib.
Spakowane komponenty powinny być dojrzałe
Składniki zawarte w wyselekcjonowanym rejestrze muszą być dojrzałe i przeznaczone do użycia przez użytkowników programu vcpkg. Składniki przeznaczone do użytku osobistego powinny być publikowane do własnych rejestrów.
Składnik jest uważany za wystarczająco dojrzały dla wyselekcjonowanego rejestru, jeśli jedno z tych stwierdzeń jest prawdziwe:
- Składnik ma wersję sprzed co najmniej sześciu miesięcy.
- Składnik wykazuje co najmniej sześć miesięcy aktywnego rozwoju publicznego.
- Składnik jest oficjalną częścią projektu z co najmniej sześciomiesięczną historią wydań lub aktywnym publicznym rozwojem. Na przykład nowa biblioteka Boost lub składnik Qt.
- Składnik demonstruje równoważną dojrzałość do poprzednich wymagań w innym zakresie.
Niektóre wskaźniki niedojrzałości komponentów to:
- Składnik nie jest wyświetlany w wyszukiwarkach.
- Składnik jest często przemianowywany.
- Konflikty z innymi bibliotekami.
Napiwek
Jeśli nie można uwzględnić portu w rejestrze wybranym, rozważ opublikowanie rejestru niestandardowego lub użycie portu nakładkowego.
Struktura PR
Składaj oddzielne żądania ściągnięcia dla każdego portu
Mniejsze żądania ściągnięcia są łatwiejsze do przejrzenia. Pull requesty powinny wprowadzać zmiany dla jednego portu. Zmniejsza to również czas oczekiwania na wyniki ciągłej integracji.
Ograniczenie próśb o scalenie do pojedynczego portu może nie być możliwe w niektórych przypadkach. Na przykład zmiana portu wymaga zaktualizowania lub stosowania poprawek dla odbiorców podrzędnych.
Unikaj niepowiązanych zmian kosmetycznych
Nie wprowadzaj niepowiązanych zmian kosmetycznych w skądinąd niezmodyfikowanym porcie, takich jak ponowne formatowanie, zmienianie nazw zmiennych lub naprawianie literówek. Te zmiany zużywają czas obliczeniowy, który lepiej wykorzystać gdzie indziej. Zmiany poprawiające poprawność kompilacji, zgodność, niezawodność lub powtarzalność nie są uznawane za trywialne wyłącznie dlatego, że zainstalowane pliki pozostają niezmienione.
Używanie charakterystycznych nazw portów
Nazwa portu powinna wskazywać na jego zawartość.
Wyszukiwanie nazwy portu oprogramowania w wyszukiwarce lub wyspecjalizowanych przeglądarkach pakietów, takich jak Repology, powinno prowadzić do odpowiadającego mu składnika.
Porty z krótkimi nazwami lub nazwane po typowych słowach wymagają uściślania. Dotyczy to tylko nazwy portu w kuratowanym rejestrze; nazwa spakowanego składnika i jego zawartość nie muszą być zgodne z tą zasadą.
Wyjątki stosuje się dla portów, które pakują składnik z silnym skojarzeniem z nazwą portu. Na przykład: libpng, openssllub zlib.
Aby spełnić te zasady, nowe porty z niejednoznacznymi nazwami mogą używać prefiksu, takiego jak:
- Właściciel, nazwa użytkownika lub organizacja repozytorium. Przykład:
google-cloud-cpp. W przypadku portów składników hostowanych na GitHubie właściciel na GitHubie jest akceptowalnym jednoznacznym prefiksem<github owner>-<repository name>. - Nazwa pakietu, do którego należy pakiet:
boost-dll. Tylko wtedy, gdy pakiet jest oficjalnym składnikiem takiego pakietu.
Przykład: niejednoznaczna nazwa portu
Port o nazwie ip jest uznawany za niejednoznaczny, ponieważ:
- nazwa jest za krótka,
- nazwa jest pospolitym słowem i
- nazwa nie jest silnie skojarzona z żadnym pojedynczym komponentem.
Aby określić, czy nazwa jest niejednoznaczna, usuń z nazwy portu następujące typowe prefiksy i sufiksy używane przez komponenty C++ i open source:
cppfreelibopen- cyfry
Na przykład: ip-cpp, libip i ip5 są niejednoznaczne, ponieważ są zredukowane do tego samego ip rdzenia.
Ograniczanie nazw portów
Aby uniknąć nieporozumień wśród użytkowników, port nie może być przemianowany więcej niż raz w żadnym okresie 12 miesięcy.
Wersje robocze pull requestów 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 ludzkiej opinii na temat pracy, która nie jest jeszcze gotowa do scalenia. Większość nowych żądań ściągnięcia powinna być otwierana jako wersje robocze i konwertowana na normalne żądania ściągnięcia po pomyślnym zakończeniu testów ciągłej integracji.
Aby uzyskać więcej informacji na temat wersji roboczych pull requestów GitHub, zobacz Wprowadzenie do roboczych pull requestów.
Opiekun vcpkg może przekonwertować PR na wersję roboczą podczas procesu przeglądu, zwykle podczas żądania zmian lub pozostawiania komentarzy, które wskazują, kiedy oznaczyć PR jako gotowe do przeglądu.
Zamknij nieaktywne PRy
Opiekun vcpkg może zamknąć PR, jeśli oczekuje on na działanie ze strony współtwórcy przez ponad 60 dni. Odliczanie braku aktywności jest uruchamiane tylko wtedy, gdy wymagana jest akcja użytkownika. Nie jest ono uruchamiane, gdy pull request oczekuje na weryfikację laboratorium kompilacji ani na przegląd przez opiekuna projektu vcpkg.
Żądanie scalenia jest gotowe do weryfikacji, gdy:
- Nie ma nieudanych kontroli PR lub współautor prosi o pomoc albo uzasadnia przyczynę niepowodzeń.
- Nie ma żadnych oczekujących zmian ani wyjaśnień wymaganych przez osobę odpowiedzialną za program vcpkg.
- Nie ma konfliktów scalania.
Odliczanie rozpoczyna się, gdy PR przechodzi do stanu, który wymaga działania współtwórcy. Może się tak zdarzyć, gdy PR jest otwierany z problemami, które współtwórca musi rozwiązać, lub gdy osoba utrzymująca vcpkg żąda zmian lub wyjaśnień. Opiekun vcpkg może oznaczyć PR jako wersję roboczą, gdy prosi współtwórcę o podjęcie działania.
Merytoryczna odpowiedź współtwórcy resetuje odliczanie. Jeśli odpowiedź rozwiąże wszystkie oczekujące żądania, a PR jest gotowe do przeglądu, odliczanie zostanie zatrzymane do momentu, gdy ponownie będzie wymagane działanie współtwórcy. Jeśli współtwórca nie odpowiada w ciągu 60 dni, gdy jest wymagana akcja, PR jest uznawany za nieaktualny i może zostać zamknięty według uznania opiekuna vcpkg.
Portfile (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()bezARCHIVEpowinno zostać zastąpione przez obsługiwane przeciążenie zARCHIVE. -
vcpkg_apply_patches()argumenty powinny zostać zastąpionePATCHESargumentami 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_cmakeelement powinien zostać zastąpiony przezvcpkg_cmake_configure()po usunięciuPREFER_NINJA -
vcpkg_build_cmakeelement powinien zostać zastąpiony przezvcpkg_cmake_build() -
vcpkg_install_cmakeelement powinien zostać zastąpiony przezvcpkg_cmake_install() -
vcpkg_fixup_cmake_targetselement 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 szablonowe na skutek polecenia create przed przesłaniem PR.
Użyj małych liter dla ciągów cyfr szesnastkowych
Wiele funkcji w narzędziu vcpkg polega na porównywaniu ciągów cyfr szesnastkowych. Niektóre przykłady obejmują, ale nie są ograniczone do, skrótów SHA512, identyfikatorów zatwierdzeń usługi Git i skrótów obiektów drzewa.
Wewnętrznie vcpkg używa normalizacji małych liter do porównań takich wartości, w których wielkość liter nie ma znaczenia. Jednak narzędzia oparte na infrastrukturze vcpkg mogą nie uwzględniać tych samych zagadnień. Z tego powodu wymagamy ciągów szesnastkowych
aby były zapisane małymi literami dla spójności w następujących scenariuszach:
-
SHA512Parametr w funkcjach pomocnika vcpkg. -
REFParametr w funkcjach pomocnika vcpkg, gdy wartość jest ciągiem szesnastkowym. - Obiekt
git-treew plikach baz danych wersji. - Obiekt
sha512wscripts/vcpkg-tools.jsonpliku. - Inne miejsca, w których wielkość liter ciągu szesnastkowego jest nieważna.
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 na podstawie:
> 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 drzewie zainstalowanym przez inny port, zanim podejmą jakieś działania. 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 powinno być dwóch portów, które użytkownik oczekuje używać jednocześnie, mogących dostarczać ten sam plik. Jeśli port spróbuje zainstalować plik już dostarczony przez inny port, 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 uruchomienia ciągłej integracji, które próbują zainstalować wszystkie porty w rejestrze, co zakończy się niepowodzeniem FILE_CONFLICTS, jeśli dwa porty dostarczają 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óżnic między poleganiem na bibliotece z systemu a poleganiem na bibliotece 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 CMake eksportowane przez porty, które nie znajdują się w bibliotece nadrzędnej, powinny mieć prefiks unofficial-. 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 uzyskania pakietu unikalnego dla vcpkg -
unofficial::<port>::<target>jako wyeksportowany cel z tego portu.
Przykłady:
-
brotlitworzy pakietunofficial-brotli, produkując docelowyunofficial::brotli::brotli.
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ę komponentó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ć używane tylko do utrzymania spójności z niezależnymi składnikami.
Zmienne w MAYBE_UNUSED_VARIABLES muszą mieć zastosowanie do co najmniej jednej konfiguracji
Podczas dodawania nowej zmiennej w MAYBE_UNUSED_VARIABLES celu wyciszenia ostrzeżenia podczas kroku konfiguracji narzędzia CMake należy dodać komentarz wyjaśniający przypadek zastosowania nowej zmiennej. Jeśli zmienna nie ma zastosowania w żadnej konfiguracji, jest bardzo prawdopodobne, że istnieje ukryty błąd (na przykład błędna nazwa zmiennej) i dodanie jej nie ma rzeczywistego wpływu na kompilację.
vcpkg_check_features(OUT_FEATURE_OPTIONS FEATURE_OPTIONS
FEATURES
windowsfeature WINDOWS_OPTION
)
vcpkg_cmake_configure(
SOURCE_PATH "${SOURCE_PATH}"
OPTIONS
${FEATURE_OPTIONS}
MAYBE_UNUSED_VARIABLES
WINDOWS_OPTION # Applies only on Windows
)
Funkcje
Nie używaj funkcji do implementowania alternatyw
Funkcje muszą być traktowane jako funkcje addytywne. Jeśli port[featureA] zainstaluje się i port[featureB] zainstaluje się, to port[featureA,featureB] musi zostać zainstalowane. 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, zgodnie z wyrażeniami w vcpkg, a użytkownicy, którzy preferują inne ustawienia, muszą obecnie korzystać z portów typu overlay.
Istniejące przykłady nie zostaną dziś zaakceptowane w celu zachowania zgodności z poprzednimi wersjami:
-
libgit2,libzipopen62541wszystkie mają funkcje do wybierania zaplecza TLS lub kryptografii.curlma różne opcje silników kryptograficznych, ale umożliwia wybór między nimi w czasie działania, co oznacza, że powyższa zasada jest utrzymana. -
darknetmaopencv2,opencv3funkcje do kontrolowania, której wersji opencv użyć dla swoich zależności.
Funkcja może włączać tryb 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 (w formacie
azure-Xxx) mają funkcjępublic-preview. -
imguiexperimental-dockingma 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
Uwaga / Notatka
Funkcja domyślnie włączona przez nadrzędny system kompilacji nie oznacza, że należy tę funkcję dodać do wpisów default-features. Celem default-features nie jest modelowanie decyzji podjętych przez system nadrzędny, ale zapewnienie wygody dla użytkowników trybu klasycznego.
Funkcje domyślne są przeznaczone do zapewnienia, że instalowana jest wystarczająco funkcjonalna wersja biblioteki dla klientów, którzy nie wiedzą, że z niej korzystają. Jeśli nie wiedzą, że korzystają z biblioteki, nie mogą wiedzieć, jak wymienić funkcje. 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.
W tym miejscu odbiorcy obejmują zarówno projekty użytkowników, które używają grafu pakietów, jak i porty zależne w ramach tego grafu. Obie wyrażają swoje wymagania dotyczące zależności za pośrednictwem tego samego interfejsu funkcji.
Dokładnie zastanów się, czy funkcja powinna być domyślnie włączona, ponieważ wyłączenie funkcji domyślnych jest złożone.
Aby wyłączyć funkcje domyślne dla zależności przechodniej:
- Każdy klient, który ma zależność od portu, musi wyłączyć jego domyślne funkcje w deklaracji zależności za pomocą
"default-features": false. - Projekt najwyższego poziomu musi również bezpośrednio określać zależność przechodnią, albo w swoim manifeście za pomocą
"default-features": false, albo w wierszu poleceniavcpkg installza pomocą[core].
Wyłączenie funkcji domyślnych nie uniemożliwia innemu klientowi wyraźnego zażądania żadnej z tych funkcji.
Na potrzeby tej polityki interfejs API jest dowolnym interfejsem udostępnianym użytkownikom, w tym interfejsami biblioteki, wykonywalnymi interfejsami wiersza polecenia i innymi interfejsami binarnymi. Funkcja może być domyślnie włączona, gdy dodaje funkcjonalność w ramach istniejącego interfejsu API, takie jak obsługa dodatkowych algorytmów kompresji za pośrednictwem istniejącego interfejsu ogólnego.
W kuratorowanym rejestrze vcpkg, jeśli funkcja dodaje interfejs API, musi być domyślnie wyłączona. 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]kontroluje działanie polyfill, ale nie wbudowuje ustawienia w zainstalowane drzewo. -
ace[wchar]zmienia wszystkie interfejsy API tak, aby akceptowałyconst wchar_t*zamiastconst char*.
Funkcja może zastąpić polyfills aliasami, pod warunkiem że zamiana jest wbudowana w strukturę instalacyjną.
Niezależnie od powyższego, porty mogą usuwać polyfille za pomocą funkcji, o ile:
- Włączenie funkcji powoduje zmianę wielowypełnień na aliasy jednostki poliwypełnionej
- Stan poliwypełniania jest zintegrowany z zainstalowanymi nagłówkami, dzięki czemu błędy ABI, które teoretycznie są "niemożliwe" podczas działania programu, 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]zmieniaabsl::string_viewna zamiennik lubstd::string_view; poprawka wprowadza 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 budowania
Nie używaj zależności od dostawcy
Preferuj oddzielnie spakować zależności, aby użytkownicy mogli je wybierać i aktualizować za pomocą narzędzia vcpkg. Dołączone do projektu zależności wiążą się z kilkoma wyzwaniami:
- Trudność aktualizacji: Zależności dołączone do projektu są trudniejsze do śledzenia i aktualizowania, w tym podczas stosowania poprawek zabezpieczeń.
- Konflikty symboli: Dołączona zależność może definiować te same symbole co inna wersja zależności, powodując błędy środowiska uruchomieniowego lub niezdefiniowane zachowanie.
- Zgodność licencyjna: Zależności dołączone do projektu mogą zaciemniać wymagania dotyczące licencjonowania lub powodować problemy ze zgodnością licencji.
- Zwiększona konserwacja: Utrzymywanie zależności wbudowanych w projekt zsynchronizowanych z ich wersjami upstream zwiększa pracę konserwacyjną i może duplikować pracę między portami.
Z tych powodów usuwaj zależność od dostawcy z zależności, ilekroć jest to praktyczne. Zależności dołączone do projektu nie mogą być udostępniane w domenie linkowania użytkownika.
Domena linkera to zestaw symboli, które mogą być wzajemnie dowiązywane w czasie wykonywania. W Windows każda biblioteka DLL zazwyczaj ma własną domenę linkowania. Na platformach z tabelą symboli dla całego procesu domena łącza zwykle obejmuje cały proces.
Jeśli składnik uwidacznia zależność dołączoną przez dostawcę w tym samym obszarze linkowania co zależność wybrana za pośrednictwem programu vcpkg, obie kopie mogą definiować te same symbole. Narusza to regułę jednej definicji i może powodować błędy środowiska uruchomieniowego lub niezdefiniowane zachowanie. Problem może występować tylko wtedy, gdy dwie wersje są wystarczająco różne, aby były niezgodne.
Zależność dołączona do źródeł jest dozwolona tylko wtedy, gdy jest w pełni odizolowana od domen linkowania używanych przez porty zależne i aplikacje użytkowników. Na przykład narzędzie kompilacji tylko dla hosta może zawierać statycznie połączoną zależność, jeśli binaria dalszego etapu nie łączą się z narzędziem, a symbole tej zależności nie mogą trafić do ich domen linkowania.
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 zawsze należy dążyć do maksymalizacji przyszłej łatwości utrzymania portu. Zazwyczaj oznacza to zminimalizowanie liczby wierszy, które należy zmienić, 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 opakowanie wywołania install(TARGETS ...) w elemencie 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) Zastąp wiersz blokiem warunkowym, który również wyklucza niechciany element docelowy z kompilacji domyślnej:
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 z użyciem vcpkg_check_features() jest 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 ma znaczenie 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
Plik wejściowy konsolidatora zainstalowany w systemie lib lub debug/lib, taki jak .lib, .a, .solub .dylib , jest uznawany za powodujący konflikt, jeśli wykonuje którykolwiek z następujących czynności:
- Definiuje element
main. - Definiuje element
malloc. - Definiuje symbole, które są również zdefiniowane w innych bibliotekach.
Niektóre pliki wejściowe linkera celowo udostępniają wąsko ograniczone zamienniki symboli, które użytkownicy w inny sposób zdefiniowaliby lub uzyskali w innym miejscu. Na przykład usługa Google Test gtest-main.lib udostępnia main dla plików wykonywalnych testów, których autorzy zdecydują się z niego korzystać zamiast definiować własny punkt wejścia.
Umieść powodujące konflikt pliki wejściowe konsolidatora w lib/manual-link lub debug/lib/manual-link, aby systemy kompilacji, które automatycznie łączą pliki z katalogu biblioteki, ich nie wybierały. Biblioteki DLL systemu Windows pozostają w bin lub debug/bin; umieść ich biblioteki importu w manual-link, gdy wymagane jest jawne linkowanie. Konsumenci muszą jawnie wyrazić zgodę na łączenie tych plików i są odpowiedzialni za uniknięcie konfliktowych definicji. Ten wyjątek nie jest ogólnym mechanizmem pakowania alternatywnych dostawców innego składnika, a przeniesienie pliku wejściowego edytora połączeń do manual-link nie powoduje odizolowania jego symboli od domeny linkowania konsumenta.
Instalowanie wstępnie utworzonych plików binarnych
Porty, które instalują wstępnie utworzone artefakty (tylko binarne), są dozwolone, ale zdecydowanie odradzane, pod warunkiem, że artefakty nie uniemożliwiają użytkownikom wybierania ani aktualizowania zależności za pośrednictwem narzędzia vcpkg. Kompilowanie ze źródła jest preferowane, ponieważ uwzględnia ustawienia vcpkg kontrolujące kompilator i flagi.
Odrzucimy porty spełniające wszystkie następujące warunki:
- Instalowanie wstępnie utworzonych plików binarnych, a nie kompilowanie z źródła i
- Te pliki binarne obejmują lub wymagają zależności środowiska uruchomieniowego udostępnianych przez inne porty w wyselekcjonowanym rejestrze i
- Zainstalowane artefakty udostępniają te zależności domenie linkowania, która może również zawierać wersje wybrane za pomocą narzędzia vcpkg.
Ta kombinacja skutecznie blokuje graf zależności do wersji używanych podczas tworzenia wstępnie zbudowanego pakietu upstream.
Jeśli program vcpkg aktualizuje zależność, taką jak zlib lub openssl, wstępnie utworzone i wybrane przez użytkownika wersje mogą definiować niezgodne symbole w tej samej domenie łącza. Może to spowodować naruszenia reguły jednej definicji, niezgodności ABI lub pominiętych aktualizacji zabezpieczeń.
Artefakt uwidacznia zależność za każdym razem, gdy ta zależność uczestniczy w domenie łącza użytkownika, niezależnie od tego, czy komponent nadrzędny zamierza ją uwidocznić. Obejmuje to:
- Biblioteki, z którymi użytkownik może się linkować:
.lib,.so,.a,.dyliblub biblioteki importu, które wprowadzają zależność do obszaru linkowania użytkownika. - Zainstalowane nagłówki odwołujące się (bezpośrednio lub za pośrednictwem kodu wbudowanego/szablonu) do symboli, typów lub makr z innych portów vcpkg.
- Zainstalowane pliki konfiguracji narzędzia CMake lub pkg-config, które wywołują
find_dependency()lubRequires:na innych portach vcpkg.
Dozwolone (ale nadal zniechęcone) scenariusze:
- Narzędzia pomocnicze tylko dla hosta używane w czasie kompilacji, których dane wyjściowe są używane, ale z którymi porty zależne się nie linkują, pod warunkiem, że izolują one dołączone zależności lub polegają tylko na wszechobecnych bibliotekach środowiska uruchomieniowego systemu.
- Wstępnie utworzone biblioteki, których dołączone zależności pozostają całkowicie w osobnych domenach linków i nie pojawiają się w zainstalowanych plikach nagłówkowych ani wyeksportowanych interfejsach. Samo łączenie statyczne nie izoluje zależności od domeny linkowania użytkownika.
- Pakiety zawierające wyłącznie dane, oprogramowanie układowe lub zasoby, które nie są połączone z kodem użytkownika.
Przykłady zabronione:
- Wstępnie skompilowana biblioteka, która statycznie łączy prywatną kopię
zlibi uwidacznia jej symbole w obszarze linkowania, który może również zawierać wersjęzlibwybraną za pomocą narzędzia vcpkg. - Wstępnie skonfigurowany
libfoo, który instalujelib/libfoo.liboraz nagłówki, w tym<zlib.h>i został skompilowany na konkretną wersjęzlib; użytkownicy następnie łączą się zlibfooz oczekiwaną zgodnością. - Wstępnie utworzony zestaw SDK, który instaluje plik pakietu CMake wywołujący
find_dependency(OpenSSL), gdy plik binarny był kompilowany ze starszą wersją OpenSSL.
Środki zaradcze/ alternatywy:
- Udostępnij kompilację ze źródła przy użyciu przeznaczonych skryptów lub dodaj cienką warstwę CMake.
- Poproś główne repozytorium o opublikowanie wydania opartego na źródle lub instrukcji umożliwiającej odtworzenie kompilacji; umieść link do problemu lub żądania ściągnięcia z głównego repozytorium w komentarzu w
portfile.cmakelubvcpkg.json. - Użyj portu nakładki lub rejestru prywatnego dla wstępnie utworzonych elementów specyficznych dla organizacji, które nie mogą spełniać tych reguł.
Wersjonowanie
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 źródło nie opublikowało wydania od pewnego czasu, nie zmieniaj schematu wersjonowania portów, 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.
Zaktualizuj pole "port-version" dla każdego zmodyfikowanego portu
Każdy PR modyfikujący port musi utworzyć nową wersję tego portu. PR-y są scalane metodą squash, dlatego aktualizuj wersję każdego zmodyfikowanego portu raz na PR, a nie raz na commit ani poprawkę w ramach przeglądu.
Jeśli wersja źródłowa nie została zmieniona, zwiększ pole "port-version". Jeśli wersja nadrzędna została zmieniona, zresetuj "port-version" do zera, usuwając pole lub ustawiając je na 0.
Na przykład:
- Wersja pakietu Zlib jest obecnie
1.2.1, bez jawnego"port-version"(odpowiadającego"port-version"0). - 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.
Zaktualizuj pliki wersji programu versions/ dla każdego zmodyfikowanego portu
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, pliki, które są istotne, to:
${VCPKG_ROOT}/versions/baseline.json${VCPKG_ROOT}/versions/z-/zlib.json
Dla każdego zmodyfikowanego portu w PR zaktualizuj jego pliki wersji, aby zarejestrować końcowe drzewo Git. Jeśli wprowadzisz dalsze zmiany podczas przeglądu, uruchom polecenie vcpkg x-add-version <port-name> --overwrite-version, aby odświeżyć wpis niezmergowanej wersji
bez ponownego zwiększania "port-version" .
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.
Aby uzyskać więcej informacji, zobacz artykuły Versioning reference i Registries.
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ć konflikt licencji w samym repozytorium vcpkg
Powiadomienia upstream i okresy oczekiwania
Właściciele komponentów upstream są ostatecznymi arbitrami zachowania ich składnika. Osoby odpowiedzialne za program vcpkg wymagają powiadomienia upstreamu dotyczącego poprawek istotnych dla upstreamu i usterek zidentyfikowanych przez narzędzia do przeglądu kodu sztucznej inteligencji w nowych zgłoszeniach portów.
Poprawki istotne dla upstream
Jeśli poprawka może być przydatna dla projektu upstream, osoby odpowiedzialne za program vcpkg wymagają powiadomienia projektu upstream o zawartości poprawki. Poprawki, które stosują zachowanie specyficzne dla programu vcpkg, niezwiązane z projektem źródłowym, takie jak devendoring zależności, nie wymagają powiadomienia.
Aby uniknąć sytuacji, w których projekt źródłowy nie zgadza się z poprawką, osoby odpowiedzialne za program vcpkg czekają co najmniej 30 dni po powiadomieniu projektu źródłowego przed zastosowaniem takich poprawek.
Osoby odpowiedzialne za program vcpkg pomijają ten okres oczekiwania, jeśli mają wysoką pewność, że zmiana jest poprawna. Przykłady poprawek o wysokiej pewności obejmują, ale nie są ograniczone do:
- Akceptacja zmian przez projekt źródłowy jako poprawki (na przykład przeniesienie wstecz określonej zmiany z zintegrowanego żądania w projekt źródłowy).
- Dodawanie brakujących elementów
#include. - Małe i oczywiste poprawki kodu produktu (na przykład inicjowanie niezainicjowanej zmiennej).
- Wyłączanie zbędnych składników kompilacji vcpkg, takich jak testy lub przykłady.
Błędy zidentyfikowane przez SI w nowych portach
Wyselekcjonowany rejestr ma na celu uniknięcie dostarczania kodu zawierającego znane luki, ale osoby odpowiedzialne za program vcpkg nie mogą kompleksowo przeprowadzać inspekcji kodu źródłowego każdego składnika. Wyniki przeglądu kodu przez sztuczną inteligencję same w sobie nie są ostatecznym ustaleniem, że kod pochodzący z nadrzędnego źródła jest podatny na zagrożenia.
Gdy narzędzia sztucznej inteligencji do przeglądu kodu identyfikują usterkę podczas przeglądu zgłoszenia nowego portu, osoby odpowiedzialne za program vcpkg wymagają zgłoszenia usterki do projektu źródłowego, postępując zgodnie z procesem raportowania zabezpieczeń projektu w przypadku usterek potencjalnie możliwych do wykorzystania. To wymaganie ma zastosowanie nawet wtedy, gdy ustalenie dotyczy kodu upstream, którego port nie łata.
- Jeśli upstream ustali, że zgłoszone zachowanie nie jest usterką, osoby odpowiedzialne za vcpkg uznają to ustalenie za ostateczne i nie odrzucają zgłoszenia nowego portu na podstawie tego ustalenia.
- Jeśli upstream naprawi usterkę, osoby odpowiedzialne za program vcpkg akceptują poprawioną wersję lub poprawkę zatwierdzoną przez upstream, z zastrzeżeniem zasad stosowania poprawek i innych wymagań dotyczących nowych portów.
- Jeśli upstream nie odpowie w ciągu 30 dni po zgłoszeniu usterki, osoby odpowiedzialne za program vcpkg domyślnie traktują ustalenie przez SI jako problem możliwy do wykorzystania i zamykają zgłoszenie nowego portu.
Wyjątki od okresu oczekiwania na poprawkę uznane z dużą pewnością nie wyłączają tego wymagania dotyczącego zgłaszania błędów ani potrzeby odpowiedzi od projektu upstream.
Preferuj opcje stosowania poprawek
Preferowane jest ustawianie opcji w wywołaniu vcpkg_configure_xyz() niż bezpośrednie wprowadzanie zmian w ustawieniach.
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
find_package(XYz)w skryptach CMake można wyłączyć za pomocą-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 parametruFORCEdoset(). Aby uzyskać więcej informacji, zobacz dokumentację CMakeset
Preferuj pobieranie zatwierdzonych poprawek zamiast umieszczania ich w porcie.
Jeśli można uzyskać zatwierdzoną lub scaloną poprawkę z commitu w repozytorium nadrzędnym, pobierz ją i zastosuj zamiast dodawać jej do portu. Ten proces jest zalecany, ponieważ:
- Potwierdza, że upstream zaakceptował zmiany w poprawce.
- Upraszcza proces przeglądu, przenosząc odpowiedzialność na wcześniejszy etap.
- Zmniejsza rozmiar repozytorium vcpkg dla użytkowników, którzy nie korzystają z poprawki.
- Zapobiega konfliktom licencji z repozytorium vcpkg.
Pobierz poprawki tylko z adresów URL przypiętych do pełnego identyfikatora zatwierdzenia, a nie z adresów URL diffów pull requestów lub merge requestów, których zawartość może ulec zmianie. Podczas pobierania łatki commita z GitHub lub GitLab dołącz ?full_index=1 do adresu URL. Ten parametr żąda pełnych identyfikatorów obiektów w różnicy; nie sprawia, że modyfikowalny adres URL staje się niezmienny.
Na przykład:
Preferuj stosowanie łat zamiast nadpisywania 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 wbudowanych vcpkg łańcuchów narzędziowych działa, ponieważ wartość VCPKG_<LANG>_FLAGS jest przekazywana do odpowiedniej zmiennej CMAKE_<LANG>_FLAGS. Jednak niestandardowy łańcuch narzędzi, który nie jest świadomy zmiennych vcpkg, nie będzie ich przekazywać 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 instrukcji warunkowej lepiej jest dodać AND FALSE lub && 0 do warunku niż usunąć każdy wiersz instrukcji warunkowej. Jeśli duży region musi być wyłączony, łatwiej jest dodać if(0) lub #if 0 wokół regionu 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 zamiast poprawiania nieaktualnych wersji.
Pomaga to zmniejszyć rozmiar repozytorium vcpkg oraz zwiększa prawdopodobieństwo, że poprawka będzie pasować 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 przestrzegać odpowiedniej procedury open source (zgłaszanie problemu/wniosku o połączenie 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:
if(VCPKG_TARGET_IS_WINDOWS)
vcpkg_check_linkage(ONLY_STATIC_LIBRARY)
endif()
Nie zmieniaj nazw plików binarnych na inne niż nazwy nadane przez źródło
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ć przemianowane po kompilacji, ponieważ przerywa to wygenerowane pliki 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 próśb o dodanie trójek niezwiązanych ze społecznością. Promocja ze społeczności do pełnego statusu trójki opiera się głównie na budżecie przeznaczonym na testowanie sprzętu i będzie napędzana przez metryki dostarczone przez vcpkg, aby zmaksymalizować prawdopodobieństwo, że to, czego ludzie faktycznie używają, jest w pełni przetestowane.
Dodamy trójki 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 trójki w https://github.com/microsoft/vcpkg/pull/29034, ponieważ autor po prostu próbował "ukończyć zestaw", zamiast wskazać, że rzeczywiście użyje takiego elementu, a my nie dodaliśmy linux-dynamic, dopóki rozwiązanie patchelf umożliwiające przenoszenie wyników nie zostało stworzone.
Przydatne uwagi dotyczące implementacji
Pliki portów są uruchamiane w trybie skryptu
Chociaż pliki portfile.cmake i CMakeLists.txt mają wspólną składnię i podstawowe konstrukcje języka CMake (znane również jako "Scripting Commands"), portfiles działają w trybie skryptowym, podczas gdy pliki CMakeLists.txt działają w trybie projektowym. Najważniejszą różnicą między tymi dwoma trybami jest to, że "Tryb skryptu" nie przewiduje koncepcji "łańcucha narzędziowego", "języka" i "celu". 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 triplet, ale CMakeLists.txts już nie (chociaż często odbywa się jakieś tłumaczenie — VCPKG_LIBRARY_LINKAGE versus 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ą trypletów, aby uzyskać pełne wyliczenie możliwych ustawień.