Как заставить CMake передавать либо std = c ++ 14 / c ++ 1y, либо c ++ 17 / c ++ 1z в зависимости от версии GCC?

GCC 4.x не принимает --std=c++14 переключатель для кода C ++ 14 — требуется --std=c++1y вместо. Более поздние версии принимают --std=c++1z но (вероятно) нет --std=c++17 который еще не был установлен (запись в 2016 году). Возможно, есть похожие проблемы с C ++ 11.

Имеет ли CMake какое-либо средство (возможно, как модуль) для передачи правильного переключателя в соответствии с версией GCC?

29

Решение

Если вы хотите указать конкретную версию C ++, рекомендуемый способ сделать это с CMake 3.1 и более поздними версиями — использовать CXX_STANDARD, CXX_STANDARD_REQUIRED а также CXX_EXTENSIONS целевые свойства или их переменные эквиваленты для определения целевых значений по умолчанию. Полная информация может быть найдена Вот, но короткая версия выглядит примерно так:

cmake_minimum_required(VERSION 3.1)
project(Example)

set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
# ... Define targets, etc. as usual

Затем CMake должен выбрать соответствующий флаг компилятора для запрошенного стандарта C ++ на основе того, что поддерживает компилятор, или вывести ошибку, если он не поддерживает запрошенный стандарт.

Также следует отметить, что CMake может обновить цель, чтобы использовать более поздний языковой стандарт, чем тот, который указан его CXX_STANDARD целевое свойство. Использование требования к компиляции (как указано в ответе @FlorianWolters) может повысить требования к языковым стандартам. Фактически, CMake всегда выбирает более строгие требования к языку, указанные CXX_STANDARD свойство target или требования к функции компиляции, установленные для цели. Также обратите внимание, что документация CMake по состоянию на 3.10.1 не точно отражает способ CXX_EXTENSIONS взаимодействует с функциями компиляции, как CXX_EXTENSIONS вступает в силу только если CXX_STANDARD также указывается для большинства распространенных компиляторов (поскольку они указываются вместе с одним флагом компилятора).

55

Другие решения

Современный код CMake должен использовать target_compile_features Команда для запроса конкретного стандарта C ++. Это может быть указано только как требование сборки (PRIVATE), только требование использования (INTERFACE) или требования к сборке и использованию (PUBLIC).

Пример:

cmake_minimum_required(VERSION 3.9.4)

project(cpp-snippets)
add_executable(cpp-snippets "main.cpp")
target_compile_features(cpp-snippets PRIVATE cxx_std_17)

Обратитесь к разделу Требование языковых стандартов в официальной документации CMake для CMake-компиляции функции Узнать больше.

15

Проверьте, поддерживает ли компилятор флаги? Возможно что-то вроде

include(CheckCXXCompilerFlag)

# Check for standard to use
check_cxx_compiler_flag(-std=c++17 HAVE_FLAG_STD_CXX17)
if(HAVE_FLAG_STD_CXX17)
# Have -std=c++17, use it
else()
check_cxx_compiler_flag(-std=c++1z HAVE_FLAG_STD_CXX1Z)
if(HAVE_FLAG_STD_CXX1Z)
# Have -std=c++1z, use it
else()
# And so on and on...
endif()
endif()
8
По вопросам рекламы [email protected]