Spec-Zone.ru › CMake 3.5

Заголовок модуля WriteCompilerDetectionHeader

Этот модуль предоставляет функцию write_compiler_detection_header().

Функция WRITE_COMPILER_DETECTION_HEADER может быть использована для генерации файла, подходящего для включения препроцессором, который содержит макросы, используемые в исходном коде:

write_compiler_detection_header(
          FILE <file>
          PREFIX <prefix>
          [OUTPUT_FILES_VAR <output_files_var> OUTPUT_DIR <output_dir>]
          COMPILERS <compiler> [...]
          FEATURES <feature> [...]
          [VERSION <version>]
          [PROLOG <prolog>]
          [EPILOG <epilog>]
)

Функция write_compiler_detection_header генерирует файл <file> с макросами, у которых все имеют префикс <prefix>.

По умолчанию, все содержимое записывается непосредственно в <file>. Можно указать OUTPUT_FILES_VAR, чтобы содержимое, специфичное для компилятора, записывалось в отдельные файлы. Отдельные файлы затем доступны в <output_files_var> и могут быть использованы вызывающей стороной для установки, например. OUTPUT_DIR задаёт относительный путь от основного <file> к файлам, специфичным для компилятора. Например:

write_compiler_detection_header(
  FILE climbingstats_compiler_detection.h
  PREFIX ClimbingStats
  OUTPUT_FILES_VAR support_files
  OUTPUT_DIR compilers
  COMPILERS GNU Clang MSVC
  FEATURES cxx_variadic_templates
)
install(FILES
  ${CMAKE_CURRENT_BINARY_DIR}/climbingstats_compiler_detection.h
  DESTINATION include
)
install(FILES
  ${support_files}
  DESTINATION include/compilers
)

Можно использовать VERSION, чтобы указать версию API, которая должна быть сгенерирована. Будущие версии CMake могут ввести альтернативные API. Определённый API выбирается, если значение <version> больше или равно версии CMake, которая ввела данный API, и меньше версии CMake, которая ввела последующий API. Используется значение переменной CMAKE_MINIMUM_REQUIRED_VERSION, если явная версия не указана. (Начиная с версии CMake 3.5.2, существует только одна версия API.)

PROLOG может быть указан как текстовое содержимое, которое должно быть записано в начале заголовка. EPILOG может быть указан как текстовое содержимое, которое должно быть записано в конце заголовка.

Должны быть указаны как минимум один <compiler> и один <feature>. Компиляторы, известные CMake, но не указанные, обнаруживаются, и для них генерируется препроцессор #error. Для каждого компилятора, известного CMake, генерируется макрос препроцессора, соответствующий <PREFIX>_COMPILER_IS_<compiler>, который содержит значение 0 или 1.

Возможные идентификаторы компиляторов документированы в переменной CMAKE_<LANG>_COMPILER_ID. Доступные возможности в этой версии CMake перечислены в глобальных свойствах CMAKE_C_KNOWN_FEATURES и CMAKE_CXX_KNOWN_FEATURES.

См. руководство cmake-compile-features(7) для получения информации о функциях компиляции.

Макросы проверки функций

Для каждого компилятора генерируется макрос препроцессора, соответствующий <PREFIX>_COMPILER_IS_<compiler>, который содержит либо 0, либо 1, в зависимости от используемого компилятора. Генерируются макросы препроцессора для компонентов версии компилятора, соответствующие <PREFIX>_COMPILER_VERSION_MAJOR <PREFIX>_COMPILER_VERSION_MINOR и <PREFIX>_COMPILER_VERSION_PATCH, содержащие десятичные значения соответствующих компонентов версии компилятора, если они определены.

Генерируется тест препроцессора, основанный на версии компилятора, определяющий, включена ли каждая функция. Генерируется макрос препроцессора, соответствующий <PREFIX>_COMPILER_<FEATURE>, где <FEATURE> — имя <feature> в верхнем регистре, который содержит значение 0 или 1, в зависимости от того, поддерживает ли используемый компилятор функцию:

