web-dev-qa-db-fra.com

Comment diviser des chaînes sur plusieurs lignes dans CMake?

J'ai généralement une politique dans mon projet, pour ne jamais créer de lignes dans des fichiers texte qui dépassent une longueur de ligne de 80, donc elles sont facilement modifiables dans toutes sortes d'éditeurs (vous connaissez l'affaire). Mais avec CMake, j'ai le problème de ne pas savoir comment diviser une chaîne simple en plusieurs lignes pour éviter une énorme ligne. Considérez ce code de base:

set(MYPROJ_VERSION_MAJOR "1")
set(MYPROJ_VERSION_MINOR "0")
set(MYPROJ_VERSION_PATCH "0")
set(MYPROJ_VERSION_EXTRA "rc1")
set(MYPROJ_VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}-${VERSION_EXTRA}")

Il dépasse déjà la limite de 80 lignes. Alors, comment puis-je couper une ligne dans CMake en plusieurs lignes sans obtenir de verbose (plusieurs list(APPEND ...) ou similaire)?

80

Mise à jour pour CMake 3.0 et plus récent :

la poursuite de la ligne est possible avec \. voir cmake-3.0-doc

message("\
This is the first line of a quoted argument. \
In fact it is the only line but since it is long \
the source code uses line continuation.\
")

Disponibilité des versions de CMake:

Debian Wheezy (2013): 2.8.9
Debian Wheezy-backports: 2.8.11
Debian Jessy (2015): 3.0.2
Ubuntu 14.04 (LTS): 2.8.12
Ubuntu 15.04: 3.0.2
Mac OSX: cmake-3 disponible via Homebrew , Macports et Fink
Windows: cmake-3 disponible via Chocolatey

72
Hotschke

CMake 3.0 et plus récent

Utilisez la commande string(CONCAT):

set(MYPROJ_VERSION_MAJOR "1")
set(MYPROJ_VERSION_MINOR "0")
set(MYPROJ_VERSION_PATCH "0")
set(MYPROJ_VERSION_EXTRA "rc1")
string(CONCAT MYPROJ_VERSION "${MYPROJ_VERSION_MAJOR}"
                             ".${MYPROJ_VERSION_MINOR}"
                             ".${MYPROJ_VERSION_PATCH}"
                             "-${MYPROJ_VERSION_EXTRA}")

Bien que CMake 3.0 et une prise en charge plus récente suite de ligne des arguments cités , vous ne pouvez pas mettre en retrait la deuxième ligne ou les lignes suivantes sans obtenir les espaces blancs d'indentation inclus dans votre chaîne.

CMake 2.8 et plus

Vous pouvez utiliser une liste. Chaque élément de la liste peut être mis sur une nouvelle ligne:

set(MYPROJ_VERSION_MAJOR "1")
set(MYPROJ_VERSION_MINOR "0")
set(MYPROJ_VERSION_PATCH "0")
set(MYPROJ_VERSION_EXTRA "rc1")
set(MYPROJ_VERSION_LIST "${MYPROJ_VERSION_MAJOR}"
                        ".${MYPROJ_VERSION_MINOR}"
                        ".${MYPROJ_VERSION_PATCH}"
                        "-${MYPROJ_VERSION_EXTRA}")

Une liste utilisée sans guillemets est concaténée sans espace blanc:

message(STATUS "Version: " ${MYPROJ_VERSION_LIST})
-- Version: 1.0.0-rc1

Si vous avez vraiment besoin d'une chaîne, vous pouvez d'abord convertir la liste en chaîne:

string(REPLACE ";" "" MYPROJ_VERSION "${MYPROJ_VERSION_LIST}")
message(STATUS "Version: ${MYPROJ_VERSION}")
-- Version: 1.0.0-rc1

Tous les points-virgules dans vos chaînes d'origine seront considérés comme des séparateurs d'éléments de liste et supprimés. Ils doivent être échappés:

set(MY_LIST "Hello World "
            "with a \;semicolon")
47
Douglas Royds

C'est encore un peu bavard, mais si la limite de 80 caractères vous dérange vraiment, vous pouvez ajouter plusieurs fois à la même variable:

set(MYPROJ_VERSION_MAJOR "1")
set(MYPROJ_VERSION_MINOR "0")
set(MYPROJ_VERSION_PATCH "0")
set(MYPROJ_VERSION_EXTRA "rc1")
set(MYPROJ_VERSION "${MYPROJ_VERSION_MAJOR}.")
set(MYPROJ_VERSION "${MYPROJ_VERSION}${MYPROJ_VERSION_MINOR}.")
set(MYPROJ_VERSION "${MYPROJ_VERSION}${MYPROJ_VERSION_PATCH}-")
set(MYPROJ_VERSION "${MYPROJ_VERSION}${MYPROJ_VERSION_EXTRA}")
message(STATUS "version: ${MYPROJ_VERSION}")

Donne la sortie:

$ cmake  ~/project/tmp
-- version: 1.0.0-rc1
-- Configuring done
-- Generating done
-- Build files have been written to: /home/rsanderson/build/temp
8
Rian Sanderson

Il n'existe aucun moyen de diviser un littéral de chaîne sur plusieurs lignes dans les fichiers CMakeLists.txt ou dans les scripts CMake. Si vous incluez une nouvelle ligne dans une chaîne, il y aura une nouvelle ligne littérale dans la chaîne elle-même.

# Don't do this, it won't work, MYPROJ_VERSION will contain newline characters:
set(MYPROJ_VERSION "${VERSION_MAJOR}.
  ${VERSION_MINOR}.${VERSION_PATCH}-
  ${VERSION_EXTRA}")

Cependant, CMake utilise des espaces pour séparer les arguments, vous pouvez donc changer un espace qui est un séparateur d'arguments en une nouvelle ligne où vous le souhaitez, sans changer le comportement.

Vous pouvez reformuler cette ligne plus longue:

set(MYPROJ_VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}-${VERSION_EXTRA}")

comme ces deux lignes plus courtes:

set(MYPROJ_VERSION
  "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}-${VERSION_EXTRA}")

Ils sont entièrement équivalents.

7
DLRdave

L'exemple de la question d'origine concerne uniquement une chaîne relativement courte. Pour les chaînes plus longues (y compris les exemples donnés dans d'autres réponses), un argument crochet pourrait être mieux. De la documentation:

Une parenthèse ouvrante est écrite [ suivi de zéro ou plus = suivi par [. Le crochet de fermeture correspondant est écrit ] suivi du même nombre de = suivi par ]. Les supports ne s'emboîtent pas. Une longueur unique peut toujours être choisie pour que les supports d'ouverture et de fermeture contiennent des supports de fermeture d'autres longueurs.

[...]

Par exemple:

message([=[
This is the first line in a bracket argument with bracket length 1.
No \-escape sequences or ${variable} references are evaluated.
This is always one argument even though it contains a ; character.
The text does not end on a closing bracket of length 0 like ]].
It does end in a closing bracket of length 1.
]=])```
0
ingomueller.net