GCC 4.x n'accepte pas le --std=c++14
commutateur pour le code C++ 14 - il faut --std=c++1y
au lieu. Les versions ultérieures prennent --std=c++1z
mais pas (probablement) --std=c++17
qui n'a pas encore été défini (écrit en 2016). Il existe peut-être des problèmes similaires avec C++ 11.
CMake a-t-il une possibilité (peut-être en tant que module) de passer le commutateur approprié en fonction de la version de GCC?
Lorsque vous souhaitez spécifier une version C++ particulière, la méthode recommandée avec CMake 3.1 et versions ultérieures consiste à utiliser le fichier CXX_STANDARD
, CXX_STANDARD_REQUIRED
et CXX_EXTENSIONS
propriétés cibles ou leurs équivalents variables pour spécifier les valeurs par défaut de la cible. Les détails complets peuvent être trouvés ici , mais la version courte ressemble à ceci:
cmake_minimum_required(VERSION 3.1)
project(Example)
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
# ... Define targets, etc. as usual
CMake devrait ensuite sélectionner le drapeau de compilateur approprié pour la norme C++ demandée en fonction de ce que le compilateur prend en charge, ou en cas d'erreur s'il ne prend pas en charge la norme demandée.
Il convient également de noter que CMake peut mettre à niveau la cible pour utiliser une norme de langue plus récente que celle spécifiée par son CXX_STANDARD
propriété cible. L'utilisation de exigences de compilation (comme indiqué dans la réponse de @FlorianWolters) peut augmenter les exigences de la norme de langue. En fait, CMake choisira toujours l'exigence linguistique plus stricte spécifiée par le CXX_STANDARD
propriété cible ou exigences de compilation définies sur la cible. Notez également que la documentation de CMake à partir de 3.10.1 ne reflète pas exactement la façon dont CXX_EXTENSIONS
interagit avec les fonctionnalités de compilation, comme CXX_EXTENSIONS
ne prend effet que si CXX_STANDARD
est également spécifié pour les compilateurs les plus courants (car ils sont spécifiés avec le drapeau du compilateur).
Le code CMake moderne devrait utiliser le target_compile_features
commande pour demander une norme C++ spécifique. Cela peut être spécifié uniquement comme exigence de construction (PRIVATE
), comme exigence d’utilisation seulement (INTERFACE
) ou comme exigence de construction et d’utilisation (PUBLIC
).
Exemple:
cmake_minimum_required(VERSION 3.9.4)
project(cpp-snippets)
add_executable(cpp-snippets "main.cpp")
target_compile_features(cpp-snippets PRIVATE cxx_std_17)
Reportez-vous à la section relative aux normes linguistiques dans la documentation officielle de CMake pour cmake-compile-features pour en savoir plus.
Vérifiez si le compilateur prend en charge les drapeaux? Peut-être quelque chose comme
include(CheckCXXCompilerFlag)
# Check for standard to use
check_cxx_compiler_flag(-std=c++17 HAVE_FLAG_STD_CXX17)
if(HAVE_FLAG_STD_CXX17)
# Have -std=c++17, use it
else()
check_cxx_compiler_flag(-std=c++1z HAVE_FLAG_STD_CXX1Z)
if(HAVE_FLAG_STD_CXX1Z)
# Have -std=c++1z, use it
else()
# And so on and on...
endif()
endif()