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>]
[ALLOW_UNKNOWN_COMPILERS]
[ALLOW_UNKNOWN_COMPILER_VERSIONS]
)
Функция 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 Intel
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.8.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. Мета-функции {c,cxx}_std_* игнорируются, если они запрошены.
См. руководство cmake-compile-features(7) для получения информации о функциях компиляции.
ALLOW_UNKNOWN_COMPILERS и ALLOW_UNKNOWN_COMPILER_VERSIONS заставляют модуль генерировать условия, которые рассматривают неизвестные компиляторы как просто не имеющие всех функций. Без этих опций по умолчанию генерируется #error для неизвестных компиляторов.
Макросы проверки функций
Для каждого компилятора генерируется препроцессорный макрос, соответствующий <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 Intel 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.8/module/WriteCompilerDetectionHeader.html