Průvodce údržbou
Tento dokument obsahuje sadu zásad, které byste měli použít při přidávání nebo aktualizaci receptu na port. Má sloužit roli Příručky k zásadám Debianu, Homebrew's Maintainer Guidelines a Homebrew's Formula Cookbook.
Celkové cíle návrhu registru
Porty v aktuálním směrném plánu musí být instalovatelné současně.
Chceme být schopni zobrazit podřízené uživatele knihoven v kurátorovaném registru, že kombinace knihoven v libovolném směrném plánu, který publikujeme, byla testována tak, aby spolupracovala alespoň v některých konfiguracích. Když povolíte, aby se porty navzájem vyloučily, přeruší možnost testovat takové konfigurace, protože počet sestavení nezbytných pro takové testy by se zvětšil jako 2^number_of_such_cases
. Instalace dalších závislostí je navíc vždy považována za "bezpečnou": neexistuje způsob, jak port nebo koncový uživatel uplatnit, že závislost není nainstalovaná ve svých požadavcích.
Pokud chcete uživatelům představit takovou alternativní situaci, zvažte popis toho, jak může někdo vytvořit překryvný port implementující alternativní formulář s komentářem portfile.cmake
a nepokoušejte se přidávat další porty nikdy integrované v kontinuální integraci kurátorovaného registru. Například viz glad@0.1.36.
Před zavedením registrů jsme přijali několik neotestovaných portů jako alternativ, například boringssl
, které by mohly usnadnit vytváření překryvných portů. Tato možnost už není přijata, protože registry umožňují publikování těchto neotestovaných portů beze změny kurátorovaného registru.
Struktura žádosti o přijetí změn
Vytvoření samostatných žádostí o přijetí změn na port
Kdykoli je to možné, oddělte změny do více žádostí o přijetí změn. To jim výrazně usnadňuje kontrolu a zabraňuje problémům s jednou sadou změn v uchovávání všech ostatních změn.
Vyhněte se triviálním změnám v nedotčených souborech.
Vyhněte se například přeformátování nebo přejmenování proměnných v souborech portů, které jinak nemají žádný důvod k úpravě problému. Pokud ale potřebujete upravit soubor pro primární účel žádosti o přijetí změn (aktualizace knihovny), jsou samozřejmě užitečné změny, jako je oprava překlepů.
Kontrola názvů v jiných úložištích
Názvy portů by se měly pokusit jednoznačně určit, který balíček se port nainstaluje. V ideálním případě by hledání názvu portu ve vyhledávacím webu mělo rychle vést k odpovídajícímu projektu. Dobrou službou pro kontrolu mnoha názvů balíčků napříč více úložišti najednou je repologie.
Projekty s krátkými názvy nebo pojmenovanými po běžných slovech mohou vyžadovat nejednoznačnost, zejména pokud neexistují žádné projekty se silným přidružením k danému slovu. Například port s názvem ip
není přijatelný, protože je pravděpodobné, že by se podobně jmenovalo více projektů.
Mezi příklady dobrých nejednoznačných hodnot patří:
- Uživatelské jméno nebo organizace vlastníka úložiště:
google-cloud-cpp
. - Název sady knihoven, které projekt tvoří:
boost-dll
.
Běžné předpony a přípony používané c++ a opensourcovými projekty nejsou platnými nejednoznačnými znaky, mezi příklady patří mimo jiné:
-
cpp
, -
free
, -
lib
, -
open
, - Čísla
Například při porovnávání následujících názvů portů a ip-cpp
libip
ip5
odebrání neplatných nejednoznačných výrazů se všechny zmenší na stejný kmen (ip
), a proto se považují za stejné jméno.
Výjimkou tohoto návodu jsou názvy, které jsou silně přidružené k jednomu projektu. Například: libpng
a openssl
zlib
.
Použití žádostí o přijetí změn konceptu GitHubu
Žádosti o přijetí změn konceptu GitHubu představují skvělý způsob, jak získat CI nebo lidskou zpětnou vazbu k práci, která ještě není připravená ke sloučení. Většina nových žádostí o přijetí změn by se měla otevřít jako koncepty a po průchodu CI by se měla převést na normální žádosti o přijetí změn.
Další informace o žádostech o přijetí změn konceptu GitHubu najdete v tématu Úvod k žádostem o přijetí změn.
Soubory portů
Vyhněte se zastaralým pomocným funkcím
V tuto chvíli jsou následující pomocné rutiny 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()
bezARCHIVE
by mělo být nahrazeno podporovaným přetížením .ARCHIVE
-
vcpkg_apply_patches()
by měly být nahrazenyPATCHES
argumenty pomocných rutin "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_cmake
by měla být nahrazenavcpkg_cmake_configure()
po odebráníPREFER_NINJA
-
vcpkg_build_cmake
by měla být nahrazenavcpkg_cmake_build()
-
vcpkg_install_cmake
by měla být nahrazenavcpkg_cmake_install()
-
vcpkg_fixup_cmake_targets
by měla být nahrazenavcpkg_cmake_config_fixup
Některé náhradní pomocné funkce jsou v "portech nástrojů", které uživatelům umožňují připnout jejich chování v konkrétních verzích, aby bylo možné uzamknout chování pomocných rutin v konkrétní verzi. 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 žádosti o přijetí změn odeberte všechny komentáře kotelny zavedené create
příkazem.
Porty nesmí být závislé na cestě.
Porty nesmí měnit jejich chování na základě toho, které porty jsou již nainstalovány ve formuláři, který by změnil obsah, který port nainstaluje. Například:
> vcpkg install a
> vcpkg install b
> vcpkg remove a
a
> vcpkg install b
soubory, které b
byly nainstalovány, 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, jestli je v nainstalovaném stromu poskytnutý 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é dva porty, které uživatel bude používat souběžně, může poskytnout 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 spuštěním kontinuální integrace, která se pokusí nainstalovat všechny porty v registru, což selže FILE_CONFLICTS
, pokud dva porty poskytují 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:
-
brotli
unofficial-brotli
vytvoří balíček, který vytváří 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é sbalí několik 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 vcpkg_install_copyright
nových portů, ale je 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.
Funkce
Nepoužívejte funkce k implementaci alternativ
Funkce musí být považovány za doplňkové funkce. Pokud port[featureA]
se nainstaluje a port[featureB]
nainstaluje, port[featureA,featureB]
musí se nainstalovat. 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 kvůli zpětné kompatibilitě, bychom dnes nepřijali:
-
libgit2
,libzip
open62541
všechny mají funkce pro výběr protokolu TLS nebo kryptografického back-endu.curl
má 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. -
darknet
hasopencv2
, ,opencv3
funkce pro řízení, 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é skutečnosti platí, že pokud existuje větev ve verzi Preview nebo podobná, ve které má funkce preview vysokou pravděpodobnost, že nenaruší funkčnost bez verze Preview (například bez odebrání rozhraní API), je pro modelování tohoto nastavení přijatelná funkce.
Příklady:
- Sady Azure SDK (ve formuláři
azure-Xxx
) majípublic-preview
funkci. -
imgui
experimental-docking
má funkci, která zapojuje dokovací větev ve verzi Preview, která používá potvrzení sloučení připojené k jednotlivým veřejným číslovaným verzím.
Výchozí funkce nesmí přidávat rozhraní API.
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 knihovnu používají, nemůžou znát funkce seznamu.
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 explicitně zakazují výchozí funkce prostřednictvím
"default-features": false
seznamu funkcí nebo 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 kvůli zpětné kompatibilitě, bychom dnes nepřijali:
-
redis-plus-plus[cxx17]
řídí polyfill, ale nezapeče nastavení do nainstalovaného stromu. -
ace[wchar]
změní všechna rozhraní API tak, aby přijímalaconst wchar_t*
místoconst char*
.
Funkce může nahradit polyfilly aliasy za předpokladu, že se nahrazení upeče do nainstalovaného stromu.
Bez ohledu na výše uvedené možnosti mohou porty odebrat polyfilly funkcí, pokud:
- Zapnutí funkce změní polyfills na aliasy polyfilled entity.
- Stav polyfillu se zapečí do instalovaných hlaviček, proto je nepravděpodobné, že chyby modulu runtime neshody ABI nejsou možné.
- 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]
změnyabsl::string_view
nahrazení nebostd::string_view
; oprava 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 vcpkg_cmake_configure()
CMake předá správnou hodnotu na BUILD_SHARED_LIBS
základě požadované varianty uživatele.
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ů, se kterými je potřeba problém vyřešit.
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 install(TARGETS ...)
volání do .if(BUILD_SHARED_LIBS)
Bude to kratší než zabalení nebo odstranění každého řádku, který zmíní 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í fragment kódu je vcpkg_check_features()
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>
v dokumentaci.
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í:
- Definovat
main
- Definování 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
.
Vytváření verzí
Postupujte podle běžných konvencí pro "version"
dané pole.
Při vytváření nového portu postupujte podle konvence správy verzí, kterou používá autor balíčku. Při aktualizaci portu používejte stejnou konvenci, pokud upstream nehlásí jinak. Úplné vysvětlení našich konvencí najdete v naší dokumentaci ke správě verzí.
Pokud upstream nějakou verzi nějakou dobu nepublikuje, nezměníte schéma správy verzí portu tak, aby version-date
získalo nejnovější změny. Tato potvrzení můžou zahrnovat změny, které nejsou připravené pro produkční prostředí. 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:
- Verze balíčku Zlib je v současné době
1.2.1
bez explicitního"port-version"
(ekvivalentu"port-version"
).0
- Zjistili jste, že byl nasazen nesprávný soubor autorských práv a opravený v souboru portu.
- 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.
Poznámka:
Tyto příkazy vyžadují, abyste před spuštěním těchto portů potvrdili změny portů. Důvodem je, že v těchto souborech verzí se vyžaduje SHA Gitu adresáře portů. Ale nemějte obavy, příkaz vás upozorní, x-add-version
pokud máte místní změny, které nebyly potvrzeny.
Další informace najdete v článcích referenčního materiálu k verzování a rejstříky.
Opravy
vcpkg je obalové řešení, ne konečné vlastníky 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é:
- upstream by nesouhlasil s
- způsobit ohrožení zabezpečení nebo chybové ukončení
- nemůžeme udržovat aktualizace upstreamových verzí
- jsou dostatečně velké, aby způsobily propletení licencí se samotným úložištěm vcpkg.
Upstreamoví vlastníci upstreamových oprav upstreamových oprav
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ří:
- Přijetí upstreamu jako opravy (například backportování konkrétní změny z upstreamu žádosti o přijetí změn bylo sloučeno).
- Přidání chybějících
#include
s. - 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 vhodnější nastavit možnosti při volání přes vcpkg_configure_xyz()
opravu nastavení přímo.
Běžné možnosti, které umožňují vyhnout se opravám:
- [MSBUILD]
<PropertyGroup>
nastavení uvnitř souboru projektu lze přepsat pomocí/p:
parametrů. - [CMAKE]
find_package(XYz)
Volání ve skriptech CMake je možné 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")
) je možné přepsat tak, že je jednoduše předáte na příkazovém řádku jako-DVAR:STRING=Foo
. Jednou z případných výjimek je, pokudFORCE
je parametr předánset()
. Další informace najdete v dokumentaci k CMakeset
.
Preferujte stažení schválených oprav před kontrolou 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:
- Potvrdí, že upstream přijal změny oprav.
- Zjednodušuje proces kontroly posunutím onus upstreamu.
- 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=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
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}")
Použití vcpkg
předdefinovaných nástrojů to funguje, protože hodnota VCPKG_<LANG>_FLAGS
je předána příslušné CMAKE_LANG_FLAGS
proměnné. Vlastní sada nástrojů, která o proměnných neví vcpkg
, je ale 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 zakazování podmíněného nastavení je lepší přidat AND FALSE
podmínku nebo && 0
do ní, než odstranit každý řádek podmíněného stavu. Pokud je potřeba zakázat velkou oblast, je kratší místo odstranění každého řádku v opravě přidat if(0)
oblast nebo #if 0
kolem ní.
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. Neimplementuje nové funkce, a to místo toho, abyste postupovali správně (odeslání problému, žádosti o přijetí změn atd.).
Nevystavujte testy, dokumenty nebo příklady ve výchozím nastavení
Při odesílání nového portu zkontrolujte všechny možnosti, jako BUILD_TESTS
je nebo WITH_TESTS
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é buildy pro Windows a měly by být označené jako takové vcpkg_check_linkage(ONLY_STATIC_LIBRARY)
.
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 ve vydané verzi a ladění, neměli bychom zavést 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 uživatelům používat běžný název a být negnorantní pro podřízené 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 přeruší vygenerované knihovny 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í nestejných tripletů. Propagace z komunity na plný stav trojitého trojití je primárně založená na rozpočtu hardwaru k otestování takových tripletů a bude řízena metrikami odeslaným vcpkg, aby se maximalizovala pravděpodobnost, že lidé skutečně používají plně otestované.
Pokud přidáme trojité sady komunity, přidáme:
- Ukázalo se, že lidé budou tuto komunitu používat ve skutečnosti trojité; a
- Nevíme, že takový triplet je zlomený.
Například jsme nepřidali triplet https://github.com/microsoft/vcpkg/pull/29034 , protože autor se snažil "dokončit sadu" místo toho, aby indikoval, že by skutečně použil takovou věc, a nepřidali jsme linux-dynamic, dokud se řešení patchelf nevytvořilo znovu přiřaďovat výsledky.
Užitečné poznámky k implementaci
Soubory portů se spouštějí v režimu skriptu.
I když portfile.cmake
sdílíme CMakeLists.txt
společnou syntaxi a základní konstruktory jazyka CMake (neboli Skriptovací příkazy), soubory portů se spouštějí 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é.
Soubory portů mají přímý přístup k proměnným nastaveným v trojitém souboru, ale CMakeLists.txt
ne (i když často dochází k překladu – versus VCPKG_LIBRARY_LINKAGE
BUILD_SHARED_LIBS
).
Soubory portů a sestavení projektu vyvolané soubory portů 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
).
Úplný výčet možných nastavení najdete také v naší dokumentaci tripletu.