Подтвердить что ты не робот

Как включить С++ 17 в CMake

Я использую VS 15.3, который поддерживает интегрированный CMake 3.8. Как настроить таргетинг на С++ 17 без написания флагов для каждого конкретного компилятора? Мои текущие глобальные настройки не работают:

# https://cmake.org/cmake/help/latest/prop_tgt/CXX_STANDARD.html
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

# expected behaviour
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /std:c++lastest")

Я ожидал, что CMake добавит "/std: С++ lastest" или эквиваленты при создании файлов решений VS, но не было найдено никаких флагов С++ 17, что привело к ошибке компилятора:

C1189 #error: class template optional is only available with C++17.
4b9b3361

Ответ 1

Из документация CMake 3.9:

Для компиляторов, не имеющих понятия стандартного уровня, например MSVC, это не имеет никакого эффекта.

Короче говоря, CMake не были обновлены для размещения стандартных флагов, добавленных в VС++ 2017.

Вы должны определить, используется ли VС++ 2017 (или более поздняя версия) и добавлять соответствующие флаги самостоятельно.


В CMake 3.10 (и позже) это исправлено для более новой версии VС++. См. документацию 3.10.

Ответ 2

В современном CMake лучше всего назначать стандарты CXX на целевом уровне, а не на уровне глобальных переменных и использовать встроенные свойства (см. Здесь: https://cmake.org/cmake/help/latest/manual/cmake. -properties.7.html) чтобы он не зависел от компилятора.

Например:

set_target_properties(FooTarget PROPERTIES
            CXX_STANDARD 17
            CXX_EXTENSIONS OFF
            etc..
            )

Ответ 3

Вы можете сохранить этот set(CMAKE_CXX_STANDARD 17) для других компиляторов, таких как Clang и GCC. Но для Visual Studio это бесполезно.

Если CMake все еще не поддерживает это, вы можете сделать следующее:

if(MSVC)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /std:c++17")
endif(MSVC)

Ответ 4

Современный CMake предлагает интерфейс для этой цели target_compile_features. Документация здесь: Требование языковых стандартов

Используйте это так:

target_compile_features(${TARGET_NAME} PRIVATE cxx_std_17)