Condividi tramite


Guida di stile di CMake

Ci aspettiamo che tutti gli script CMake siano i seguenti:

  • scripts/ Nella directory o
  • In una vcpkg-* porta

deve seguire le linee guida disposte in questo documento. Gli script esistenti potrebbero non seguire ancora queste linee guida; è previsto che si continuerà ad aggiornare gli script precedenti in modo che siano conformi a queste linee guida.

Queste linee guida sono concepite per creare stabilità negli script. Speriamo che faciliteranno la compatibilità sia in avanti che con le versioni precedenti.

Linee guida

  • Ad eccezione dei parametri out, si usano cmake_parse_arguments() sempre anziché parametri di funzione o si fa riferimento a ${ARG<N>}.

    • Questo non deve necessariamente essere seguito per le "funzioni helper locali script"

      • In questo caso, i parametri posizionali devono essere inseriti nella dichiarazione di funzione (anziché usare ${ARG<N>}) e devono essere denominati in base alle regole locali (ad esempio snake_case).
      • Eccezione: ai parametri posizionali facoltativi deve essere assegnato un nome tramite set(argument_name "${ARG<N>}"), dopo aver controllato ARGC.
    • I parametri out devono essere il primo parametro di una funzione. Esempio:

      function(format out_var)
        cmake_parse_arguments(PARSE_ARGV 1 "arg" ...)
        # ... set(buffer "output")
        set("${out_var}" "${buffer}" PARENT_SCOPE)
      endfunction()
      
  • Non sono presenti argomenti non verificati o inutilizzati. Verificare sempre la presenza ARGN di o arg_UNPARSED_ARGUMENTS. FATAL_ERROR se possibile, WARNING se necessario per la compatibilità con le versioni precedenti.

  • Tutti cmake_parse_arguments devono usare PARSE_ARGV.

  • Tutti i foreach cicli devono usare IN LISTS, IN ITEMSo RANGE.

  • Le variabili ${ARGV} e ${ARGN} non vengono referenziate, ad eccezione dei messaggi utili per l'utente.

    • (ad esempio, message(FATAL_ERROR "blah was passed extra arguments: ${ARGN}"))
  • Usiamo sempre funzioni, non macro o codice di primo livello.

    • Eccezione: "macro helper locali script". A volte è utile definire una piccola macro. Questa operazione deve essere eseguita con moderazione e le funzioni devono essere preferite.
    • Eccezione: vcpkg.cmake's find_package.
  • Gli script nell'albero degli script non devono essere necessari modifiche osservabili come parte del normale funzionamento.

    • Violazione di esempio: vcpkg_acquire_msys() include pacchetti hardcoded e versioni che richiedono l'aggiornamento nel tempo a causa del progetto MSYS che elimina i pacchetti precedenti.
    • Eccezione di esempio: vcpkg_from_sourceforge() include un elenco di mirror che richiede la manutenzione, ma non ha un impatto sul comportamento osservabile sui chiamanti.
  • Regole per le virgolette: in CMake sono disponibili tre tipi di argomenti, tra virgolette (foo(BAR)), tra virgolette (foo("BAR")) e tra parentesi quadre (foo([[BAR]])). Seguire queste regole per citare correttamente:

    • Se un argomento contiene un'espansione ${...}variabile , deve essere racchiuso tra virgolette.

      • Eccezione: espansione di una variabile "splat", quando una variabile verrà passata a una funzione come più argomenti. In questo caso, l'argomento deve essere ${foo}semplicemente :

        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})
        
    • In caso contrario, se l'argomento contiene sequenze di escape che non \\sono , \"o \$, tale argomento deve essere un argomento tra virgolette.

      • Ad esempio: "foo\nbar" deve essere racchiuso tra virgolette.
    • In caso contrario, se l'argomento contiene un \oggetto , o ", $tale argomento deve essere racchiuso tra parentesi quadre.

      • Esempio:

        set(x [[foo\bar]])
        set(y [=[foo([[bar\baz]])]=])
        
    • In caso contrario, se l'argomento contiene caratteri non alfanumerici o _, l'argomento deve essere racchiuso tra virgolette.

    • In caso contrario, l'argomento deve essere unquotato.

    • Eccezione: gli argomenti di if() tipo <variable|string> devono sempre essere racchiusi tra virgolette:

      • Entrambi gli argomenti degli operatori di confronto - EQUAL, STREQUAL, e VERSION_LESScosì via.

      • Primo argomento a MATCHES e IN_LIST

      • Esempio:

        if("${FOO}" STREQUAL "BAR") # ...
        if("${BAZ}" EQUAL "0") # ...
        if("FOO" IN_LIST list_variable) # ...
        if("${bar}" MATCHES [[a[bcd]+\.[bcd]+]]) # ...
        
      • Per le singole espressioni e per altri tipi di predicati che non accettano <variable|string>, usare le regole normali.

  • Non sono presenti parametri "puntatore" o "in uscita" (in cui un utente passa un nome di variabile anziché il contenuto), ad eccezione dei semplici parametri out.

  • Le variabili non vengono considerate vuote. Se la variabile deve essere usata localmente, deve essere inizializzata in modo esplicito con vuoto se set(foo "") si tratta di una variabile stringa e vcpkg_list(SET foo) , se si tratta di una variabile di elenco.

  • set(var) non deve essere utilizzato. Utilizzare unset(var) per annullare l'impostazione di una variabile, set(var "") per impostarla sulla stringa vuota e vcpkg_list(SET var) impostarla sull'elenco vuoto. Nota: la stringa vuota e l'elenco vuoto sono lo stesso valore;questa è una differenza notazione piuttosto che una differenza nel risultato

  • Tutte le variabili che devono essere ereditate dall'ambito padre attraverso un limite API (ovvero non una funzione locale di file) devono essere documentate. Tutte le variabili indicate nei file Triplet vengono considerate documentate.

  • I parametri out vengono impostati solo in PARENT_SCOPE e non vengono mai letti. Vedere anche l'helper z_vcpkg_forward_output_variable() per inoltrare i parametri tramite un ambito di funzione.

  • CACHE le variabili vengono usate solo per le variabili globali condivise internamente tra le funzioni fortemente associate e per lo stato interno all'interno di una singola funzione per evitare la duplicazione del lavoro. Questi devono essere usati con estrema moderazione e devono usare il Z_VCPKG_ prefisso per evitare conflitti con qualsiasi variabile locale che verrebbe definita da qualsiasi altro codice.

    • Esempi:
      • vcpkg_cmake_configure's Z_VCPKG_CMAKE_GENERATOR
      • z_vcpkg_get_cmake_vars's Z_VCPKG_GET_CMAKE_VARS_FILE
  • include()s è consentito solo in ports.cmake o vcpkg-port-config.cmake.

  • foreach(RANGE)Gli argomenti di devono essere sempre numeri naturali e <start> devono essere sempre minori o uguali a <stop>.

    • Questa operazione deve essere verificata in base a un aspetto simile al seguente:

      if("${start}" LESS_EQUAL "${end}")
        foreach(RANGE "${start}" "${end}")
          ...
        endforeach()
      endif()
      
  • Tutti gli script basati su porta devono essere usati include_guard(GLOBAL) per evitare di essere inclusi più volte.

