WriteCompilerDetectionHeader
Этот модуль предоставляет функцию 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> [...]
[BARE_FEATURES <feature> [...]]
[VERSION <version>]
[PROLOG <prolog>]
[EPILOG <epilog>]
[ALLOW_UNKNOWN_COMPILERS]
[ALLOW_UNKNOWN_COMPILER_VERSIONS]
)
Это генерирует файл <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.15.7 существует только одна версия 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) для получения информации о возможностях компиляции.
BARE_FEATURES определит макросы совместимости с именем, используемым в более новых версиях стандарта языка, чтобы код мог использовать новое имя функции безусловно.
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 поддерживается.
Если BARE_FEATURES cxx_final был передан в качестве аргумента, ключевое слово final будет определено и для старых компиляторов.
Следующие функции генерируют соответствующие символьные определения, и если они доступны как BARE_FEATURES:
Функция | Определение | Символ | bare |
|---|---|---|---|
|
|
| да |
|
|
| да |
|
|
| |
|
|
| |
|
|
| да |
|
|
| да |
|
|
| |
|
|
| да |
Макросы реализации совместимости
Некоторые функции подходят для обертывания в макрос с реализацией обратной совместимости, если компилятор не поддерживает функцию.
Если функция 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.
Функция | Определение | Символ | bare |
|---|---|---|---|
|
|
| |
|
|
| |
|
|
| да |
|
|
| |
|
|
| |
|
|
| |
|
|
| |
|
|
|
Пример использования, возникающий при таких макросах устаревания, — это устаревание целой библиотеки. В этом случае все общедоступные API в библиотеке могут быть помечены макросом <PREFIX>_DEPRECATED. Это приводит к очень шумному выводу сборки при построении самой библиотеки, поэтому в этом случае при построении устаревшей библиотеки макрос может быть определён как пустой:
add_library(compat_support ${srcs})
target_compile_definitions(compat_support
PRIVATE
CompatSupport_DEPRECATED=
)
© 2000–2020 Kitware, Inc. and Contributors
Licensed under the BSD 3-clause License.
https://cmake.org/cmake/help/v3.15/module/WriteCompilerDetectionHeader.html