Freigeben über


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 ARGCeinen Namen set(argument_name "${ARG<N>}")erhalten.
    • 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 oder arg_UNPARSED_ARGUMENTS. FATAL_ERROR wenn möglich, falls erforderlich, WARNING um abwärtskompatibel zu sein.

  • Alle cmake_parse_arguments müssen verwendet werden PARSE_ARGV.

  • Alle foreach Schleifen müssen verwendet IN LISTSwerden, IN ITEMSoder RANGE.

  • 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}"))
  • 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's find_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.
  • 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.
    • 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_LESSusw.

      • Das erste Argument für MATCHES und IN_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, und vcpkg_list(SET foo) wenn es sich um eine Listenvariable handelt.

  • set(var) sollte nicht verwendet werden. Wird unset(var) verwendet, set(var "") um eine Variable auf die leere Zeichenfolge festzulegen und vcpkg_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 Hilfsprogramm z_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 verwenden Z_VCPKG_ , um zu vermeiden, dass sie mit lokalen Variablen kollidieren, die von einem anderen Code definiert werden.

    • Beispiele:
      • vcpkg_cmake_configure's Z_VCPKG_CMAKE_GENERATOR
      • z_vcpkg_get_cmake_vars's Z_VCPKG_GET_CMAKE_VARS_FILE
  • include()s sind nur zulässig in ports.cmake oder vcpkg-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.cmakevon , können davon ausgehen, dass die version von CMake vorhanden cmake_minimum_requiredports.cmakeist.
    • Dies cmake_minimum_required sollte jedes Mal stoßen, wenn eine neue Version von CMake hinzugefügt vcpkgTools.xmlwird, wie dies cmake_minimum_required in allen Hilfsdateien CMakeLists.txt der Fall ist.
  • 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> keine z_, aber keine Hilfsfunktion z_z_foo_barbenennen.
  • Öffentliche globale Variablen werden benannt VCPKG_.