Kiedy próbuję uruchomić plik makefile wygenerowany przez CMake w celu skompilowania mojego programu, pojawia się błąd
zakres oparty na pętlach nie jest obsługiwany w trybie C ++ 98.
Próbowałem dodać add_definitions(-std=c++0x)
do mojego CMakeLists.txt
, ale to nie pomogło.
Próbowałem też:
if(CMAKE_COMPILER_IS_GNUCXX)
add_definitions(-std=gnu++0x)
endif()
Kiedy to robię g++ --version
, otrzymuję:
g ++ (Ubuntu / Linaro 4.6.1-9ubuntu3) 4.6.1
Próbowałem też SET(CMAKE_CXX_FLAGS "-std=c++0x")
, co też nie działa.
Nie rozumiem, jak mogę aktywować funkcje C ++ 11 za pomocą CMake.
SET(CMAKE_CXX_FLAGS "-std=c++0x")
Działa dobrze dla mnie, więc nie ma chyba problem gdzie indziej w pliku CMakeLists. Upewnij się, że później nie przypadkowo zastąpisz zawartość CMAKE_CXX_FLAGS.set(CMAKE_CXX_STANDARD 11)
(przed zdefiniowaniem celu) jest najlepszym sposobem.CXX_STANDARD
to nie działa na MSVC, więc w zasadzie musisz cofnąć się,target_compile_features
jeśli chcesz czegoś, co działa na wielu platformach.Odpowiedzi:
CMake 3.1 wprowadził zmienną CMAKE_CXX_STANDARD , której możesz użyć. Jeśli wiesz, że zawsze będziesz mieć dostępną wersję CMake 3.1, możesz po prostu napisać ją w pliku CMakeLists.txt najwyższego poziomu lub ustawić ją przed zdefiniowaniem nowego obiektu docelowego:
Jeśli potrzebujesz obsługi starszych wersji CMake, oto makro, które wymyśliłem, którego możesz użyć:
Makro obsługuje obecnie tylko GCC, ale powinno być łatwe do rozszerzenia na inne kompilatory.
Następnie możesz napisać
use_cxx11()
na górze dowolnego pliku CMakeLists.txt, który definiuje cel, który używa C ++ 11.CMake numer 15943 dla użytkowników clang atakujących macOS
Jeśli używasz CMake i clang do targetowania macOS, istnieje błąd, który może powodować, że
CMAKE_CXX_STANDARD
funkcja po prostu nie działa (nie dodaje żadnych flag kompilatora). Upewnij się, że wykonujesz jedną z następujących czynności:Ustaw zasadę CMP0025 na NOWY z następującym kodem u góry pliku CMakeLists.txt przed
project
poleceniem:źródło
gnu++11
wymuszanie, nawet gdy te zmienne są zdefiniowaneset(CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION clang)
set(CMAKE_ANDROID_STL_TYPE c++_static)
. Dla mnie jedynym realnym sposobem był klasykset (CMAKE_CXX_FLAGS "-std=c++11 ${CMAKE_CXX_FLAGS}")
Polecenie CMake
target_compile_features()
służy do określania wymaganej funkcji C ++cxx_range_for
. CMake wywoła następnie użycie standardu C ++.Nie ma potrzeby używania
add_definitions(-std=c++11)
ani modyfikowania zmiennej CMakeCMAKE_CXX_FLAGS
, ponieważ CMake upewni się, że kompilator C ++ zostanie wywołany z odpowiednimi flagami wiersza poleceń.Być może twój program C ++ używa innych funkcji C ++ niż
cxx_range_for
. Globalna właściwość CMakeCMAKE_CXX_KNOWN_FEATURES
zawiera listę funkcji C ++ do wyboru.Zamiast używać
target_compile_features()
można również jawnie określić standard C ++, ustawiając właściwości CMakeCXX_STANDARD
iCXX_STANDARD_REQUIRED
cel CMake.Zobacz także moją bardziej szczegółową odpowiedź .
źródło
ja używam
Ale jeśli chcesz się bawić
C++11
,g++ 4.6.1
jest dość stary. Spróbuj uzyskać nowsząg++
wersję.źródło
CXX_STANDARD
odpowiedziami na podstawie, ale była to jedyna odpowiedź przydatna w mojej sytuacji.Najłatwiejszym sposobem ustawienia standardu Cxx jest:
Więcej informacji znajduje się w dokumentacji CMake .
źródło
set(CMAKE_CXX_STANDARD 11)
zdefiniować domyślną właściwość dla wszystkich celów utworzonych później.set
polecenie sugerowane przez @emlai ma charakter globalny i wpływa na wszystkie kolejne cele.Jak się okazuje,
SET(CMAKE_CXX_FLAGS "-std=c++0x")
aktywuje wiele funkcji C ++ 11. Powodem, dla którego nie zadziałało, było to, że oświadczenie wyglądało tak:Po tym podejściu
-std=c++0x
flaga została w jakiś sposób nadpisana i nie działała. Działa ustawianie flag jeden po drugim lub przy użyciu metody listy.źródło
CXX_STANDARD
Nieruchomość jest lepszy, ponieważ jest to kompilator-agnostykiem.Najłatwiejszy sposób:
add_compile_options(-std=c++11)
źródło
Do CMake 3.8 i nowszych możesz użyć
źródło
PUBLIC
tutaj funkcja ?PUBLIC
oznacza, że inne cele zależne od twojego celu również będą używać C ++ 11. Na przykład, jeśli twoim celem jest biblioteka, wówczas wszystkie cele łączące się z twoją bibliotekątarget_link_libraries
zostaną skompilowane z obsługą C ++ 11.To kolejny sposób włączenia obsługi C ++ 11,
Napotkałem przypadki, w których działa tylko ta metoda, a inne metody zawodzą. Może ma to coś wspólnego z najnowszą wersją CMake.
źródło
add_definitions
służy tylko do dodawania DEFINICJI, tj. -D COŚ. I jak powiedział @Emmanuel, w wielu przypadkach nie działa.add_definitions
nie został stworzony do ustawiania flag.Na współczesnym CMake (> = 3.1) najlepszym sposobem na ustawienie globalnych wymagań jest:
Przekłada się to na „Chcę C ++ 11 dla wszystkich celów, nie jest opcjonalny, nie chcę używać żadnych rozszerzeń GNU ani Microsoft”. Począwszy od C ++ 17, nadal jest to najlepszy sposób IMHO.
Źródło: Włączanie C ++ 11 i później w CMake
źródło
To, co działa dla mnie, to ustawić następujący wiersz w pliku CMakeLists.txt:
Ustawienie tego polecenia aktywuje funkcje C ++ 11 dla kompilatora, a po wykonaniu
cmake ..
polecenia powinieneś być w stanie korzystaćrange based for loops
z kodu i skompilować go bez żadnych błędów.źródło
-std=c++11
, ponieważset (CMAKE_CXX_STANDARD 11)
użyje flagi-std=gnu++11
, co może być niepożądane.set (CMAKE_CXX_EXTENSIONS OFF)
Myślę, że wystarczy te dwie linie.
źródło
target_compile_features
funkcja Cmake , zastosowana dla każdego celu, jak pokazano w innych odpowiedziach, jest bardziej zalecanym podejściem.Jeśli chcesz zawsze aktywować najnowszy standard C ++, oto moje rozszerzenie odpowiedzi Davida Graysona , w świetle ostatnich (CMake 3.8 i CMake 3.11) dodatków o wartościach 17 i 20 dla CMAKE_CXX_STANDARD):
(Użyj tego kodu zamiast
set (CMAKE_CXX_STANDARD 11)
linku w odpowiedzi.)źródło
Nowoczesne cmake oferuje prostsze sposoby konfigurowania kompilatorów do używania konkretnej wersji C ++. Jedyne, co każdy musi zrobić, to ustawić odpowiednie właściwości docelowe. Wśród właściwości obsługiwanych przez cmake są te, które są używane do określenia, jak skonfigurować kompilatory do obsługi określonej wersji C ++:
CXX_STANDARD
ustawia standard C ++, którego funkcji wymaga budowanie obiektu docelowego. Ustaw to jako11
docelowe C ++ 11.CXX_EXTENSIONS
, wartość logiczna określająca, czy wymagane są rozszerzenia specyficzne dla kompilatora. Ustawienie tego jakoOff
wyłącza obsługę dowolnego rozszerzenia specyficznego dla kompilatora.Aby to zademonstrować, oto minimalny działający przykład
CMakeLists.txt
.źródło
Związane z OS X i Homebrew LLVM:
Nie zapomnij wywołać cmake_minimum_required (VERSION 3.3) i project () po nim!
Lub CMake wstawi
project()
niejawnie przed wierszem 1, powodując problemy z wykrywaniem wersji Clanga i ewentualnie inne problemy. Oto pokrewny problem .źródło