Versioni di CMake da richiedere

  • Tutti gli script CMake, ad eccezione vcpkg.cmakedi , possono presupporre la versione di CMake presente in cmake_minimum_required di ports.cmake.
    • Questa cmake_minimum_required operazione deve essere aggiornata ogni volta che viene aggiunta una nuova versione di CMake a vcpkgTools.xml, come dovrebbe cmake_minimum_required in tutti i file helper CMakeLists.txt .
  • vcpkg.cmake deve presupporre una versione di CMake alla versione 3.7.2 in generale
    • Funzioni e opzioni specifiche possono presupporre una versione CMake maggiore; in caso affermativo, assicurarsi di impostare come commento la funzione o l'opzione con la versione di CMake richiesta.

Modifica delle funzioni esistenti

  • Non rimuovere mai argomenti in funzioni non interne; se non dovrebbero più fare nulla, basta prenderli come di consueto e avvisare sull'uso.
  • Non aggiungere mai un nuovo argomento obbligatorio.

Assegnazione di nomi alle variabili

  • cmake_parse_arguments: impostare il prefisso su "arg"

  • Le variabili locali sono denominate con snake_case

  • I nomi delle variabili globali interni sono preceduti da Z_VCPKG_.

  • I nomi di variabili globali sperimentali esterni sono preceduti da X_VCPKG_.

  • Le funzioni interne sono precedute da un prefisso z_vcpkg_

    • Le funzioni interne a una singola funzione (ad esempio, le funzioni helper) sono denominate [z_]<func>_<name>, dove <func> è il nome della funzione a cui sono un helper ed <name> è ciò che fa la funzione helper.
      • z_ deve essere aggiunto al front se <func> non ha un z_oggetto , ma non denominare una funzione z_z_foo_barhelper .
  • Le variabili globali pubbliche sono denominate VCPKG_.