Partager via


Guide de style CMake

Nous nous attendons à ce que tous les scripts CMake soient les suivants :

  • Dans le scripts/ répertoire ou
  • Dans un vcpkg-* port

doit suivre les instructions présentées dans ce document. Les scripts existants peuvent ne pas encore suivre ces instructions ; on s’attend à ce que nous continuions à mettre à jour les anciens scripts pour qu’ils tombent en ligne avec ces instructions.

Ces instructions sont destinées à créer la stabilité dans nos scripts. Nous espérons qu’ils faciliteront la compatibilité avant et descendante.

Les instructions

  • À l’exception des paramètres sortants, nous utilisons cmake_parse_arguments() toujours plutôt que les paramètres de fonction ou en faisant référence à ${ARG<N>}.

    • Cela n’a pas nécessairement besoin d’être suivi pour les « fonctions d’assistance locales de script »

      • Dans ce cas, les paramètres positionnels doivent être placés dans la déclaration de fonction (au lieu d’utiliser ${ARG<N>}) et doivent être nommés en fonction des règles locales (c’est-à-dire snake_case).
      • Exception : les paramètres positionnels facultatifs doivent être attribués à un nom via set(argument_name "${ARG<N>}"), après vérification ARGC.
    • Les paramètres out doivent être le premier paramètre d’une fonction. Exemple :

      function(format out_var)
        cmake_parse_arguments(PARSE_ARGV 1 "arg" ...)
        # ... set(buffer "output")
        set("${out_var}" "${buffer}" PARENT_SCOPE)
      endfunction()
      
  • Il n’existe aucun argument non utilisé ou non utilisé. Toujours vérifier ARGN ou arg_UNPARSED_ARGUMENTS. FATAL_ERROR si possible, WARNING si nécessaire pour la compatibilité descendante.

  • Tous cmake_parse_arguments doivent utiliser PARSE_ARGV.

  • Toutes les foreach boucles doivent utiliser IN LISTS, IN ITEMSou RANGE.

  • Les variables ${ARGV} et ${ARGN} ne sont pas référencées, sauf dans les messages utiles à l’utilisateur.

    • (c.-à-d. message(FATAL_ERROR "blah was passed extra arguments: ${ARGN}"))
  • Nous utilisons toujours des fonctions, et non des macros ou du code de niveau supérieur.

    • Exception : « macros d’assistance locales de script ». Il est parfois utile de définir une petite macro. Cette opération doit être effectuée avec parcimonie, et les fonctions doivent être préférées.
    • Exception : vcpkg.cmake's find_package.
  • Les scripts de l’arborescence des scripts ne doivent pas être censés avoir besoin de modifications observables dans le cadre d’une opération normale.

    • Exemple de violation : vcpkg_acquire_msys() contient des packages et des versions codés en dur qui ont besoin de se mettre à jour au fil du temps en raison de la suppression d’anciens packages par le projet MSYS.
    • Exemple d’exception : vcpkg_from_sourceforge() contient une liste de miroirs qui nécessitent une maintenance, mais n’a pas d’impact observable sur les appelants.
  • Règles de guillemets : il existe trois types d’arguments dans CMake - sans guillemets (), entre guillemets (foo(BAR)foo("BAR")) et entre crochets (foo([[BAR]])). Suivez ces règles pour citer correctement :

    • Si un argument contient une extension ${...}de variable, il doit être entre guillemets.

      • Exception : extension de variable « splat », lorsqu’une variable est passée à une fonction en tant qu’arguments multiples. Dans ce cas, l’argument doit simplement être ${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})
        
    • Sinon, si l’argument contient des séquences d’échappement qui ne sont pas \\, \"ou \$si cet argument doit être un argument entre guillemets.

      • Par exemple : "foo\nbar" doit être entre guillemets.
    • Sinon, si l’argument contient un \argument , un "ou un $, cet argument doit être entre crochets.

      • Exemple :

        set(x [[foo\bar]])
        set(y [=[foo([[bar\baz]])]=])
        
    • Sinon, si l’argument contient des caractères qui ne sont pas alphanumériques ou _, cet argument doit être entre guillemets.

    • Sinon, l’argument doit être non cité.

    • Exception : les arguments de if() type <variable|string> doivent toujours être entre guillemets :

      • Les deux arguments des opérateurs de comparaison - EQUAL, STREQUAL, VERSION_LESS, etc.

      • Premier argument vers MATCHES et IN_LIST

      • Exemple :

        if("${FOO}" STREQUAL "BAR") # ...
        if("${BAZ}" EQUAL "0") # ...
        if("FOO" IN_LIST list_variable) # ...
        if("${bar}" MATCHES [[a[bcd]+\.[bcd]+]]) # ...
        
      • Pour les expressions uniques et pour d’autres types de prédicats qui ne prennent <variable|string>pas, utilisez les règles normales.

  • Il n’existe aucun paramètre « pointeur » ou « in-out » (où un utilisateur passe un nom de variable plutôt que le contenu), à l’exception des paramètres sortants simples.

  • Les variables ne sont pas supposées être vides. Si la variable est destinée à être utilisée localement, elle doit être initialisée explicitement pour être vide si set(foo "") elle est une variable de chaîne et vcpkg_list(SET foo) s’il s’agit d’une variable de liste.

  • set(var) ne doit pas être utilisé. Permet unset(var) de supprimer une variable, set(var "") de la définir sur la chaîne vide et vcpkg_list(SET var) de la définir sur la liste vide. Remarque : la chaîne vide et la liste vide sont la même valeur ;il s’agit d’une différence notationnelle plutôt que d’une différence dans le résultat

  • Toutes les variables censées être héritées de l’étendue parente sur une limite d’API (c’est-à-dire pas une fonction locale de fichier) doivent être documentées. Toutes les variables mentionnées dans les fichiers Triplet sont considérées comme documentées.

  • Les paramètres out sont définis uniquement et PARENT_SCOPE ne sont jamais lus. Consultez également l’assistance z_vcpkg_forward_output_variable() pour transférer les paramètres via une étendue de fonction.

  • CACHE les variables sont utilisées uniquement pour les variables globales qui sont partagées en interne entre les fonctions fortement couplées et pour l’état interne au sein d’une fonction unique afin d’éviter de dupliquer le travail. Celles-ci doivent être utilisées de manière extrêmement éparse et doivent utiliser le Z_VCPKG_ préfixe pour éviter toute collision avec les variables locales qui seraient définies par tout autre code.

    • Exemples :
      • vcpkg_cmake_configureEst Z_VCPKG_CMAKE_GENERATOR
      • z_vcpkg_get_cmake_varsEst Z_VCPKG_GET_CMAKE_VARS_FILE
  • include()sont autorisés uniquement dans ports.cmake ou vcpkg-port-config.cmake.

  • foreach(RANGE)les arguments de l’argument doivent toujours être des nombres naturels et <start> doivent toujours être inférieurs ou égaux à .<stop>

    • Cela doit être vérifié par quelque chose comme :

      if("${start}" LESS_EQUAL "${end}")
        foreach(RANGE "${start}" "${end}")
          ...
        endforeach()
      endif()
      
  • Tous les scripts basés sur les ports doivent être utilisés include_guard(GLOBAL) pour éviter d’être inclus plusieurs fois.

