J'ai un certain nombre de projets construits en utilisant CMake et j'aimerais pouvoir facilement basculer entre GCC ou Clang/LLVM pour les compiler. Je crois (corrigez-moi si je me trompe!) Que pour utiliser Clang, je dois définir les paramètres suivants:
SET (CMAKE_C_COMPILER "/usr/bin/clang")
SET (CMAKE_C_FLAGS "-Wall -std=c99")
SET (CMAKE_C_FLAGS_DEBUG "-g")
SET (CMAKE_C_FLAGS_MINSIZEREL "-Os -DNDEBUG")
SET (CMAKE_C_FLAGS_RELEASE "-O4 -DNDEBUG")
SET (CMAKE_C_FLAGS_RELWITHDEBINFO "-O2 -g")
SET (CMAKE_CXX_COMPILER "/usr/bin/clang++")
SET (CMAKE_CXX_FLAGS "-Wall")
SET (CMAKE_CXX_FLAGS_DEBUG "-g")
SET (CMAKE_CXX_FLAGS_MINSIZEREL "-Os -DNDEBUG")
SET (CMAKE_CXX_FLAGS_RELEASE "-O4 -DNDEBUG")
SET (CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g")
SET (CMAKE_AR "/usr/bin/llvm-ar")
SET (CMAKE_LINKER "/usr/bin/llvm-ld")
SET (CMAKE_NM "/usr/bin/llvm-nm")
SET (CMAKE_OBJDUMP "/usr/bin/llvm-objdump")
SET (CMAKE_RANLIB "/usr/bin/llvm-ranlib")
Existe-t-il un moyen simple de basculer entre ces variables et les variables GCC par défaut, de préférence sous la forme d’un changement à l’échelle du système plutôt que selon le projet (c.-à-d. Ne pas simplement les ajouter au fichier CMakeLists.txt)?
Aussi, est-il nécessaire d'utiliser les programmes llvm-*
plutôt que les valeurs par défaut du système lors de la compilation avec clang au lieu de gcc? Quelle est la différence?
CMake respecte les variables d'environnement CC
et CXX
lors de la détection des compilateurs C et C++ à utiliser:
$ export CC=/usr/bin/clang
$ export CXX=/usr/bin/clang++
$ cmake ..
-- The C compiler identification is Clang
-- The CXX compiler identification is Clang
Les indicateurs spécifiques au compilateur peuvent être remplacés en les plaçant dans un fichier CMake système et en pointant la variable CMAKE_USER_MAKE_RULES_OVERRIDE . Créez un fichier ~/ClangOverrides.txt
avec le contenu suivant:
SET (CMAKE_C_FLAGS_INIT "-Wall -std=c99")
SET (CMAKE_C_FLAGS_DEBUG_INIT "-g")
SET (CMAKE_C_FLAGS_MINSIZEREL_INIT "-Os -DNDEBUG")
SET (CMAKE_C_FLAGS_RELEASE_INIT "-O3 -DNDEBUG")
SET (CMAKE_C_FLAGS_RELWITHDEBINFO_INIT "-O2 -g")
SET (CMAKE_CXX_FLAGS_INIT "-Wall")
SET (CMAKE_CXX_FLAGS_DEBUG_INIT "-g")
SET (CMAKE_CXX_FLAGS_MINSIZEREL_INIT "-Os -DNDEBUG")
SET (CMAKE_CXX_FLAGS_RELEASE_INIT "-O3 -DNDEBUG")
SET (CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT "-O2 -g")
Le suffixe _INIT fera en sorte que CMake initialise la variable *_FLAGS
correspondante avec la valeur donnée. Ensuite, appelez cmake de la manière suivante:
$ cmake -DCMAKE_USER_MAKE_RULES_OVERRIDE=~/ClangOverrides.txt ..
Enfin, pour forcer l'utilisation de LLVM binutils, définissez la variable interne _CMAKE_TOOLCHAIN_PREFIX
. Cette variable est honorée par le module CMakeFindBinUtils
:
$ cmake -D_CMAKE_TOOLCHAIN_PREFIX=llvm- ..
En regroupant tous ces éléments, vous pouvez écrire un wrapper Shell qui configure les variables d'environnement CC
et CXX
, puis appelle cmake avec les substitutions de variables mentionnées.
Changement C++ à l'échelle du système sur Ubuntu:
Sudo apt-get install clang
Sudo update-alternatives --config c++
Imprimera quelque chose comme ceci:
Selection Path Priority Status
------------------------------------------------------------
* 0 /usr/bin/g++ 20 auto mode
1 /usr/bin/clang++ 10 manual mode
2 /usr/bin/g++ 20 manual mode
Ensuite, il suffit de sélectionner Clang ++.
Vous pouvez utiliser la commande option:
option(USE_CLANG "build application with clang" OFF) # OFF is the default
et ensuite envelopper les paramètres du compilateur clang dans if () s:
if(USE_CLANG)
SET (...)
....
endif(USE_CLANG)
De cette façon, il est affiché comme une option cmake dans les outils de configuration graphique.
Pour l’étendre à l’ensemble du système, vous pouvez bien sûr utiliser une variable d’environnement comme valeur par défaut ou conserver la réponse de Ferruccio.
Changement de système global sur Ubuntu:
Sudo update-alternatives --config cc
Changement C++ à l'échelle du système sur Ubuntu:
Sudo update-alternatives --config c++
Pour chacun des éléments ci-dessus, appuyez sur Numéro de sélection (1), puis sur Entrée pour sélectionner Clang:
Selection Path Priority Status
------------------------------------------------------------
* 0 /usr/bin/gcc 20 auto mode
1 /usr/bin/clang 10 manual mode
2 /usr/bin/gcc 20 manual mode
Press enter to keep the current choice[*], or type selection number:
Vous n'avez certainement pas besoin d'utiliser les différents programmes llvm-ar etc:
SET (CMAKE_AR "/usr/bin/llvm-ar") SET (CMAKE_LINKER "/usr/bin/llvm-ld") SET (CMAKE_NM "/usr/bin/llvm-nm") SET (CMAKE_OBJDUMP "/usr/bin/llvm-objdump") SET (CMAKE_RANLIB "/usr/bin/llvm-ranlib")
Celles-ci sont conçues pour fonctionner sur le format interne llvm et ne sont donc pas utiles pour la construction de votre application.
En tant que note, -O4 invoquera LTO sur votre programme, ce que vous ne voudrez peut-être pas (cela augmentera considérablement le temps de compilation) et clanguera par défaut le mode c99 afin que cet indicateur ne soit pas nécessairement nécessaire.
Vous pouvez utiliser le mécanisme de fichiers de la chaîne d’outils de cmake à cette fin (voir par exemple). ici . Vous écrivez un fichier de chaîne d’outils pour chaque compilateur contenant les définitions correspondantes. Au moment de la configuration, vous lancez par exemple
cmake -DCMAKE_TOOLCHAIN_FILE=/path/to/clang-toolchain.cmake ..
et toutes les informations du compilateur seront définies lors de l'appel de project () à partir du fichier toolchain. Bien que la documentation ne soit mentionnée que dans le contexte de la compilation croisée, elle fonctionne également pour différents compilateurs sur le même système.
Selon l’aide de cmake
:
-C <initial-cache>
Pre-load a script to populate the cache.
When cmake is first run in an empty build tree, it creates a CMakeCache.txt file and populates it with customizable settings for the project. This option may be used to specify a file from
which to load cache entries before the first pass through the project's cmake listfiles. The loaded entries take priority over the project's default values. The given file should be a CMake
script containing SET commands that use the CACHE option, not a cache-format file.
Vous pouvez créer des fichiers tels que gcc_compiler.txt
et clang_compiler.txt
pour inclure toutes les configurations relatives dans la syntaxe CMake.
Exemple de clang (clang_compiler.txt):
set(CMAKE_C_COMPILER "/usr/bin/clang" CACHE string "clang compiler" FORCE)
Puis lancez le en tant que
GCC:
cmake -C gcc_compiler.txt XXXXXXXX
Bruit:
cmake -C clang_compiler.txt XXXXXXXX
Si le compilateur par défaut choisi par cmake
est gcc
et que vous avez installé clang
, vous pouvez utiliser le moyen le plus simple pour compiler votre projet avec clang
:
$ mkdir build && cd build
$ CXX=clang++ CC=clang cmake ..
$ make -j2
Vous pouvez utiliser la syntaxe: $ENV{environment-variable}
dans votre CMakeLists.txt
pour accéder aux variables d'environnement. Vous pouvez créer des scripts qui initialisent correctement un ensemble de variables d’environnement et qui n’ont que des références à ces variables dans vos fichiers CMakeLists.txt
.