Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Tento dokument popisuje zásady, pokyny a osvědčené postupy, které je potřeba dodržovat při přispívání do vcpkg.
Má sloužit stejné roli jako:
Kurátorované cíle návrhu registru
Porty musí být nainstalovány současně.
Port zahrnutý v kurátorovaném registru se musí úspěšně sestavit v přítomnosti všech ostatních portů v registru. Automatická CI vcpkg pravidelně testuje celou kombinaci portů.
Port nesmí provádět žádnou z následujících věcí:
- Nainstalujte soubory, které jsou v konfliktu s jiným portem.
- Nainstalujte symboly a definice vlastněné jiným balíčkem.
- Otestujte přítomnost nebo nepřítomnost jiného portu. S výjimkou deklarování závislosti.
Výjimky jsou provedeny pro:
- Porty, které nahrazují další v oficiální funkci. Následnický projekt.
- Porty, ve kterých se žádná platforma nepřekrývá. Například náhrada určená pouze pro Windows pro linuxový projekt, který nepodporuje Windows.
- Porty, které předcházejí zavedení této zásady a mají prokazatelně velký počet uživatelů a přispěvatelů.
Porty, které nevyhovují této zásadě, nelze přijmout do kurátorovaného registru.
Návod
Pokud váš port není možné zahrnout do kurátorovaného registru, zvažte publikování vlastního registru nebo použití překryvného portu.
Porty musí být testovány alespoň v jedné oficiální trojici.
Všechny porty v kurátorovaném registru musí být testovány v CI alespoň pro jeden oficiální triplet.
Výjimky jsou provedeny pro:
- Dočasné okolnosti, například:
- Port se nevystaví bez aktualizace infrastruktury CI.
- Port se nevystaví kvůli nedávné zásadní změně v upstreamové závislosti a probíhá práce na vyřešení situace.
- Porty, které předcházejí této zásadě a mají prokazatelně velký počet uživatelů a přispěvatelů.
Nové porty, které nelze testovat alespoň v jednom oficiálním trojitém kódu, nejsou do kurátorovaného registru přijaty. Stávající porty, které již této zásadě nevyhovují a nejsou dočasně vyňaty, se vyřadí z registru.
Návod
Pokud váš port není možné zahrnout do kurátorovaného registru, zvažte publikování vlastního registru nebo použití překryvného portu.
Zabalené projekty by měly být stabilní a aktivně udržované
Projekty zahrnuté ve spravovaném registru musí být aktivně udržovány. Porty pro neaktivní projekty mohou být vyřazeny ze seznamu.
Projekt se považuje za neaktivní, pokud:
- Správci projektu deklarovali, že projekt opustili.
- Archivuje se nebo už nepřijímá příspěvky.
- Správci nejsou nereagující nebo nedostupní.
- Dlouho nebyly provedeny žádné smysluplné změny.
Výjimky se provádějí u základních projektů, které jsou považovány za vyspělé a stabilní a často neobdrží změny.
Například: zlib.
Projekty formou balíčku by měly být vyspělé
Projekty zabalené v kurátorovaném registru musí být dospělé a určené pro použití uživateli nástroje vcpkg. Projekty určené pro osobní použití by měly být publikovány ve vlastních registrech.
Projekt je považován za dostatečně vyspělý pro kurátorovaný registr, pokud je jeden z těchto tvrzení pravdivý:
- Projekt má vydání, které je alespoň šest měsíců staré.
- Projekt ukazuje alespoň šest měsíců aktivního veřejného vývoje.
- Projekt je oficiální součástí jiného projektu, který splňuje předchozí požadavky. Například nová knihovna Boost nebo součást Qt.
- Projekt ukazuje ekvivalentní vyspělost předchozích požadavků v některé jiné kapacitě.
Mezi indikátory neměnnosti projektu patří:
- Projekt se nezobrazuje ve vyhledávacích webech.
- Projekt se často přejmenovává.
- Konflikty s jinými knihovnami
Návod
Pokud váš port není možné zahrnout do kurátorovaného registru, zvažte publikování vlastního registru nebo použití překryvného portu.
Struktura pull requestu
Vytvoření samostatných žádostí o přijetí změn na port
Menší žádosti o přijetí změn (PR) se snadněji kontrolují. Žádosti o pull request by měly provádět změny v jednom portu. Tím se také zkracují doby čekání na výsledky kontinuální integrace (CI).
Omezení pull requestů na jeden port nemusí být v některých případech možné. Například při změně portu je potřeba aktualizovat nebo opravit podřízené uživatele.
Vyhněte se triviálním změnám v nedotčených souborech.
Neprovádějte triviální změny v jinak neupraveném portu, jako je například přeformátování, přejmenování proměnných nebo oprava překlepů. Jakákoli změna, která nemá vliv na výstup instalace portu, se považuje za triviální. Triviální změny spotřebovávají výpočetní dobu lépe využitou jinak.
Použití výrazných názvů portů
Název portu by měl být orientačním názvem jeho obsahu.
Hledání názvu portu ve vyhledávacím webu nebo specializovaném prohlížeči balíčků, jako je Repology, by mělo vést k odpovídajícímu projektu.
Porty s krátkými názvy nebo pojmenovanými po běžných slovech vyžadují nejednoznačnost. To platí jenom pro název portu v kurátorovaném registru, název zabaleného projektu a jeho obsah nejsou nutné, aby byly v souladu s touto zásadou.
Výjimky jsou činěny pro porty, které mají projekt úzce spojený s jeho názvem. Například: libpng, opensslnebo zlib.
Pro splnění této zásady můžou nové porty s nejednoznačnými názvy používat předponu, například:
- Vlastník, uživatelské jméno nebo organizace úložiště. Příklad:
google-cloud-cpp. Pro porty projektů GitHubu je vlastník na GitHubu přijatelným jednoznačným prefixem<github owner>-<repository name>. - Název sady, do které balíček patří:
boost-dll. Pouze pokud je balíček oficiální součástí takové sady.
Příklad: Nejednoznačný název portu
Port s názvem ip se považuje za nejednoznačný, protože:
- jméno je příliš krátké,
- název je společné slovo a
- název není silně přidružený k žádnému jednotnému projektu.
Pokud chcete zjistit, jestli je název nejednoznačný, odeberte z názvu portu následující běžné předpony a přípony používané V++ a opensourcovými projekty:
cppfreelibopen- číslice
Například: ip-cppa libipip5, jsou nejednoznačné, protože jsou sníženy na stejný ip kmen.
Omezení přejmenování portů
Aby nedocházelo k nejasnostem pro uživatele, nelze porty přejmenovat až po jednom roce jejich posledního přejmenování.
Používejte koncepty žádostí o přijetí změn na GitHubu
Koncept pull requestů na GitHubu představují skvělý způsob, jak získat CI nebo osobní zpětnou vazbu ke své práci, která ještě není připravená ke sloučení. Většina nových PR by měla být otevřena jako návrhy a po úspěšném průchodu CI by měly být převedeny na normální PR.
Další informace o konceptu žádosti o přijetí změn na GitHubu najdete v Úvodu k konceptům žádostí o přijetí změn.
Tým vcpkg může vaši žádost o přijetí změn během procesu kontroly převést na návrh. Obvykle s požadavkem na provedení změn ve vašem kódu nebo komentáře, označující, kdy se má PR označit jako připravené ke kontrole.
Zavření neaktivních žádostí o přijetí změn
Tým vcpkg může uzavřít pull requesty, které nejsou aktivní déle než 60 dní.
Pro žádosti o přijetí změn, které jsou ve stavu vhodném pro revizi, se odpočet začíná od posledního okamžiku, kdy správce vcpkg požádá o změny nebo vysvětlení. Pokud přispěvatel do 60 dnů neudělá žádnou aktivitu, považuje se PR za zastaralý a může být uzavřen dle uvážení týmu.
Žádost o přijetí změn je v revidovatelném stavu, když:
- Nemá žádné neúspěšné kontroly PR, nebo přispěvatel požádá o pomoc či odůvodní selhání.
- Nemá žádné nevyřízené požadované změny ani objasnění od správce vcpkg.
- Nemá konflikty při slučování.
Žádosti o přijetí změn neaktivní po dobu delší než 60 dnů a nejsou ve stavu k posouzení mohou být uzavřeny bez posouzení.
Soubory portů
Vyhněte se zastaralým pomocným funkcím
V tuto chvíli jsou následující pomocníci zastaralí:
-
vcpkg_extract_source_archive_ex()by mělo být nahrazeno podporovaným přetíženímvcpkg_extract_source_archive()(sARCHIVE) - Zastaralé přetížení
vcpkg_extract_source_archive()bezARCHIVEby mělo být nahrazeno podporovaným přetížením .ARCHIVE -
vcpkg_apply_patches()by mělo být nahrazeno argumentyPATCHESdo pomocných funkcí "extrakce" (např.vcpkg_from_github()) -
vcpkg_build_msbuild()by měla být nahrazenavcpkg_install_msbuild() -
vcpkg_copy_tool_dependencies()by měla být nahrazenavcpkg_copy_tools() -
vcpkg_configure_cmakeby měla být nahrazenavcpkg_cmake_configure()po odebráníPREFER_NINJA -
vcpkg_build_cmakeby měla být nahrazenavcpkg_cmake_build() -
vcpkg_install_cmakeby měla být nahrazenavcpkg_cmake_install() -
vcpkg_fixup_cmake_targetsby měla být nahrazenavcpkg_cmake_config_fixup
Některé náhradní pomocné funkce jsou v "portech nástrojů", což uživatelům umožňuje připnout jejich chování ke specifickým verzím a uzamknout ho tak na jednom místě. Porty nástrojů je potřeba přidat do portu "dependencies", například takto:
{
"name": "vcpkg-cmake",
"host": true
},
{
"name": "vcpkg-cmake-config",
"host": true
}
Vyhněte se nadměrným komentářům v souborech portů
V ideálním případě by měly být soubory portů krátké, jednoduché a co nejvíce deklarativní.
Před odesláním pull requestu odeberte všechny šablonové komentáře zavedené create příkazem.
Používejte malá písmena pro řetězce šestnáctkových číslic
Mnoho funkcí vcpkg spoléhá na porovnání řetězců šestnáctkových číslic. Mezi příklady patří mimo jiné hodnoty hash SHA512, ID potvrzení Gitu a hodnoty hash objektů stromu.
Interně vcpkg používá pro porovnání těchto hodnot normalizaci malých písmen, kde je význam velikosti písmen irelevantní. Nástroje založené na infrastruktuře vcpkg ale nemusí brát v úvahu stejné aspekty. Z tohoto důvodu vyžadujeme šestnáctkové řetězce.
být psáno malými písmeny pro konzistenci v následujících scénářích:
- Parametr
SHA512v pomocných funkcích vcpkg. - Parametr
REFv pomocných funkcích vcpkg, pokud má hodnotu šestnáctkového řetězce. - Objekt
git-treev souborech databáze verzí. - Objekt
sha512vscripts/vcpkg-tools.jsonsouboru. - Jiná místa, kde je velikost písmen šestnáctkového řetězce nedůležitá.
Porty nesmí být závislé na cestě.
Porty nesmí měnit své chování na základě toho, které již porty jsou nainstalovány způsobem, který by změnil obsah nainstalovaný portem. Například:
> vcpkg install a
> vcpkg install b
> vcpkg remove a
a
> vcpkg install b
soubory nainstalované prostřednictvím b musí být stejné, bez ohledu na vliv předchozí instalace a. To znamená, že se porty před provedením určité akce nesmí pokusit zjistit, zda je něco v nainstalovaném stromu přítomno jiným portem. Konkrétní a běžná příčina takového chování "závislé na cestě" je popsána níže v části "Při definování funkcí, explicitně řídit závislosti".
Jedinečné pravidlo přiřazení portů
V celém systému vcpkg se očekává, že žádné z dvou portů, které uživatel bude používat souběžně, nesmí poskytovat stejný soubor. Pokud se port pokusí nainstalovat soubor, který už poskytuje jiný soubor, instalace se nezdaří. Pokud port chce pro hlavičku použít extrémně běžný název, měl by například umístit tato záhlaví do podadresáře, nikoli do include.
Tato vlastnost se pravidelně kontroluje prostřednictvím běhů kontinuální integrace, které se pokoušejí nainstalovat všechny porty v registru, což se nezdaří s FILE_CONFLICTS, pokud se dva porty pokusí poskytnout stejný soubor.
Přidání exportů CMake do neoficiálního oboru názvů
Základním designem, který je ideální pro vcpkg, je nevytvořovat "lock-in" pro uživatele. V systému sestavení by neměl existovat žádný rozdíl mezi v závislosti na knihovně ze systému a v závislosti na knihovně z vcpkg. Za tímto účelem se vyhneme přidávání exportů nebo cílů CMake do existujících knihoven se "zjevným názvem", abychom umožnili upstreamům přidávat vlastní oficiální exporty CMake bez konfliktu s vcpkg.
Za tímto účelem by všechny konfigurace CMake, které export portů, které nejsou v nadřazené knihovně, měly mít unofficial- jako předponu. Všechny další cíle by měly být v unofficial::<port>:: oboru názvů.
To znamená, že by měl uživatel vidět:
-
find_package(unofficial-<port> CONFIG)jako způsob, jak se dostat k balíčku unique-to-vcpkg -
unofficial::<port>::<target>jako exportovaný cíl z daného portu.
Příklady:
-
brotlivytvoří balíčekunofficial-brotli, což má za následek cílunofficial::brotli::brotli.
Instalace souboru autorských práv
Každý port musí poskytnout soubor pojmenovaný copyright ve složce ${CURRENT_PACKAGES_DIR}/share/${PORT}. Pokud je obsah licence balíčku k dispozici ve zdrojových souborech, měl by být tento soubor vytvořen voláním vcpkg_install_copyright().
vcpkg_install_copyright v případě potřeby také zahrnuje více souborů autorských práv.
vcpkg_install_copyright(FILE_LIST "${SOURCE_PATH}/LICENSE")
Starší metoda ručního vytvoření tohoto souboru je pomocí integrovaného file příkazu CMake. To se nedoporučuje ve prospěch použití vcpkg_install_copyright v nových portech, je však stále povoleno.
file(INSTALL "${SOURCE_PATH}/LICENSE" DESTINATION "${CURRENT_PACKAGES_DIR}/share/${PORT}" RENAME copyright)
Pokud obsah licence v upstreamových zdrojových souborech není v textové podobě (např. soubor PDF), copyright měl by obsahovat vysvětlení, jak uživatel může najít licenční požadavky. Pokud je to možné, měl by obsahovat také odkaz na původní zdrojové soubory, které to označují, aby uživatelé mohli zkontrolovat, jestli je aktuální.
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
]])
Omezení verzí na portech
Omezení verzí v portech by se obecně měla vyhnout, protože mohou bránit nezávislému vývoji projektů. Přidání takových omezení je přípustné pouze v případě, že existuje dobře zdokumentované odůvodnění, jako je například prokázáno nekompatibilitu s konkrétními dřívějšími verzemi. Tato omezení by se neměla používat pouze k zachování parity s nezávislými projekty.
Proměnné se MAYBE_UNUSED_VARIABLES musí vztahovat alespoň na jednu konfiguraci.
Když přidáváte novou proměnnou do MAYBE_UNUSED_VARIABLES s cílem ztlumit upozornění během kroku konfigurace v CMake, je nutné přidat komentář, který vysvětluje, kdy se nová proměnná použije. Pokud se proměnná nepoužije v žádné konfiguraci, je velmi pravděpodobné, že existuje základní chyba (například název chybně napsané proměnné) a jeho přidání nemá žádný skutečný vliv na sestavení.
vcpkg_check_features(OUT_FEATURE_OPTIONS FEATURE_OPTIONS
FEATURES
windowsfeature WINDOWS_OPTION
)
vcpkg_configure_cmake(
SOURCE_PATH "${SOURCE_PATH}"
OPTIONS
${FEATURE_OPTIONS}
MAYBE_UNUSED_VARIABLES
# Applies only on Windows
WINDOWS_OPTION
)
Funkce
Nepoužívejte funkce k implementaci alternativ
Funkce musí být považovány za doplňkové funkce. Pokud se nainstaluje port[featureA] a nainstaluje port[featureB], musí se nainstalovat port[featureA,featureB]. Navíc, pokud druhý port závisí na [featureA] a třetí port závisí na [featureB], instalace druhého i třetího portu by měla mít své závislosti splněné.
Knihovny v této situaci musí zvolit jednu z dostupných možností vyjádřených vcpkg a uživatelé, kteří chtějí jiné nastavení, musí v tuto chvíli používat překryvné porty.
Stávající příklady, které bychom dnes nepřijali, jsou zachovány kvůli zpětné kompatibilitě.
-
libgit2,libzipopen62541všechny mají funkce pro výběr protokolu TLS nebo kryptografického back-endu.curlmá různé možnosti kryptografického back-endu, ale umožňuje vybrat mezi nimi za běhu, což znamená, že se udržuje výše uvedený tenet. -
darknetmáopencv2,opencv3funkce pro řízení toho, kterou verzi opencv použít pro své závislosti.
Funkce může zapojit funkci ve verzi Preview nebo beta.
Bez ohledu na výše uvedené platí, že pokud existuje větev ve verzi Preview nebo podobná, ve které je s vysokou pravděpodobností zajištěno, že funkčnost bez verze Preview nebude narušena (například nedojde k odebrání rozhraní API), je pro modelování tohoto nastavení přijatelná vlastnost.
Příklady:
- Sady Azure SDK (v podobě
azure-Xxx) majípublic-previewfunkci. -
imguiexperimental-dockingmá funkci, která aktivuje dokovací větev předběžné verze, která používá sloučovací potvrzení připojené ke každé veřejné číslované verzi.
Výchozí funkce nesmí přidávat rozhraní API.
Poznámka:
Funkce, kterou povoluje systém sestavení upstream ve výchozím nastavení, neznamená, že by měla být přidána do default-features položek. Vzhledem k tomu, že zamýšleným účelem default-features není modelovat rozhodnutí provedená upstreamem, ale poskytovat pohodlí pro uživatele klasického režimu .
Výchozí funkce jsou určené k zajištění toho, aby bylo možné nainstalovat přiměřeně funkční sestavení knihovny pro zákazníky, kteří o něm neví, že ji používají. Pokud neví, že používají knihovnu, nemohou vědět, jaké funkce vyjmenovat.
libarchive Například zveřejňuje funkce, které umožňují komprimační algoritmy stávajícímu obecnému rozhraní; pokud je sestavena bez těchto funkcí, knihovna nemusí mít žádný nástroj.
Je nutné pečlivě zvážit, jestli má být funkce ve výchozím nastavení zapnutá, protože zakázání výchozích funkcí je složité.
Zakázání výchozí funkce jako tranzitivního příjemce vyžaduje:
- Všichni zákazníci, kteří explicitně deaktivují výchozí funkce prostřednictvím
"default-features": falsenebo zahrnují[core]do seznamu funkcí na příkazovém řádku. - Pojmenování tranzitivní závislosti na příkazovém
vcpkg installřádku nebo jako přímá závislost v manifestu nejvyšší úrovně
Pokud ve kurátorovaném registru vcpkg přidá funkce další rozhraní API, spustitelné soubory nebo jiné binární soubory, musí být ve výchozím nastavení vypnutá. Pokud máte pochybnosti, neoznamujte funkci jako výchozí.
Nepoužívejte funkce k řízení alternativ v publikovaných rozhraních.
Pokud příjemce portu závisí pouze na základních funkcích tohoto portu, s vysokou pravděpodobností nesmí být přerušen zapnutím této funkce. To je ještě důležitější, pokud alternativu přímo neřídí příjemce, ale nastavení kompilátoru, jako je /std:c++17 / -std=c++17.
Stávající příklady, které bychom dnes nepřijali, jsou zachovány kvůli zpětné kompatibilitě.
-
redis-plus-plus[cxx17]řídí polyfill, ale nezabuduje nastavení do nainstalovaného stromu. -
ace[wchar]změní všechna rozhraní API tak, aby přijímalaconst wchar_t*místoconst char*.
Vlastnost může nahradit polyfilly aliasy, za předpokladu, že je toto nahrazení integrováno do nainstalovaného stromu.
Bez ohledu na výše uvedené mohou porty odebrat polyfilly s funkcí, pokud:
- Aktivace této funkce změní polifyly tak, aby fungovaly jako aliasy polifylované entity.
- Stav polyfillu je integrován do instalovaných hlaviček, takže chyby runtime kvůli neshodě ABI jsou nepravděpodobné.
- Příjemce portu může napsat kód, který funguje v obou režimech, například pomocí typedef, který je buď plněný, nebo ne.
Příklad:
-
abseil[cxx17]měníabsl::string_viewna náhradu nebostd::string_view; oprava, která implementuje požadavek na pečení.
Doporučená řešení
Pokud je důležité zveřejnit podkladové alternativy, doporučujeme, abyste uživateli v době sestavení poskytli pokyn, jak zkopírovat port do privátního překrytí:
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")
Techniky sestavování
Nepoužívejte závislosti s dodavatelem.
Nepoužívejte vložené kopie knihoven. Všechny závislosti by se měly rozdělit a zabalit samostatně, aby se mohly aktualizovat a udržovat.
Závislosti spravované dodavateli představují několik výzev, které jsou v konfliktu s cíli systému vcpkg poskytovat spolehlivý, konzistentní a udržovatelný systém správy balíčků.
Potíže s aktualizacemi: Vložené kopie knihoven znesnadňují sledování a aplikování aktualizací, včetně oprav zabezpečení, z upstreamových projektů. To vede k potenciálním bezpečnostním rizikům a zastaralým závislostem v ekosystému.
Konflikty symbolů: Dodávané závislosti mohou způsobit konflikty symbolů, pokud více balíčků obsahuje různé verze stejné knihovny.
Příklad: Pokud balíček A obsahuje knihovnu X (verze 1) a balíček B obsahuje knihovnu X (verze 2), aplikace propojující oba balíčky může zaznamenat chyby za běhu nebo nedefinované chování z důvodu konfliktních symbolů.
Díky samostatnému balení závislostí zajišťuje vcpkg, že se ve všech balíčcích používá jedna verze knihovny a eliminuje tak takové konflikty.
Dodržování licenčních předpisů: Závislosti spravované dodavateli mohou zastřít licencování vložených knihoven a potenciálně porušovat jejich podmínky nebo způsobovat problémy s kompatibilitou.
Zvýšená zátěž údržby: Udržování závislostí dodavatelů v synchronizaci s jejich nadřazenými verzemi vyžaduje značné ruční úsilí a často vede k duplikování práce napříč balíčky.
Preferovat používání CMake
Pokud je k dispozici více systémů sestavení, raději použijte CMake.
Pokud je to vhodné, může být jednodušší a lépe udržovatelné přepisovat alternativní buildsystemy do CMake pomocí file(GLOB) direktiv.
Příklady: abseil
Volba statických nebo sdílených binárních souborů
Při sestavování knihoven v CMake předá vcpkg_cmake_configure() na BUILD_SHARED_LIBS správnou hodnotu podle varianty, kterou požaduje uživatel.
Alternativní parametry konfigurace můžete vypočítat pomocí .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}
)
Pokud knihovna nenabízí možnosti konfigurace pro výběr varianty sestavení, musí být sestavení opraveno. Při opravách sestavení byste se vždy měli pokusit maximalizovat budoucí udržovatelnost portu. Obvykle to znamená minimalizaci počtu řádků, které je potřeba upravit, aby se problém vyřešil.
Příklad: Oprava knihovny CMake, aby se zabránilo vytváření nežádoucích variant
Například při opravě knihovny založené na CMake může být dostačující přidat EXCLUDE_FROM_ALL do nežádoucích cílů a zabalit volání install(TARGETS ...) do if(BUILD_SHARED_LIBS). Bude to kratší než zabalení nebo odstranění každého řádku, který obsahuje nežádoucí variantu.
Pro projekt CMakeLists.txt s následujícím obsahem:
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)
Je potřeba opravit pouze čáru install(TARGETS) .
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)
Při definování funkcí explicitně řídit závislosti
Při definování funkce, která zachycuje volitelnou závislost, zajistěte, aby se závislost nepoužívala náhodně, pokud tato funkce není explicitně povolená.
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}
)
Následující úryvek používající vcpkg_check_features() je ekvivalentní.
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 v fragmentu kódu se rozlišují malá a velká písmena. Další informace najdete v dokumentaci CMAKE_DISABLE_FIND_PACKAGE_<PackageName> a CMAKE_REQUIRE_FIND_PACKAGE_<PackageName>.
Umístění konfliktních knihoven v manual-link adresáři
Knihovna je považována za konfliktní, pokud provede některou z následujících věcí:
- Definuj
main - Definujte malloc
- Definujte symboly, které jsou deklarovány také v jiných knihovnách.
Konfliktní knihovny jsou obvykle navrženy a nejsou považovány za vadu. Vzhledem k tomu, že některé buildové systémy odkazují na všechno v adresáři lib, měly by být přesunuty do podadresáře s názvem manual-link.
Instalace předem připravených binárních souborů
Porty, které instalují předem připravené artefakty (pouze binární soubory), jsou povolené, ale důrazně se nedoporučuje, pokud efektivně neblokují změnu verzí jiných portů. Kompilace ze zdrojového kódu je upřednostňovaná, protože respektuje všechna nastavení vcpkg, která mění kompilátor nebo příznaky.
Porty, které splňují všechny následující podmínky, odmítneme:
- Instalace předem připravených binárních souborů místo sestavení ze zdroje a
- Tyto binární soubory mají (nebo vyžadují za běhu) závislosti poskytované jinými porty v kurátorovaném registru a
- Nainstalované artefakty vstupují do publikované domény odkazů vcpkg, tj. instalují knihovny, hlavičky/CMake nebo metadata pkg-config, na které se očekává, že se budou odkazovat podřízené porty nebo uživatelské projekty.
Odůvodnění: Tato kombinace efektivně uzamkne ABI grafu závislostí na verze použité při vytváření předpřipraveného upstreamu. Vcpkg nemůže bezpečně aktualizovat (například) zlib, openssl nebo podobné závislosti, aniž by riskoval subtilní porušení ODR / ABI pro uživatele propojující se s předem zkompilovanou knihovnou. Uživatelé také mohou přijít o důležité bezpečnostní opravy.
"Zadá publikovanou doménu propojení" obvykle znamená některou z těchto možností:
-
.libInstalace , ,.a.so,.dylibnebo import knihoven určených pro uživatele, se kterými se mají propojit. - Záhlaví pro přenos, která odkazují (přímo nebo prostřednictvím vloženého kódu nebo kódu šablony) na symboly, typy nebo makra z jiných portů vcpkg.
- Instalace konfiguračních souborů CMake / pkg-config, které spouštějí
find_dependency()/Requires:na jiných portech vcpkg.
Povolené (ale i nadále se nedoporučuje) scénáře:
- Pomocné nástroje jen pro hostitele (spustitelné soubory) používané v době sestavení, jejichž výstupy se spotřebovávají, ale které nejsou propojeny závislými porty, za předpokladu, že jsou závislé buď soukromě, nebo spoléhají pouze na všudypřítomné systémové knihovny runtime.
- Plně obsažené předem připravené knihovny, které staticky propojují všechny závislosti operačního systému A nezpřístupňují jejich symboly ani typy prostřednictvím nainstalovaných hlaviček nebo exportovaných rozhraní (uživatelé nemohou sledovat nebo záviset na tranzitivním ABI).
- Balíčky pouze pro data, firmware nebo prostředky, které nejsou propojené s uživatelským kódem.
Zakázané příklady:
- Předem připravený
libfoo, který instalujelib/libfoo.libplus včetně hlaviček jako<zlib.h>a který byl zkompilován pro konkrétnízlibverzi; uživatelé pak propojí slibfoos očekáváním kompatibility. - Předem připravené SDK, které nainstaluje soubor balíčku CMake volající
find_dependency(OpenSSL), zatímco binární soubor byl zkompilován proti starší verzi OpenSSL.
Zmírnění rizik / alternativy:
- Poskytněte sestavení ze zdroje pomocí upstreamových skriptů nebo přidejte tenkou obálku CMake.
- Požádejte upstream o publikování zdrojové verze nebo pokyny pro reprodukovatelnou sestavu; odkazujte na problém nebo PR na upstreamu v komentáři v
portfile.cmakenebovcpkg.json. - Použijte overlay port nebo soukromý registr pro specifické předem připravené balíčky organizace, které tato pravidla nemohou splnit.
Vytváření verzí
Postupujte podle běžných konvencí pro "version" pole.
Při vytváření nového portu postupujte podle konvence správy verzí, kterou používá autor balíčku. Při aktualizaci portu pokračujte v používání stejné konvence, pokud není stanoveno jinak upstreamem. Úplné vysvětlení našich konvencí najdete v naší dokumentaci ke správě verzí.
Pokud upstream po nějakou dobu nepublikuje žádné vydání, nezměňte schéma správy verzí portu na version-date kvůli získání nejnovějších změn. Tyto commity můžou zahrnovat změny, které nejsou připravené pro produkci. Místo toho požádejte upstreamové úložiště, aby publikovalo novou verzi.
"port-version" Aktualizace pole v souboru manifestu u všech upravených portů
Vcpkg používá toto pole k určení, jestli je daný port zastaralý a má být změněn při každé změně chování portu.
Naší konvencí je použít "port-version" pole pro změny portu, který nemění nadřazenou verzi, a resetovat "port-version" zpět na nulu při aktualizaci upstreamové verze.
Příklad:
- cs-CZ: Verze balíčku Zlib je v současné době
1.2.1, bez explicitního"port-version"(s ekvivalentem"port-version"0). - Zjistili jste, že byl nasazen špatný soubor autorských práv, a opravili jste to v portfile.
- Pole v souboru manifestu
"port-version"byste měli aktualizovat na1.
Další informace najdete v dokumentaci k správě verzí.
Aktualizace souborů verzí u versions/ všech upravených portů
Vcpkg používá sadu souborů metadat k napájení funkce správy verzí. Tyto soubory jsou umístěné v následujících umístěních:
-
${VCPKG_ROOT}/versions/baseline.json, (tento soubor je společný pro všechny porty) a -
${VCPKG_ROOT}/versions/${first-letter-of-portname}-/${portname}.json(jeden na port).
Například pro zlib příslušné soubory:
${VCPKG_ROOT}/versions/baseline.json${VCPKG_ROOT}/versions/z-/zlib.json
Očekáváme, že pokaždé, když aktualizujete port, aktualizujete také jeho soubory verzí.
Doporučeným způsobem aktualizace těchto souborů je spuštění x-add-version příkazu, například:
vcpkg x-add-version zlib
Pokud současně aktualizujete více portů, můžete místo toho spustit:
vcpkg x-add-version --all
chcete-li aktualizovat soubory pro všechny upravené porty najednou.
Další informace najdete v článcích referenčního materiálu k verzování a rejstříky.
Opravy
vcpkg je balíčkovací řešení, ne koneční vlastníci komponent, které nasadíme. V některých případech musíme použít opravy, abychom zlepšili kompatibilitu komponent s platformami nebo kompatibilitu komponent s ostatními.
- Chceme se vyhnout opravám, které:
- "nadřazený nesouhlasil s"
- způsobit zranitelnosti nebo pády
- Nejsme schopni udržovat kontinuitu při aktualizacích upstreamových verzí
- jsou dostatečně velké, aby způsobily propletení licencí se samotným úložištěm vcpkg.
Upozorněte vlastníky upstreamu na relevantní opravy.
Pokud by oprava mohla být možná užitečná upstreamem, musí být upstream upozorněn na obsah opravy. (Opravy, které používají chování specifické pro vcpkg nesouvisející s upstreamem, jako je například odstranění závislosti, nevyžadují oznámení.)
Abychom se vyhnuli situacím, kdy upstream nesouhlasí s opravou, počkáme alespoň 30 dní na použití těchto oprav.
Pokud máme vysokou jistotu, že změna je správná, přeskočíme tuto čekací dobu. Mezi příklady oprav s vysokou spolehlivostí patří mimo jiné:
- Přijetí změny upstreamem jako záplaty (například zpětné portování konkrétní změny z žádosti o přijetí změn, kterou upstream sloučil).
- Přidání chybějících
#include. - Malé a běžné opravy kódu produktu (například inicializace neinicializované proměnné).
- Zakázání irelevantních součástí sestavení vcpkg, jako jsou testy nebo příklady.
Preferovat možnosti před opravami
Je lepší nastavit možnosti při volání s vcpkg_configure_xyz(), než přímo upravovat nastavení.
Běžné možnosti, které umožňují vyhnout se opravám:
- [MSBUILD]
<PropertyGroup>nastavení uvnitř souboru projektu lze přepsat pomocí/p:parametrů. - [CMAKE] Volání na
find_package(XYz)ve skriptech CMake lze zakázat prostřednictvím-DCMAKE_DISABLE_FIND_PACKAGE_XYz=ON - [CMAKE] Proměnné mezipaměti (deklarované jako
set(VAR "value" CACHE STRING "Documentation")nebooption(VAR "Documentation" "Default Value")) lze přepsat tím, že je jednoduše předáte na příkazovém řádku jako-DVAR:STRING=Foo. Jednou z výjimek je, pokud je parametrFORCEpředánset(). Další informace najdete v dokumentaci k CMakeset.
Preferujte stažení schválených záplat před jejich integrací do portu.
Pokud se schválený nebo sloučený soubor oprav dá získat z nadřazeného proudu, měly by se je porty pokusit stáhnout a použít je, a ne je použít jako součást souborů portů. Tento proces se upřednostňuje, protože:
- Potvrzuje, že upstream přijal změny v patchi.
- Zjednodušuje proces kontroly přesunutím odpovědnosti na začátek procesu.
- Zmenšuje velikost úložiště vcpkg pro uživatele, kteří nepoužívají opravu.
- Vyhne se konfliktům licencí s úložištěm vcpkg.
Opravy by se měly stáhnout ze stabilního koncového bodu, aby nedocházelo ke konfliktům SHA.
Při stahování souborů oprav z žádosti o přijetí změn nebo potvrzení z GitHubu a GitLabu ?full_index=1 by se měl parametr připojit k adrese URL pro stažení.
Příklady:
https://github.com/google/farmhash/pull/40.diff?full_index=1https://github.com/linux-audit/audit-userspace/commit/f8e9bc5914d715cdacb2edc938ab339d5094d017.patch?full_index=1https://gitlab.kitware.com/paraview/paraview/-/merge_requests/6375.diff?full_index=1
Preferovat opravy před přepsáním VCPKG_<VARIABLE> hodnot
Některé proměnné s předponou VCPKG_<VARIABLE> mají ekvivalentní CMAKE_<VARIABLE>.
Ne všechny z nich se však předávají internímu sestavení balíčku (viz implementace: sada nástrojů systému Windows).
Představte si následující příklad:
set(VCPKG_C_FLAGS "-O2 ${VCPKG_C_FLAGS}")
set(VCPKG_CXX_FLAGS "-O2 ${VCPKG_CXX_FLAGS}")
Při použití integrovaných nástrojových řetězců vcpkg to funguje, protože hodnota VCPKG_<LANG>_FLAGS je předána příslušné proměnné CMAKE_LANG_FLAGS. Ale vlastní sada nástrojů, která nebere v potaz proměnné vcpkg, je nepředá.
Z tohoto důvodu je vhodnější opravit systém sestavení přímo při nastavení CMAKE_<LANG>_FLAGS.
Minimalizace oprav
Při provádění změn v knihovně se snažte minimalizovat konečný rozdíl. To znamená, že při provádění změn, které mají vliv na oblast, byste neměli přeformátovat nadřazený zdrojový kód. Při vypínání podmínky je lepší přidat AND FALSE nebo && 0 k podmínce, než odstranit každý řádek podmínky. Pokud je potřeba vypnout velkou oblast, je kratší přidat if(0) nebo #if 0 kolem této oblasti místo odstranění každého řádku v opravě.
Nepřidávejte opravy, pokud je port zastaralý a aktualizace portu na novější vydanou verzi by vyřešila stejný problém. Vcpkg dává přednost aktualizaci portů před opravami zastaralých verzí.
To pomáhá udržet velikost úložiště vcpkg dolů a také zvyšuje pravděpodobnost, že oprava bude platit pro budoucí verze kódu.
Neimplementujte funkce v opravách
Účelem oprav vcpkg je umožnit kompatibilitu s kompilátory, knihovnami a platformami. Není určeno pro implementaci nových funkcí místo toho, aby se postupovalo podle správného postupu pro Open Source (odeslání problému, žádosti o přijetí úprav atd.).
Nevystavujte testy, dokumenty nebo příklady ve výchozím nastavení
Při odesílání nového portu zkontrolujte, zda existují nějaké možnosti, jako například BUILD_TESTS, WITH_TESTS nebo POCO_ENABLE_SAMPLES, a ujistěte se, že jsou další binární soubory zakázané. Tím se minimalizují doby sestavení a závislosti pro průměrného uživatele.
Volitelně můžete přidat test funkci, která umožňuje sestavování testů, ale tato funkce by neměla být v Default-Features seznamu.
Povolení přepnutí stávajících uživatelů knihovny na vcpkg
Nepřidávejte CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS
Pokud ji autor knihovny ještě nepoužívá, neměli bychom tuto funkci CMake používat, protože pracuje špatně se šablonami jazyka C++ a přeruší některé funkce kompilátoru. Knihovny, které neposkytují soubor .def a nepoužívají deklarace __declspec() jednoduše nepodporují sdílené sestavení pro Windows a měly by být označené takto:
if(VCPKG_TARGET_IS_WINDOWS)
vcpkg_check_linkage(ONLY_STATIC_LIBRARY)
endif()
Nepřejmenovávat binární soubory mimo názvy zadané upstreamem
To znamená, že pokud má upstreamová knihovna různé názvy ve vydané verzi a ladění (libx versus libxd), pak by ladicí knihovna neměla být přejmenována na libx. Naopak, pokud má upstreamová knihovna stejný název v release a debug verzi, neměli bychom zavádět nový název.
Důležitá výstraha:
- Statické a sdílené varianty by se často měly přejmenovat na společné schéma. To umožňuje spotřebitelům používat běžný název a nevědět o podřízeném propojení. To je bezpečné, protože je k dispozici pouze jeden po druhém.
Pokud knihovna generuje integrační soubory CMake (foo-config.cmake), je nutné přejmenování provést prostřednictvím oprav samotného sestavení CMake místo pouhého volání file(RENAME) do výstupních archivů nebo knihoven DLL.
A konečně, soubory DLL ve Windows by nikdy neměly být přejmenovány po sestavení, protože to přeruší vygenerované soubory LIB.
Manifesty
Vyžadujeme, aby byl soubor manifestu naformátovaný. Pomocí následujícího příkazu naformátujte všechny soubory manifestu:
> vcpkg format-manifest --all
Trojčata
V tuto chvíli nepřijímáme žádosti o přidání nekomunitních tripletů. Propagace z komunity na plný status tripletu je primárně založená na rozpočtu pro hardware potřebný k testování takových tripletů a bude řízena metrikami odeslanými vcpkg, aby se maximalizovala pravděpodobnost, že co lidé skutečně používají, je plně otestováno.
Přidáme trojité sady komunity za těchto podmínek:
- Ukázalo se, že lidé skutečně použijí tuto komunitní trojici; a
- Nevíme, že takový triplet je zlomený.
Například jsme nepřidali triplet https://github.com/microsoft/vcpkg/pull/29034, protože se autor snažil "dokončit sadu" spíše než aby naznačil, že by něco takového skutečně použil, a nepřidali jsme linux-dynamic, dokud nebylo vytvořeno řešení patchelf, které by učinilo výsledky přemístitelnými.
Užitečné poznámky k implementaci
Soubory portů se spouštějí v režimu skriptu.
I když portfile.cmake a CMakeLists.txt sdílejí společnou syntaxi a základní konstrukty jazyka CMake (takzvané "skriptovací příkazy"), soubory portů fungují v "režimu skriptu", zatímco CMakeLists.txt soubory běží v "režimu projektu". Nejdůležitější rozdíl mezi těmito dvěma režimy je, že režim skriptů nemá koncepty "Toolchain", "Language" a "Target". Jakékoli chování, včetně skriptovacích příkazů, které závisí na těchto konstruktorech (např. CMAKE_CXX_COMPILER, CMAKE_EXECUTABLE_SUFFIX, CMAKE_SYSTEM_NAME) nebudou správné.
Portfile má přímý přístup k proměnným nastaveným v souboru triplet, ale CMakeLists.txt ne (i když často dochází k překladu – VCPKG_LIBRARY_LINKAGE vs. BUILD_SHARED_LIBS).
Soubory portů a sestavení projektů vyvolané těmito soubory se spouštějí v různých procesech. Koncepčně:
+----------------------------+ +------------------------------------+
| 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) |
+----------------------------+ +------------------------------------+
Pokud chcete určit hostitele v souboru portu, jsou standardní proměnné CMake v pořádku (CMAKE_HOST_WIN32).
K určení cíle v souboru portu by se měly použít proměnné vcpkg triplet (VCPKG_CMAKE_SYSTEM_NAME).
Pro podrobný výčet možných nastavení se také podívejte do naší dokumentace tripletů.