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

Как включить /std: С++ 17 в VS2017 с CMake

Я пытаюсь добавить флаг компилятора /std:c++17 в VS2017 с помощью CMake. До сих пор я использую "современный" кросс-платформенный способ:

set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF) # -std=c++11 instead of -std=gnu++11
set(MY_CXX_COMPILE_FEATURES cxx_generic_lambdas cxx_range_for cxx_strong_enums)

add_library(mylib INTERFACE)
target_compile_features(mylib INTERFACE ${MY_CXX_COMPILE_FEATURES})

Это добавляет /std:c++14 в VS2017 (который по умолчанию может быть по умолчанию?). Однако мне не удается переключить это на С++ 17 (т.е. Добавить /std:c++17). Если я просто добавлю его вручную, я получаю предупреждение не очень хорошо, потому что присутствуют оба флага:

1>cl : Command line warning D9025: overriding '/std:c++14' with '/std:c++17'

Я пробовал set(CMAKE_CXX_STANDARD 17), но это не имеет никакого эффекта, на самом деле документация CMake указывает, что CMAKE_CXX_STANDARD никак не влияет на VS.

Что касается добавления функции С++ 17 в target_compile_features, похоже, что пока нет (даже в CMake-3.9.0-rc5), и даже если бы это было так, я был конкретно используя std::optional из С++ 17, и там нет флагов target_compile_features для библиотечных функций, таких как std::optional.

Итак, мой вопрос: какой лучший (или наименее уродливый) способ сделать это с помощью CMake? И таким образом, он также будет работать на gcc и clang? Я рад использовать очень недавнюю версию CMake (3.8 или 3.9). Я предпочитаю, чтобы он был "приятным", а не ручным циклом через CXX_COMPILE_FLAGS и удалением строки "/std: С++ 14" или некоторым взломом.

(Edit: также может быть переключатель VS /std:c++latest - в зависимости от того, что возможно. Оба работают для этой цели.)

4b9b3361

Ответ 1

Превращение моего комментария в ответ

  • Команда CMake работает над ней для VS2017 (как и в июле 2017 года для предстоящей версии CMake версии 3.10):

    Стандартные версии CMake: MSVC

    Эти флаги кажутся скорее новыми переключателями (связанные с датой этого вопроса):

    VS 2017 Предварительный просмотр 15.3 теперь поддерживает /std: С++ 17

    Итак, для Visual Studio вам нужно "вручную" заменить или добавить ключи компилятора до тех пор, пока CMake официально не поддержит его.

    Вот фрагмент кода, который я тестировал для std:c++latest (который уже поддерживается, например, в моей версии CMake 3.8.0):

    if (MSVC_VERSION GREATER_EQUAL "1900")
        include(CheckCXXCompilerFlag)
        CHECK_CXX_COMPILER_FLAG("/std:c++latest" _cpp_latest_flag_supported)
        if (_cpp_latest_flag_supported)
            add_compile_options("/std:c++latest")
        endif()
    endif()
    
  • Для CLang и GNU поддержка была объединена с началом основного исходного кода 2017 года и является частью CMake версии 3.8 и выше:

    CMake: Возможности: Добавить поддержку для языка С++ 17

Ответ 2

версии CMake выше 3.10 поддерживают стандартные коммутаторы MSVC С++, но в более ранних версиях они не влияют.

Единственный переносимый подход, обеспечивающий компиляцию вашей программы с правильным стандартным режимом С++ в Visual Studio, должен требовать хотя бы CMake 3.10, установить целевое свойство CXX_STANDARD до желаемого значения и CXX_STANDARD_REQUIRED до ON.

Пример использования:

set_property(TARGET my_target PROPERTY CXX_STANDARD 17)
set_property(TARGET my_target PROPERTY CXX_STANDARD_REQUIRED ON)

Примечание. В документации CXX_STANDARD для CMake 3.10 неправильно указано, что она не влияет на MSVC. Там проблема отслеживания этого здесь.