Průvodce stylem CMake
Očekáváme, že všechny skripty CMake, které jsou:
- V adresáři
scripts/
nebo vcpkg-*
Na portu
by měly dodržovat pokyny uvedené v tomto dokumentu. Stávající skripty zatím nemusí postupovat podle těchto pokynů; Očekává se, že budeme dál aktualizovat staré skripty tak, aby byly v souladu s těmito pokyny.
Tyto pokyny jsou určeny k vytvoření stability v našich skriptech. Doufáme, že zjednoduší kompatibilitu vpřed i zpět.
Pokyny
S výjimkou out-parameters, vždy používáme
cmake_parse_arguments()
místo parametrů funkce nebo odkazování na${ARG<N>}
.Nemusí se to nutně dodržovat u pomocných funkcí skriptů místního prostředí.
- V tomto případě by měly být poziční parametry vloženy do deklarace funkce (místo použití
${ARG<N>}
) a měly by být pojmenovány podle místních pravidel (tj.snake_case
). - Výjimka: poziční parametry, které jsou volitelné, by měly být pojmenovány prostřednictvím
set(argument_name "${ARG<N>}")
, po kontroleARGC
.
- V tomto případě by měly být poziční parametry vloženy do deklarace funkce (místo použití
Výstupní parametry by měly být prvním parametrem funkce. Příklad:
function(format out_var) cmake_parse_arguments(PARSE_ARGV 1 "arg" ...) # ... set(buffer "output") set("${out_var}" "${buffer}" PARENT_SCOPE) endfunction()
Neexistují žádné neoddělené ani nepoužívané argumenty. Vždy zkontrolujte
ARGN
neboarg_UNPARSED_ARGUMENTS
.FATAL_ERROR
pokud je to možné,WARNING
pokud je to nezbytné pro zpětnou kompatibilitu.Všechny
cmake_parse_arguments
musí používatPARSE_ARGV
.Všechny
foreach
smyčky musí používatIN LISTS
,IN ITEMS
neboRANGE
.Proměnné
${ARGV}
a${ARGN}
neodkazují se, s výjimkou užitečných zpráv pro uživatele.- (tj.,
message(FATAL_ERROR "blah was passed extra arguments: ${ARGN}")
)
- (tj.,
Vždy používáme funkce, ne makra nebo kód nejvyšší úrovně.
- Výjimka: "makra pomocné rutiny pro skript-místní". Někdy je užitečné definovat malé makro. Mělo by se to provést střídmě a měly by být upřednostňované funkce.
- Výjimka:
vcpkg.cmake
sfind_package
.
Skripty ve stromu skriptů by neměly být očekávány tak, aby v rámci normálního provozu potřebovaly pozorovatelné změny.
- Příklad porušení:
vcpkg_acquire_msys()
obsahuje pevně zakódované balíčky a verze, které potřebují aktualizaci v průběhu času kvůli vyřazení starých balíčků projektu MSYS. - Příklad výjimky:
vcpkg_from_sourceforge()
obsahuje seznam zrcadlek, které vyžadují údržbu, ale nemají pozorovatelný dopad na chování volajících.
- Příklad porušení:
Pravidla pro uvozování: V CMake existují tři druhy argumentů – necitované (
foo(BAR)
), uvozené () afoo("BAR")
závorky (foo([[BAR]])
). Při správné citaci postupujte podle těchto pravidel:Pokud argument obsahuje rozšíření
${...}
proměnné, musí být uvozováno.Výjimka: rozšíření proměnné "splat", kdy se jedna proměnná předá funkci jako více argumentů. V tomto případě by argument měl být
${foo}
jednoduše:vcpkg_list(SET working_directory) if(DEFINED "arg_WORKING_DIRECTORY") vcpkg_list(SET working_directory WORKING_DIRECTORY "${arg_WORKING_DIRECTORY}") endif() # calls do_the_thing() if NOT DEFINED arg_WORKING_DIRECTORY, # else calls do_the_thing(WORKING_DIRECTORY "${arg_WORKING_DIRECTORY}") do_the_thing(${working_directory})
V opačném případě, pokud argument obsahuje všechny řídicí sekvence, které nejsou
\\
,\"
nebo\$
, tento argument musí být uvozovaný argument.- Například:
"foo\nbar"
musí být citováno.
- Například:
V opačném případě, pokud argument obsahuje
\
,"
a , nebo$
, tento argument by měl být závorka.Příklad:
set(x [[foo\bar]]) set(y [=[foo([[bar\baz]])]=])
V opačném případě, pokud argument obsahuje znaky, které nejsou alfanumerické nebo
_
, tento argument by měl být citován.Jinak by měl být argument necitovaný.
Výjimka: Argumenty typu
if()
<variable|string>
by měly být vždy uvozovány:Oba argumenty pro relační operátory -
EQUAL
,STREQUAL
,VERSION_LESS
atd.První argument a
MATCHES
IN_LIST
Příklad:
if("${FOO}" STREQUAL "BAR") # ... if("${BAZ}" EQUAL "0") # ... if("FOO" IN_LIST list_variable) # ... if("${bar}" MATCHES [[a[bcd]+\.[bcd]+]]) # ...
Pro jednoduché výrazy a pro jiné typy predikátů, které se nepoužívají
<variable|string>
, použijte normální pravidla.
Neexistují žádné parametry "ukazatel" nebo "in-out" (kde uživatel předá název proměnné místo obsahu), s výjimkou jednoduchých out-parameters.
Proměnné se nepředpokládají jako prázdné. Pokud je proměnná určená k místnímu použití, musí být explicitně inicializována tak, aby byla prázdná,
set(foo "")
pokud se jedná o řetězcovou proměnnou, avcpkg_list(SET foo)
pokud se jedná o proměnnou seznamu.set(var)
by se nemělo používat. Sloužíunset(var)
k zrušení nastavení proměnné,set(var "")
nastavení na prázdný řetězec avcpkg_list(SET var)
jeho nastavení na prázdný seznam. Poznámka: prázdný řetězec a prázdný seznam jsou stejné hodnoty;jedná se o rozdíl v zápisu, nikoli o rozdíl ve výsledku.Všechny proměnné, které by měly být zděděny z nadřazeného oboru v rámci hranice rozhraní API (tj. ne z místní funkce souboru), by se měly zdokumentovat. Všechny proměnné uvedené v souborech Triplet jsou považovány za zdokumentované.
Out parameters are set only in
PARENT_SCOPE
and are never read. Podívejte se také na pomocnou rutinuz_vcpkg_forward_output_variable()
pro předávání parametrů prostřednictvím oboru funkce.CACHE
Proměnné se používají pouze pro globální proměnné, které jsou sdíleny interně mezi silně propojenými funkcemi a pro vnitřní stav v rámci jedné funkce, aby se zabránilo duplikování práce. Ty by se měly používat velmi střídmě a měly by používat předponuZ_VCPKG_
, aby nedocházelo ke kolidování s místními proměnnými, které by byly definovány jakýmkoli jiným kódem.- Příklady:
vcpkg_cmake_configure
jeZ_VCPKG_CMAKE_GENERATOR
z_vcpkg_get_cmake_vars
jeZ_VCPKG_GET_CMAKE_VARS_FILE
- Příklady:
include()
s jsou povoleny pouze vports.cmake
nebovcpkg-port-config.cmake
.foreach(RANGE)
Argumenty musí být vždy přirozenými čísly a<start>
musí být vždy menší než nebo rovno<stop>
.Toto je potřeba zkontrolovat přibližně takto:
if("${start}" LESS_EQUAL "${end}") foreach(RANGE "${start}" "${end}") ... endforeach() endif()
Všechny skripty založené na portech musí používat
include_guard(GLOBAL)
, aby se zabránilo zahrnutí vícekrát.
Verze CMake, které se vyžadují
- Všechny skripty CMake, s výjimkou
vcpkg.cmake
, mohou předpokládat verzi CMake, která je přítomnacmake_minimum_required
v souboruports.cmake
.- To
cmake_minimum_required
by se mělo narazit při každém přidání nové verze CMake ,vcpkgTools.xml
stejně jakocmake_minimum_required
ve všech pomocnýchCMakeLists.txt
souborech.
- To
vcpkg.cmake
musí obecně předpokládat verzi CMake zpět na verzi 3.7.2.- Určité funkce a možnosti mohou předpokládat větší verzi CMake; pokud ano, nezapomeňte tuto funkci okomentovat nebo použít požadovanou verzi CMake.
Změna existujících funkcí
- Nikdy neodstraňujte argumenty v neinterních funkcích; pokud by už neměli dělat nic, stačí je vzít jako normální a varovat při použití.
- Nikdy nepřidávejte nový povinný argument.
Názvy proměnných
cmake_parse_arguments
: nastavit předponu na"arg"
Místní proměnné jsou pojmenované pomocí
snake_case
Názvy interních globálních proměnných mají předponu
Z_VCPKG_
.Názvy externích experimentálních globálních proměnných mají předponu
X_VCPKG_
.Interní funkce mají předponu
z_vcpkg_
- Funkce, které jsou interní pro jednu funkci (tj. pomocné funkce), jsou pojmenované
[z_]<func>_<name>
, kde<func>
je název funkce, které jsou pomocnou funkcí, a<name>
je to, co pomocná funkce dělá.z_
pokud nemá pomocnouz_
funkci, měla by být přidána do přední<func>
části, ale nepojmenovávejte pomocnou funkciz_z_foo_bar
.
- Funkce, které jsou interní pro jednu funkci (tj. pomocné funkce), jsou pojmenované
Veřejné globální proměnné jsou pojmenovány
VCPKG_
.