Как включить `/ std: последнюю версию c ` в cmake?

#c #visual-c #cmake

#c #visual-c #cmake

Вопрос:

Я могу установить CMAKE_CXX_STANDARD значение 17 для получения /std:c 17 , но я не могу установить его latest , не так ли? Я думаю, я могу просто перебрать его с помощью

 if (MSVC)
    add_compiler_options(/std:c  latest)
endif()
  

конечно, но есть ли идиоматический способ получить /std:c latest , может быть, даже не зависящий от цепочки инструментов?

РЕДАКТИРОВАТЬ Зачем кому-то это нужно? В отличие от Clang и GCC, MSVC, похоже, не определяет /std:c 2a включение функций post-C 17. Он просто использует /std:c latest для этого. Если я создаю базу кода с набором известных компиляторов, я знаю, какие функции C 20 я могу использовать, но мне нужно указать системе сборки включить все, на что способен каждый компилятор.

Комментарии:

1. Я не знаю ни одного компилятора (или набора инструментов), который предоставлял бы такую вещь. Большинство поставщиков ожидают, что пользователь будет знать и намеренно выбирать стандарт, для которого они создают (и по умолчанию использовать стандарт, для которого их поддержка стабильна и почти завершена). Поскольку последняя версия часто является нестабильной и нестабильной для разработки, выбор последней версии действительно предназначен для опытных и продвинутых разработчиков, которые хотят и могут справиться с неполными или неправильными реализациями языка или библиотеки. И эти разработчики, вероятно, будут точно знать, какую версию стандарта они хотят использовать.

2. Переменная CMAKE_CXX_STANDARD действительно является единственным «независимым от цепочки инструментов» способом настройки используемой версии C . И, к сожалению, он допускает только определенные предопределенные значения. Кроме того, ни у GCC, ни у Clang нет «последней» стандартной опции IIRC.

3. Хотя я понимаю вашу мотивацию для использования этой функции, это серьезно подорвет переносимость данной кодовой базы и системы сборки CMake. Определение «latest» будет значительно меняться между различными компиляторами и даже версиями компилятора. Лучше четко указать, какую версию вы хотите.

4. @Someprogrammerdude добавляя обоснование к вопросу, я понял, что Clang и GCC просто используют другой способ включить latest. Для этих компиляторов вы говорите -std=c 1z или -std=c 2a , и они остаются навсегда, в конечном итоге становясь псевдонимами для -std=c 17 и -std=c 20 , соответственно /std:c latest , otoh, является движущейся целью. После C 20 это станет тем, что, скорее всего, вызовут GCC и Clang -std=c 2b . Я думаю, что мне больше нравится GCC / Clang по причинам, которые Ботье и Питер правильно указали в своих комментариях.

Ответ №1:

До CMake 3.20.3, если вы попросите C 20, используя set(CMAKE_CXX_STANDARD 20) , вы получите -std:c latest . Доказательство:

   if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 19.12.25835)
    set(CMAKE_CXX20_STANDARD_COMPILE_OPTION "-std:c  latest")
    set(CMAKE_CXX20_EXTENSION_COMPILE_OPTION "-std:c  latest")
  endif()
  

(из Modules/Compiler/MSVC-CXX.cmake в исходных текстах cmake)

ОБНОВЛЕНИЕ: начиная с CMake 3.20.4, set(CMAKE_CXX_STANDARD 20) вы получаете -std:c 20 , поэтому вам нужно set(CMAKE_CXX_STANDARD 23) получить -std:c latest — при условии, что ваша версия компилятора MSVC — 16.11 Preview 1 или более поздняя (см. cmake commit 3aaf1d91bf353).

Ответ №2:

Предполагая, что вы используете компилятор, который уже совместим с C 20, и вы не хотите указывать «if» и дополнительное назначение, как это было сделано в предыдущем ответе, это стандартный способ поместить последнюю версию C в CMake при использовании Visual Studio или другого компилятора.

 target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_20)
  

Вот список функций, поддерживаемых CMake в случае C CMAKE_CXX_KNOWN_FEATURES.

Ответ №3:

Поддерживаемые значения: 98, 11, 14, 17 и 20.

Согласно документам CMake