Versions CMake à exiger

  • Tous les scripts CMake, à l’exception vcpkg.cmakede ports.cmake, peuvent supposer la version de CMake présente dans le cmake_minimum_required fichier .
    • Cela cmake_minimum_required doit être heurté chaque fois qu’une nouvelle version de CMake est ajoutée à vcpkgTools.xml, comme si dans cmake_minimum_required tous les fichiers d’assistance CMakeLists.txt .
  • vcpkg.cmake doit supposer une version de CMake de retour à la version 3.7.2 en général
    • Des fonctions et des options spécifiques peuvent supposer une version supérieure de CMake ; si c’est le cas, veillez à commenter cette fonction ou cette option avec la version CMake requise.

Modification des fonctions existantes

  • Ne supprimez jamais d’arguments dans les fonctions non internes ; s’ils ne devraient plus rien faire, il suffit de les prendre comme normal et d’avertir sur l’utilisation.
  • N’ajoutez jamais un nouvel argument obligatoire.

Nommage des variables

  • cmake_parse_arguments: définir le préfixe sur "arg"

  • Les variables locales sont nommées avec snake_case

  • Les noms de variables globales internes sont préfixés par Z_VCPKG_.

  • Les noms de variables globales expérimentales externes sont préfixés par X_VCPKG_.

  • Les fonctions internes sont préfixées avec z_vcpkg_

    • Les fonctions internes à une fonction unique (c’est-à-dire les fonctions d’assistance) sont nommées [z_]<func>_<name>, où <func> est le nom de la fonction à laquelle elles sont un assistance et <name> c’est ce que fait la fonction d’assistance.
      • z_ doit être ajouté à l’avant s’il <func> n’a pas de z_fonction d’assistance, mais ne nomme pas de fonction z_z_foo_bard’assistance.
  • Les variables globales publiques sont nommées VCPKG_.