write_compiler_detection_header(
  FILE climbingstats_compiler_detection.h
  PREFIX ClimbingStats
  COMPILERS GNU Clang AppleClang MSVC
  FEATURES cxx_variadic_templates
)
#if ClimbingStats_COMPILER_CXX_VARIADIC_TEMPLATES
template<typename... T>
void someInterface(T t...) { /* ... */ }
#else
// Compatibility versions
template<typename T1>
void someInterface(T1 t1) { /* ... */ }
template<typename T1, typename T2>
void someInterface(T1 t1, T2 t2) { /* ... */ }
template<typename T1, typename T2, typename T3>
void someInterface(T1 t1, T2 t2, T3 t3) { /* ... */ }
#endif

Макросы символов

Для определённых функций создаются дополнительные символьные определения, которые могут быть условно определены как пустые:

class MyClass ClimbingStats_FINAL
{
    ClimbingStats_CONSTEXPR int someInterface() { return 42; }
};

Макрос ClimbingStats_FINAL будет расширяться до final, если компилятор (и его флаги) поддерживают функцию cxx_final, и макрос ClimbingStats_CONSTEXPR будет расширяться до constexpr, если cxx_constexpr поддерживается.

Следующие функции генерируют соответствующие символьные определения:

Функция Определение Символ
c_restrict <PREFIX>_RESTRICT restrict
cxx_constexpr <PREFIX>_CONSTEXPR constexpr
cxx_deleted_functions <PREFIX>_DELETED_FUNCTION = delete
cxx_extern_templates <PREFIX>_EXTERN_TEMPLATE extern
cxx_final <PREFIX>_FINAL final
cxx_noexcept <PREFIX>_NOEXCEPT noexcept
cxx_noexcept <PREFIX>_NOEXCEPT_EXPR(X) noexcept(X)
cxx_override <PREFIX>_OVERRIDE override

Макросы реализации совместимости

Некоторые функции подходят для обертывания в макрос с реализацией обратной совместимости, если компилятор не поддерживает эту функцию.

Если функция cxx_static_assert не поддерживается компилятором, реализация обратной совместимости доступна через макросы-функции <PREFIX>_STATIC_ASSERT(COND) и <PREFIX>_STATIC_ASSERT_MSG(COND, MSG). Макросы расширяются до static_assert, если функция компилятора доступна, и до реализации обратной совместимости в противном случае. В первом формате условие строит в поле сообщения static_assert. Во втором формате сообщение MSG передаётся в поле сообщения static_assert, или игнорируется при использовании реализации обратной совместимости.

Функция cxx_attribute_deprecated предоставляет определение макроса <PREFIX>_DEPRECATED, который расширяется до стандартного атрибута [[deprecated]] или специфичного для компилятора декоратора, такого как __attribute__((__deprecated__)), используемого компиляторами GNU.

Функция cxx_alignas предоставляет определение макроса <PREFIX>_ALIGNAS, который расширяется до стандартного декоратора alignas или специфичного для компилятора декоратора, такого как __attribute__ ((__aligned__)), используемого компиляторами GNU.

Функция cxx_alignof предоставляет определение макроса <PREFIX>_ALIGNOF, который расширяется до стандартного декоратора alignof или специфичного для компилятора декоратора, такого как __alignof__, используемого компиляторами GNU.

Функция Определение Символ
cxx_alignas <PREFIX>_ALIGNAS alignas
cxx_alignof <PREFIX>_ALIGNOF alignof
cxx_nullptr <PREFIX>_NULLPTR nullptr
cxx_static_assert <PREFIX>_STATIC_ASSERT static_assert
cxx_static_assert <PREFIX>_STATIC_ASSERT_MSG static_assert
cxx_attribute_deprecated <PREFIX>_DEPRECATED [[deprecated]]
cxx_attribute_deprecated <PREFIX>_DEPRECATED_MSG [[deprecated]]
cxx_thread_local <PREFIX>_THREAD_LOCAL thread_local

Пример использования таких макросов обратной совместимости — устаревание целой библиотеки. В этом случае весь публичный API библиотеки может быть помечен макросом <PREFIX>_DEPRECATED. Это приводит к очень шумному выводу сборки при сборке самой библиотеки, поэтому макрос может быть определён как пустой в этом случае при сборке устаревшей библиотеки:

add_library(compat_support ${srcs})
target_compile_definitions(compat_support
  PRIVATE
    CompatSupport_DEPRECATED=
)

© 2000–2019 Kitware, Inc. and Contributors
Licensed under the BSD 3-clause License.
https://cmake.org/cmake/help/v3.5/module/WriteCompilerDetectionHeader.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API