Lorsque j'essaie d'exécuter un makefile généré par CMake pour compiler mon programme, j'obtiens l'erreur
La plage basée sur les boucles n'est pas prise en charge en mode C ++ 98.
J'ai essayé d' ajouter add_definitions(-std=c++0x)
à mon CMakeLists.txt
, mais il n'a pas aidé.
J'ai aussi essayé ça:
if(CMAKE_COMPILER_IS_GNUCXX)
add_definitions(-std=gnu++0x)
endif()
Quand je le fais g++ --version
, je reçois:
g ++ (Ubuntu / Linaro 4.6.1-9ubuntu3) 4.6.1
J'ai également essayé SET(CMAKE_CXX_FLAGS "-std=c++0x")
, ce qui ne fonctionne pas non plus.
Je ne comprends pas comment activer les fonctionnalités C ++ 11 à l'aide de CMake.
SET(CMAKE_CXX_FLAGS "-std=c++0x")
fonctionne très bien pour moi, donc il y a probablement un problème ailleurs dans le fichier CMakeLists. Assurez-vous de ne pas écraser accidentellement le contenu de CMAKE_CXX_FLAGS ultérieurement.set(CMAKE_CXX_STANDARD 11)
(avant de définir la cible) est le meilleur moyen.CXX_STANDARD
cela ne fonctionne pas sur MSVC, donc en gros, vous devez vous rabattre surtarget_compile_features
si vous voulez quelque chose qui fonctionne sur plusieurs plates-formes.Réponses:
CMake 3.1 a introduit la variable CMAKE_CXX_STANDARD que vous pouvez utiliser. Si vous savez que CMake 3.1 sera toujours disponible, vous pouvez simplement l'écrire dans votre fichier CMakeLists.txt de niveau supérieur ou le placer juste avant la définition d'une nouvelle cible:
Si vous devez prendre en charge les anciennes versions de CMake, voici une macro que j'ai imaginée que vous pouvez utiliser:
La macro ne prend en charge que GCC pour le moment, mais il devrait être simple de l'étendre à d'autres compilateurs.
Ensuite, vous pouvez écrire
use_cxx11()
en haut de n'importe quel fichier CMakeLists.txt qui définit une cible qui utilise C ++ 11.Problème CMake # 15943 pour les utilisateurs de Clang ciblant macOS
Si vous utilisez CMake et clang pour cibler macOS, un bogue peut empêcher la
CMAKE_CXX_STANDARD
fonctionnalité de fonctionner (n'ajoutez aucun indicateur de compilation). Assurez-vous de faire l'une des choses suivantes:Définissez la stratégie CMP0025 sur NEW avec le code suivant en haut de votre fichier CMakeLists.txt avant la
project
commande:la source
gnu++11
est appliquée, même lorsque ces variables sont définiesset(CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION clang)
set(CMAKE_ANDROID_STL_TYPE c++_static)
. Pour moi, le seul moyen viable était le classiqueset (CMAKE_CXX_FLAGS "-std=c++11 ${CMAKE_CXX_FLAGS}")
La commande CMake
target_compile_features()
est utilisée pour spécifier la fonctionnalité C ++ requisecxx_range_for
. CMake induira alors le standard C ++ à utiliser.Il n'est pas nécessaire d'utiliser
add_definitions(-std=c++11)
ou de modifier la variable CMakeCMAKE_CXX_FLAGS
, car CMake s'assurera que le compilateur C ++ est appelé avec les indicateurs de ligne de commande appropriés.Peut-être que votre programme C ++ utilise d'autres fonctionnalités C ++ que
cxx_range_for
. La propriété globale CMakeCMAKE_CXX_KNOWN_FEATURES
répertorie les fonctionnalités C ++ parmi lesquelles vous pouvez choisir.Au lieu d'utiliser,
target_compile_features()
vous pouvez également spécifier explicitement la norme C ++ en définissant les propriétés CMakeCXX_STANDARD
etCXX_STANDARD_REQUIRED
pour votre cible CMake.Voir aussi ma réponse plus détaillée .
la source
j'utilise
Mais si vous voulez jouer avec
C++11
,g++ 4.6.1
c'est assez vieux. Essayez d'obtenir uneg++
version plus récente.la source
CXX_STANDARD
réponses basées sur, mais c'était la seule réponse utile dans ma situation.La façon la plus simple de définir la norme Cxx est:
Voir la documentation de CMake pour plus de détails.
la source
set(CMAKE_CXX_STANDARD 11)
définir la propriété par défaut pour toutes les cibles créées après cela.set
commande suggérée par @emlai est globale et affecte toutes les cibles suivantes.En fait,
SET(CMAKE_CXX_FLAGS "-std=c++0x")
il active de nombreuses fonctionnalités C ++ 11. La raison pour laquelle cela n'a pas fonctionné était que la déclaration ressemblait à ceci:Suite à cette approche, le
-std=c++0x
drapeau a été en quelque sorte écrasé et cela n'a pas fonctionné. La définition des indicateurs un par un ou l'utilisation d'une méthode de liste fonctionne.la source
CXX_STANDARD
propriété est meilleure car elle est indépendante du compilateur.La façon la plus simple:
add_compile_options(-std=c++11)
la source
Pour CMake 3.8 et plus récent, vous pouvez utiliser
la source
PUBLIC
ici?PUBLIC
signifie que d'autres cibles qui dépendent de votre cible utiliseront également C ++ 11. Par exemple, si votre cible est une bibliothèque, toutes les cibles liées à votre bibliothèquetarget_link_libraries
seront compilées avec le support C ++ 11.Ceci est une autre façon d'activer la prise en charge de C ++ 11,
J'ai rencontré des cas où seule cette méthode fonctionne et d'autres méthodes échouent. Peut-être que cela a quelque chose à voir avec la dernière version de CMake.
la source
add_definitions
n'est censé être utilisé que pour ajouter des DÉFINITIONS, c'est-à-dire -D QUELQUE CHOSE. Et comme @Emmanuel l'a dit, cela ne fonctionne pas dans de nombreux cas.add_definitions
n'était pas fait pour définir des indicateurs.Sur CMake moderne (> = 3.1), la meilleure façon de définir les exigences globales est:
Cela se traduit par "Je veux C ++ 11 pour toutes les cibles, ce n'est pas facultatif, je ne veux utiliser aucune extension GNU ou Microsoft." À partir de C ++ 17, c'est toujours à mon humble avis la meilleure façon.
Source: activation de C ++ 11 et versions ultérieures dans CMake
la source
Ce qui fonctionne pour moi, c'est de définir la ligne suivante dans votre CMakeLists.txt:
La définition de cette commande active les fonctionnalités C ++ 11 pour le compilateur et après avoir exécuté la
cmake ..
commande, vous devriez pouvoir l'utiliserrange based for loops
dans votre code et le compiler sans aucune erreur.la source
-std=c++11
, tout commeset (CMAKE_CXX_STANDARD 11)
le drapeau-std=gnu++11
, ce qui pourrait être indésirable.set (CMAKE_CXX_EXTENSIONS OFF)
Je pense que ces deux lignes suffisent.
la source
target_compile_features
fonction Cmake , appliquée à chaque cible individuelle, comme indiqué dans d'autres réponses, est une approche plus recommandée.Si vous souhaitez toujours activer la dernière norme C ++, voici mon extension de la réponse de David Grayson , à la lumière des ajouts récents (CMake 3.8 et CMake 3.11) des valeurs de 17 et 20 pour CMAKE_CXX_STANDARD):
(Utilisez ce code à la place de
set (CMAKE_CXX_STANDARD 11)
dans la réponse liée.)la source
Modern cmake offre des moyens plus simples de configurer les compilateurs pour utiliser une version spécifique de C ++. La seule chose que quiconque doit faire est de définir les propriétés cibles pertinentes. Parmi les propriétés prises en charge par cmake , celles qui sont utilisées pour déterminer comment configurer les compilateurs pour prendre en charge une version spécifique de C ++ sont les suivantes:
CXX_STANDARD
définit la norme C ++ dont les fonctionnalités sont requises pour construire la cible. Définissez-le comme11
pour cibler C ++ 11.CXX_EXTENSIONS
, un booléen spécifiant si des extensions spécifiques au compilateur sont demandées. La définition de ce paramètreOff
désactive la prise en charge de toute extension spécifique au compilateur.Pour démontrer, voici un exemple de travail minimal d'un
CMakeLists.txt
.la source
Concernant OS X et Homebrew LLVM:
N'oubliez pas d'appeler cmake_minimum_required (VERSION 3.3) et project () après!
Ou CMake insérera
project()
implicitement avant la ligne 1, provoquant des problèmes avec la détection de version de Clang et éventuellement d'autres types de problèmes. Voici un problème connexe .la source