Führungslinie für die CMake-Formatvorlage
Wir erwarten, dass alle CMake-Skripts:
scripts/
Im Verzeichnis oder- In einem
vcpkg-*
Port
sollte den in diesem Dokument beschriebenen Richtlinien entsprechen. Vorhandene Skripts folgen diesen Richtlinien möglicherweise noch nicht; es wird erwartet, dass wir weiterhin alte Skripts aktualisieren werden, um in übereinstimmung mit diesen Richtlinien zu fallen.
Diese Richtlinien sollen stabilität in unseren Skripts schaffen. Wir hoffen, dass sie sowohl die Vorwärts- als auch abwärtskompatibilität vereinfachen werden.
Die Richtlinien
Mit Ausnahme von Out-Parametern verwenden
cmake_parse_arguments()
wir immer anstelle von Funktionsparametern oder verweisen auf${ARG<N>}
.Dies muss nicht unbedingt für "skriptlokale Hilfsfunktionen" befolgt werden.
- In diesem Fall sollten Positionsparameter in die Funktionsdeklaration (anstelle der Verwendung
${ARG<N>}
) gesetzt werden und gemäß lokalen Regeln benannt werden (d. h.snake_case
). - Ausnahme: Positionsparameter, die optional sind, sollten nach der Überprüfung
ARGC
einen Namenset(argument_name "${ARG<N>}")
erhalten.
- In diesem Fall sollten Positionsparameter in die Funktionsdeklaration (anstelle der Verwendung
Ausgabeparameter sollten der erste Parameter für eine Funktion sein. Beispiel:
function(format out_var) cmake_parse_arguments(PARSE_ARGV 1 "arg" ...) # ... set(buffer "output") set("${out_var}" "${buffer}" PARENT_SCOPE) endfunction()
Es gibt keine nicht analysierten oder nicht verwendeten Argumente. Suchen Sie immer nach
ARGN
oderarg_UNPARSED_ARGUMENTS
.FATAL_ERROR
wenn möglich, falls erforderlich,WARNING
um abwärtskompatibel zu sein.Alle
cmake_parse_arguments
müssen verwendet werdenPARSE_ARGV
.Alle
foreach
Schleifen müssen verwendetIN LISTS
werden,IN ITEMS
oderRANGE
.Die Variablen
${ARGV}
und${ARGN}
werden nicht referenziert, außer in hilfreichen Nachrichten für den Benutzer.- (d. h.,
message(FATAL_ERROR "blah was passed extra arguments: ${ARGN}")
)
- (d. h.,
Wir verwenden immer Funktionen, nicht Makros oder Code auf oberster Ebene.
- Ausnahme: "Skript-lokale Hilfsmakros". Es ist manchmal hilfreich, ein kleines Makro zu definieren. Dies sollte sparsam erfolgen, und Funktionen sollten bevorzugt werden.
- Ausnahme:
vcpkg.cmake
'sfind_package
.
Skripts in der Skriptstruktur sollten nicht erwartet werden, dass im Rahmen des normalen Vorgangs feststellbare Änderungen erforderlich sind.
- Beispielverletzung:
vcpkg_acquire_msys()
Enthält hartcodierte Pakete und Versionen, die aufgrund des MSYS-Projekts, das alte Pakete über einen Zeitraum aktualisiert werden muss. - Beispiel exception:
vcpkg_from_sourceforge()
has a list of Spiegel s which needs Standard tenance, but does not have an observable behavior impact on the callers.
- Beispielverletzung:
Regeln für die Zitatierung: Es gibt drei Arten von Argumenten in CMake - nicht anführungszeichen (
foo(BAR)
), anführungszeichen (foo("BAR")
) und Klammern (foo([[BAR]])
). Befolgen Sie die folgenden Regeln, um richtig anführungszeichen zu können:Wenn ein Argument eine variable Erweiterung
${...}
enthält, muss es an zitiert werden.Ausnahme: Eine "splat"-Variableerweiterung, wenn eine Variable als mehrere Argumente an eine Funktion übergeben wird. In diesem Fall sollte das Argument einfach wie folgt sein
${foo}
: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})
Wenn das Argument andernfalls Escapesequenzen enthält, die kein
\\
,\"
oder\$
, dieses Argument ein an zitiertes Argument sein müssen.- Beispiel:
"foo\nbar"
muss zitiert werden.
- Beispiel:
Andernfalls sollte dieses Argument in Klammern gesetzt werden, wenn das Argument ein
\
, a"
oder a$
enthält.Beispiel:
set(x [[foo\bar]]) set(y [=[foo([[bar\baz]])]=])
Wenn das Argument andernfalls Zeichen enthält, die nicht alphanumerisch oder
_
alphanumerisch sind, sollte dieses Argument an zitiert werden.Andernfalls sollte das Argument nicht angehalten werden.
Ausnahme: Argumente vom
if()
Typ<variable|string>
sollten immer zitiert werden:Beide Argumente für die Vergleichsoperatoren -
EQUAL
, ,STREQUAL
,VERSION_LESS
usw.Das erste Argument für
MATCHES
undIN_LIST
Beispiel:
if("${FOO}" STREQUAL "BAR") # ... if("${BAZ}" EQUAL "0") # ... if("FOO" IN_LIST list_variable) # ... if("${bar}" MATCHES [[a[bcd]+\.[bcd]+]]) # ...
Verwenden Sie für einzelne Ausdrücke und für andere Typen von Prädikaten, die nicht verwendet
<variable|string>
werden, die normalen Regeln.
Es gibt keine "Zeiger" oder "In-Out"-Parameter (bei denen ein Benutzer einen Variablennamen anstelle des Inhalts übergibt), mit Ausnahme einfacher Out-Parameter.
Variablen werden nicht als leer angenommen. Wenn die Variable lokal verwendet werden soll, muss sie explizit initialisiert werden, wenn
set(foo "")
es sich um eine Zeichenfolgenvariable handelt, undvcpkg_list(SET foo)
wenn es sich um eine Listenvariable handelt.set(var)
sollte nicht verwendet werden. Wirdunset(var)
verwendet,set(var "")
um eine Variable auf die leere Zeichenfolge festzulegen undvcpkg_list(SET var)
auf die leere Liste festzulegen. Hinweis: Die leere Zeichenfolge und die leere Liste sind derselbe Wert;Dies ist ein Notationalunterschied und kein Ergebnisunterschied.Alle Variablen, die von dem übergeordneten Bereich über eine API-Grenze (d. h. keine dateilokale Funktion) geerbt werden sollen, sollten dokumentiert werden. Alle Variablen, die in Triplet-Dateien Erwähnung sind, werden als dokumentiert betrachtet.
Ausgabeparameter werden nur festgelegt
PARENT_SCOPE
und nie gelesen. Siehe auch das Hilfsprogrammz_vcpkg_forward_output_variable()
zum Weiterleiten von Parametern über einen Funktionsbereich.CACHE
Variablen werden nur für globale Variablen verwendet, die intern zwischen stark gekoppelten Funktionen und für den internen Zustand innerhalb einer einzelnen Funktion gemeinsam verwendet werden, um duplizierende Arbeit zu vermeiden. Diese sollten äußerst sparsam verwendet werden und das Präfix verwendenZ_VCPKG_
, um zu vermeiden, dass sie mit lokalen Variablen kollidieren, die von einem anderen Code definiert werden.- Beispiele:
vcpkg_cmake_configure
'sZ_VCPKG_CMAKE_GENERATOR
z_vcpkg_get_cmake_vars
'sZ_VCPKG_GET_CMAKE_VARS_FILE
- Beispiele:
include()
s sind nur zulässig inports.cmake
odervcpkg-port-config.cmake
.foreach(RANGE)
Die Argumente müssen immer natürliche Zahlen sein und<start>
müssen immer kleiner oder gleich sein<stop>
.Dies muss von etwa folgendem überprüft werden:
if("${start}" LESS_EQUAL "${end}") foreach(RANGE "${start}" "${end}") ... endforeach() endif()
Alle portbasierten Skripts müssen verwendet
include_guard(GLOBAL)
werden, um zu vermeiden, dass sie mehrmals eingeschlossen werden.
CMake-Versionen, die erforderlich sind
- Alle CMake-Skripts, mit Ausnahme
vcpkg.cmake
von , können davon ausgehen, dass die version von CMake vorhandencmake_minimum_required
ports.cmake
ist.- Dies
cmake_minimum_required
sollte jedes Mal stoßen, wenn eine neue Version von CMake hinzugefügtvcpkgTools.xml
wird, wie diescmake_minimum_required
in allen HilfsdateienCMakeLists.txt
der Fall ist.
- Dies
vcpkg.cmake
muss eine Version von CMake zurück zu 3.7.2 im Allgemeinen annehmen.- Bestimmte Funktionen und Optionen können eine größere CMake-Version annehmen; Wenn dies der Fall ist, stellen Sie sicher, dass Sie diese Funktion oder Option mit der erforderlichen CMake-Version kommentieren.
Ändern vorhandener Funktionen
- Entfernen Sie niemals Argumente in nicht internen Funktionen; wenn sie nichts mehr tun sollten, nehmen Sie sie einfach wie normal und warnen Sie bei der Verwendung.
- Fügen Sie niemals ein neues obligatorisches Argument hinzu.
Benennen von Variablen
cmake_parse_arguments
: Präfix auf"arg"
Lokale Variablen werden mit
snake_case
Interne globale Variablennamen werden mit dem Präfix versehen
Z_VCPKG_
.Externe experimentelle globale Variablennamen werden mit dem Präfix versehen
X_VCPKG_
.Interne Funktionen werden mit dem Präfix "Präfix" versehen.
z_vcpkg_
- Funktionen, die für eine einzelne Funktion (d. h. Hilfsfunktionen) intern sind, werden benannt
[z_]<func>_<name>
, wobei<func>
es sich um den Namen der Funktion handelt, für die sie ein Hilfsprogramm sind und<name>
was die Hilfsfunktion tut.z_
sollte vorne hinzugefügt werden, wenn<func>
keinez_
, aber keine Hilfsfunktionz_z_foo_bar
benennen.
- Funktionen, die für eine einzelne Funktion (d. h. Hilfsfunktionen) intern sind, werden benannt
Öffentliche globale Variablen werden benannt
VCPKG_
.
Feedback
https://aka.ms/ContentUserFeedback.
Bald verfügbar: Im Laufe des Jahres 2024 werden wir GitHub-Issues stufenweise als Feedbackmechanismus für Inhalte abbauen und durch ein neues Feedbacksystem ersetzen. Weitere Informationen finden Sie unterFeedback senden und anzeigen für