Je demande ceci pour me rappeler la prochaine fois que j'utilise CMake. Cela ne colle jamais et les résultats de Google ne sont pas excellents.
Quelle est la syntaxe pour définir et utiliser des variables dans CMake?
Lorsque vous écrivez des scripts CMake, vous devez en savoir beaucoup sur la syntaxe et sur l’utilisation des variables dans CMake.
Chaînes utilisant set()
:
set(MyString "Some Text")
set(MyStringWithVar "Some other Text: ${MyString}")
set(MyStringWithQuot "Some quote: \"${MyStringWithVar}\"")
Ou avec string()
:
string(APPEND MyStringWithContent " ${MyString}")
Listes utilisant set()
:
set(MyList "a" "b" "c")
set(MyList ${MyList} "d")
Ou mieux avec list()
:
list(APPEND MyList "a" "b" "c")
list(APPEND MyList "d")
Listes de noms de fichiers:
set(MySourcesList "File.name" "File with Space.name")
list(APPEND MySourcesList "File.name" "File with Space.name")
add_excutable(MyExeTarget ${MySourcesList})
set()
Commandstring()
Commandlist()
CommandIl y a tout d'abord les "variables normales" et les informations à connaître sur leur portée:
CMakeLists.txt
où elles sont définies et tout est appelé à partir de là (add_subdirectory()
, include()
, macro()
et function()
).add_subdirectory()
et function()
sont spéciales, car elles ouvrent leur propre étendue. set(...)
, elles ne sont visibles que là-bas et elles copient toutes les variables normales du niveau de portée à partir duquel elles sont appelées (appelée portée parent).set(... PARENT_SCOPE)
.function(xyz _resultVar)
définissant set(${_resultVar} 1 PARENT_SCOPE)
include()
ou macro()
modifiera les variables directement dans l'étendue de l'endroit d'où elles sont appelées.Deuxièmement, il y a le "cache de variables globales". Ce que vous devez savoir sur le cache:
CMakeCache.txt
de votre répertoire de sortie binaire.Les valeurs du cache peuvent être modifiées dans l'application interface graphique de CMake avant d'être générées. Par conséquent, ils ont - par rapport aux variables normales - un type
et un docstring
. Normalement, je n'utilise pas l'interface graphique, j'utilise donc set(... CACHE INTERNAL "")
pour définir mes valeurs globales et persistantes.
Veuillez noter que le type de variable de cache INTERNAL
implique FORCE
Dans un script CMake, vous ne pouvez modifier les entrées de cache existantes que si vous utilisez la syntaxe set(... CACHE ... FORCE)
. Ce comportement est utilisé, par exemple. par CMake lui-même, car normalement, il ne force pas les entrées de cache et vous pouvez donc le prédéfinir avec une autre valeur.
cmake -D var:type=value
, juste cmake -D var=value
ou avec cmake -C CMakeInitialCache.cmake
.unset(... CACHE)
.Le cache est global et vous pouvez les définir pratiquement n'importe où dans vos scripts CMake. Mais je vous conseillerais de réfléchir à l’utilisation des variables de cache (elles sont globales et persistantes). Je préfère normalement la syntaxe set_property(GLOBAL PROPERTY ...)
et set_property(GLOBAL APPEND PROPERTY ...)
pour définir mes propres variables globales non persistantes.
Pour éviter les pièges, vous devez connaître les informations suivantes sur les variables:
find_...
- si elles aboutissent - écrivent leurs résultats sous forme de variables en cache "afin qu'aucun appel ne recherche à nouveau"set(MyVar a b c)
est "a;b;c"
et set(MyVar "a b c")
est "a b c"
list()
pour la gestion des listesfunctions()
au lieu de macros()
car vous ne souhaitez pas que vos variables locales apparaissent dans la portée parent.project()
et enable_language()
. Il pourrait donc être important de définir certaines variables avant que ces commandes ne soient utilisées.Parfois, seules les variables de débogage peuvent aider. Ce qui suit peut vous aider:
printf
à l'aide de la commande message()
. Il existe également des modules prêts à l’emploi fournis avec CMake lui-même: CMakePrintHelpers.cmake , CMakePrintSystemInformation.cmakeCMakeCache.txt
de votre répertoire de sortie binaire. Ce fichier est même généré si la génération actuelle de votre environnement make échoue.cmake --trace ...
pour voir le processus complet d'analyse de CMake. C'est en quelque sorte la dernière réserve, car elle génère beaucoup de résultats.$ENV{...}
et écrire les variables d'environnement set(ENV{...} ...)
$<...>
ne sont évaluées que lorsque le générateur de CMake écrit l'environnement de création (comparaison avec les variables normales remplacées "sur place" par l'analyseur)${${...}}
vous pouvez donner des noms de variable dans une variable et référencer son contenu.if()
commande) if(MyVariable)
, vous pouvez directement vérifier si une variable est vraie/fausse (inutile ici pour le ${...}
inclus)1
, ON
, YES
, TRUE
, Y
ou un nombre non nul.0
, OFF
, NO
, FALSE
, N
, IGNORE
, NOTFOUND
, la chaîne vide , ou se termine par le suffixe -NOTFOUND
.if(MSVC)
, mais elle peut prêter à confusion pour quelqu'un qui ne connaît pas ce raccourci de syntaxe.set(CMAKE_${lang}_COMPILER ...)
if()
. Voici un exemple où CMAKE_CXX_COMPILER_ID
est "MSVC"
et MSVC
est "1"
: if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
est true, car elle est évaluée à if("1" STREQUAL "1")
if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
est false, car elle est évaluée à if("MSVC" STREQUAL "1")
if(MSVC)
cmake_policy(SET CMP0054 NEW)
sur "n'interprète que les arguments if()
comme des variables ou des mots-clés non cités".option()
commande ON
ou OFF
et permettent certaines manipulations spéciales telles que, par exemple. dépendancesoption
avec la commande set
. La valeur donnée à option
n'est en réalité que la "valeur initiale" (transférée une fois au cache lors de la première étape de configuration) et doit ensuite être modifiée par l'utilisateur via interface graphique de CMake .Voici quelques exemples de base pour bien démarrer rapidement.
Définir la variable:
SET(INSTALL_ETC_DIR "etc")
Utiliser la variable:
SET(INSTALL_ETC_CROND_DIR "${INSTALL_ETC_DIR}/cron.d")
Définir la variable:
SET(PROGRAM_SRCS
program.c
program_utils.c
a_lib.c
b_lib.c
config.c
)
Utiliser la variable:
add_executable(program "${PROGRAM_SRCS}")
$ENV{FOO}
pour une utilisation, où FOO est extrait de la variable d'environnement. sinon, utilisez ${FOO}
, où FOO est une autre variable. Pour le réglage, SET(FOO "foo")
serait utilisé dans cmake.