Sdílet prostřednictvím


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 kontrole ARGC.
    • 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 nebo arg_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žívat PARSE_ARGV.

  • Všechny foreach smyčky musí používat IN LISTS, IN ITEMSnebo RANGE.

  • 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}"))
  • 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.cmakes find_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.
  • 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.
    • 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_LESSatd.

      • První argument a MATCHESIN_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, a vcpkg_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 a vcpkg_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 rutinu z_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ředponu Z_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_configureje Z_VCPKG_CMAKE_GENERATOR
      • z_vcpkg_get_cmake_varsje Z_VCPKG_GET_CMAKE_VARS_FILE
  • include()s jsou povoleny pouze v ports.cmake nebo vcpkg-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řítomna cmake_minimum_required v souboru ports.cmake.
    • To cmake_minimum_required by se mělo narazit při každém přidání nové verze CMake , vcpkgTools.xmlstejně jako cmake_minimum_required ve všech pomocných CMakeLists.txt souborech.
  • 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á pomocnou z_funkci, měla by být přidána do přední <func> části, ale nepojmenovávejte pomocnou funkci z_z_foo_bar.
  • Veřejné globální proměnné jsou pojmenovány VCPKG_.