diff options
Diffstat (limited to 'share/cmake-3.18/Modules/WriteCompilerDetectionHeader.cmake')
-rw-r--r-- | share/cmake-3.18/Modules/WriteCompilerDetectionHeader.cmake | 693 |
1 files changed, 693 insertions, 0 deletions
diff --git a/share/cmake-3.18/Modules/WriteCompilerDetectionHeader.cmake b/share/cmake-3.18/Modules/WriteCompilerDetectionHeader.cmake new file mode 100644 index 0000000..23d81b5 --- /dev/null +++ b/share/cmake-3.18/Modules/WriteCompilerDetectionHeader.cmake @@ -0,0 +1,693 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +#[=======================================================================[.rst: +WriteCompilerDetectionHeader +---------------------------- + +This module provides the function ``write_compiler_detection_header()``. + +This function can be used to generate a file suitable for preprocessor +inclusion which contains macros to be used in source code:: + + 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] + ) + +This generates the file ``<file>`` with macros which all have the prefix +``<prefix>``. + +By default, all content is written directly to the ``<file>``. The +``OUTPUT_FILES_VAR`` may be specified to cause the compiler-specific +content to be written to separate files. The separate files are then +available in the ``<output_files_var>`` and may be consumed by the caller +for installation for example. The ``OUTPUT_DIR`` specifies a relative +path from the main ``<file>`` to the compiler-specific files. For example: + +.. code-block:: cmake + + 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`` may be used to specify the API version to be generated. +Future versions of CMake may introduce alternative APIs. A given +API is selected by any ``<version>`` value greater than or equal +to the version of CMake that introduced the given API and less +than the version of CMake that introduced its succeeding API. +The value of the :variable:`CMAKE_MINIMUM_REQUIRED_VERSION` +variable is used if no explicit version is specified. +(As of CMake version |release| there is only one API version.) + +``PROLOG`` may be specified as text content to write at the start of the +header. ``EPILOG`` may be specified as text content to write at the end +of the header + +At least one ``<compiler>`` and one ``<feature>`` must be listed. Compilers +which are known to CMake, but not specified are detected and a preprocessor +``#error`` is generated for them. A preprocessor macro matching +``<PREFIX>_COMPILER_IS_<compiler>`` is generated for each compiler +known to CMake to contain the value ``0`` or ``1``. + +Possible compiler identifiers are documented with the +:variable:`CMAKE_<LANG>_COMPILER_ID` variable. +Available features in this version of CMake are listed in the +:prop_gbl:`CMAKE_C_KNOWN_FEATURES` and +:prop_gbl:`CMAKE_CXX_KNOWN_FEATURES` global properties. +The ``{c,cxx}_std_*`` meta-features are ignored if requested. + +See the :manual:`cmake-compile-features(7)` manual for information on +compile features. + +``BARE_FEATURES`` will define the compatibility macros with the name used in +newer versions of the language standard, so the code can use the new feature +name unconditionally. + +``ALLOW_UNKNOWN_COMPILERS`` and ``ALLOW_UNKNOWN_COMPILER_VERSIONS`` cause +the module to generate conditions that treat unknown compilers as simply +lacking all features. Without these options the default behavior is to +generate a ``#error`` for unknown compilers and versions. + +Feature Test Macros +=================== + +For each compiler, a preprocessor macro is generated matching +``<PREFIX>_COMPILER_IS_<compiler>`` which has the content either ``0`` +or ``1``, depending on the compiler in use. Preprocessor macros for +compiler version components are generated matching +``<PREFIX>_COMPILER_VERSION_MAJOR`` ``<PREFIX>_COMPILER_VERSION_MINOR`` +and ``<PREFIX>_COMPILER_VERSION_PATCH`` containing decimal values +for the corresponding compiler version components, if defined. + +A preprocessor test is generated based on the compiler version +denoting whether each feature is enabled. A preprocessor macro +matching ``<PREFIX>_COMPILER_<FEATURE>``, where ``<FEATURE>`` is the +upper-case ``<feature>`` name, is generated to contain the value +``0`` or ``1`` depending on whether the compiler in use supports the +feature: + +.. code-block:: cmake + + write_compiler_detection_header( + FILE climbingstats_compiler_detection.h + PREFIX ClimbingStats + COMPILERS GNU Clang AppleClang MSVC Intel + FEATURES cxx_variadic_templates + ) + +.. code-block:: c++ + + #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 + +Symbol Macros +============= + +Some additional symbol-defines are created for particular features for +use as symbols which may be conditionally defined empty: + +.. code-block:: c++ + + class MyClass ClimbingStats_FINAL + { + ClimbingStats_CONSTEXPR int someInterface() { return 42; } + }; + +The ``ClimbingStats_FINAL`` macro will expand to ``final`` if the +compiler (and its flags) support the ``cxx_final`` feature, and the +``ClimbingStats_CONSTEXPR`` macro will expand to ``constexpr`` +if ``cxx_constexpr`` is supported. + +If ``BARE_FEATURES cxx_final`` was given as argument the ``final`` keyword +will be defined for old compilers, too. + +The following features generate corresponding symbol defines and if they +are available as ``BARE_FEATURES``: + +========================== =================================== ================= ====== + Feature Define Symbol bare +========================== =================================== ================= ====== +``c_restrict`` ``<PREFIX>_RESTRICT`` ``restrict`` yes +``cxx_constexpr`` ``<PREFIX>_CONSTEXPR`` ``constexpr`` yes +``cxx_deleted_functions`` ``<PREFIX>_DELETED_FUNCTION`` ``= delete`` +``cxx_extern_templates`` ``<PREFIX>_EXTERN_TEMPLATE`` ``extern`` +``cxx_final`` ``<PREFIX>_FINAL`` ``final`` yes +``cxx_noexcept`` ``<PREFIX>_NOEXCEPT`` ``noexcept`` yes +``cxx_noexcept`` ``<PREFIX>_NOEXCEPT_EXPR(X)`` ``noexcept(X)`` +``cxx_override`` ``<PREFIX>_OVERRIDE`` ``override`` yes +========================== =================================== ================= ====== + +Compatibility Implementation Macros +=================================== + +Some features are suitable for wrapping in a macro with a backward +compatibility implementation if the compiler does not support the feature. + +When the ``cxx_static_assert`` feature is not provided by the compiler, +a compatibility implementation is available via the +``<PREFIX>_STATIC_ASSERT(COND)`` and +``<PREFIX>_STATIC_ASSERT_MSG(COND, MSG)`` function-like macros. The macros +expand to ``static_assert`` where that compiler feature is available, and +to a compatibility implementation otherwise. In the first form, the +condition is stringified in the message field of ``static_assert``. In +the second form, the message ``MSG`` is passed to the message field of +``static_assert``, or ignored if using the backward compatibility +implementation. + +The ``cxx_attribute_deprecated`` feature provides a macro definition +``<PREFIX>_DEPRECATED``, which expands to either the standard +``[[deprecated]]`` attribute or a compiler-specific decorator such +as ``__attribute__((__deprecated__))`` used by GNU compilers. + +The ``cxx_alignas`` feature provides a macro definition +``<PREFIX>_ALIGNAS`` which expands to either the standard ``alignas`` +decorator or a compiler-specific decorator such as +``__attribute__ ((__aligned__))`` used by GNU compilers. + +The ``cxx_alignof`` feature provides a macro definition +``<PREFIX>_ALIGNOF`` which expands to either the standard ``alignof`` +decorator or a compiler-specific decorator such as ``__alignof__`` +used by GNU compilers. + +============================= ================================ ===================== ====== + Feature Define Symbol bare +============================= ================================ ===================== ====== +``cxx_alignas`` ``<PREFIX>_ALIGNAS`` ``alignas`` +``cxx_alignof`` ``<PREFIX>_ALIGNOF`` ``alignof`` +``cxx_nullptr`` ``<PREFIX>_NULLPTR`` ``nullptr`` yes +``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`` +============================= ================================ ===================== ====== + +A use-case which arises with such deprecation macros is the deprecation +of an entire library. In that case, all public API in the library may +be decorated with the ``<PREFIX>_DEPRECATED`` macro. This results in +very noisy build output when building the library itself, so the macro +may be may be defined to empty in that case when building the deprecated +library: + +.. code-block:: cmake + + add_library(compat_support ${srcs}) + target_compile_definitions(compat_support + PRIVATE + CompatSupport_DEPRECATED= + ) +#]=======================================================================] + +include(${CMAKE_CURRENT_LIST_DIR}/CMakeCompilerIdDetection.cmake) + +function(_load_compiler_variables CompilerId lang) + include("${CMAKE_ROOT}/Modules/Compiler/${CompilerId}-${lang}-FeatureTests.cmake" OPTIONAL) + set(_cmake_oldestSupported_${CompilerId} ${_cmake_oldestSupported} PARENT_SCOPE) + foreach(feature ${ARGN}) + set(_cmake_feature_test_${CompilerId}_${feature} ${_cmake_feature_test_${feature}} PARENT_SCOPE) + endforeach() + include("${CMAKE_ROOT}/Modules/Compiler/${CompilerId}-${lang}-DetermineCompiler.cmake" OPTIONAL + RESULT_VARIABLE determinedCompiler) + if (NOT determinedCompiler) + include("${CMAKE_ROOT}/Modules/Compiler/${CompilerId}-DetermineCompiler.cmake" OPTIONAL) + endif() + set(_compiler_id_version_compute_${CompilerId} ${_compiler_id_version_compute} PARENT_SCOPE) +endfunction() + +macro(_simpledefine FEATURE_NAME FEATURE_TESTNAME FEATURE_STRING FEATURE_DEFAULT_STRING) + if (feature STREQUAL "${FEATURE_NAME}") + set(def_value "${prefix_arg}_${FEATURE_TESTNAME}") + string(APPEND file_content " +# if defined(${def_name}) && ${def_name} +# define ${def_value} ${FEATURE_STRING} +# else +# define ${def_value} ${FEATURE_DEFAULT_STRING} +# endif +\n") + endif() +endmacro() + +macro(_simplebaredefine FEATURE_NAME FEATURE_STRING FEATURE_DEFAULT_STRING) + if (feature STREQUAL "${FEATURE_NAME}") + string(APPEND file_content " +# if !(defined(${def_name}) && ${def_name}) +# define ${FEATURE_STRING} ${FEATURE_DEFAULT_STRING} +# endif +\n") + endif() +endmacro() + +function(_check_feature_lists C_FEATURE_VAR CXX_FEATURE_VAR) + foreach(feature ${ARGN}) + if (feature MATCHES "^c_std_") + # ignored + elseif (feature MATCHES "^cxx_std_") + # ignored + elseif (feature MATCHES "^cxx_") + list(APPEND _langs CXX) + list(APPEND ${CXX_FEATURE_VAR} ${feature}) + elseif (feature MATCHES "^c_") + list(APPEND _langs C) + list(APPEND ${C_FEATURE_VAR} ${feature}) + else() + message(FATAL_ERROR "Unsupported feature ${feature}.") + endif() + endforeach() + set(${C_FEATURE_VAR} ${${C_FEATURE_VAR}} PARENT_SCOPE) + set(${CXX_FEATURE_VAR} ${${CXX_FEATURE_VAR}} PARENT_SCOPE) + set(_langs ${_langs} PARENT_SCOPE) +endfunction() + +function(write_compiler_detection_header + file_keyword file_arg + prefix_keyword prefix_arg + ) + if (NOT "x${file_keyword}" STREQUAL "xFILE") + message(FATAL_ERROR "write_compiler_detection_header: FILE parameter missing.") + endif() + if (NOT "x${prefix_keyword}" STREQUAL "xPREFIX") + message(FATAL_ERROR "write_compiler_detection_header: PREFIX parameter missing.") + endif() + set(options ALLOW_UNKNOWN_COMPILERS ALLOW_UNKNOWN_COMPILER_VERSIONS) + set(oneValueArgs VERSION EPILOG PROLOG OUTPUT_FILES_VAR OUTPUT_DIR) + set(multiValueArgs COMPILERS FEATURES BARE_FEATURES) + cmake_parse_arguments(_WCD "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + + if (NOT _WCD_COMPILERS) + message(FATAL_ERROR "Invalid arguments. write_compiler_detection_header requires at least one compiler.") + endif() + if (NOT _WCD_FEATURES AND NOT _WCD_BARE_FEATURES) + message(FATAL_ERROR "Invalid arguments. write_compiler_detection_header requires at least one feature.") + endif() + + if(_WCD_UNPARSED_ARGUMENTS) + message(FATAL_ERROR "Unparsed arguments: ${_WCD_UNPARSED_ARGUMENTS}") + endif() + + if (prefix_arg STREQUAL "") + message(FATAL_ERROR "A prefix must be specified") + endif() + string(MAKE_C_IDENTIFIER ${prefix_arg} cleaned_prefix) + if (NOT prefix_arg STREQUAL cleaned_prefix) + message(FATAL_ERROR "The prefix must be a valid C identifier.") + endif() + + if(NOT _WCD_VERSION) + set(_WCD_VERSION ${CMAKE_MINIMUM_REQUIRED_VERSION}) + endif() + set(_min_version 3.1.0) # Version which introduced this function + if (_WCD_VERSION VERSION_LESS _min_version) + set(err "VERSION compatibility for write_compiler_detection_header is set to ${_WCD_VERSION}, which is too low.") + string(APPEND err " It must be set to at least ${_min_version}. ") + string(APPEND err " Either set the VERSION parameter to the write_compiler_detection_header function, or update") + string(APPEND err " your minimum required CMake version with the cmake_minimum_required command.") + message(FATAL_ERROR "${err}") + endif() + + if(_WCD_OUTPUT_FILES_VAR) + if(NOT _WCD_OUTPUT_DIR) + message(FATAL_ERROR "If OUTPUT_FILES_VAR is specified, then OUTPUT_DIR must also be specified.") + endif() + endif() + if(_WCD_OUTPUT_DIR) + if(NOT _WCD_OUTPUT_FILES_VAR) + message(FATAL_ERROR "If OUTPUT_DIR is specified, then OUTPUT_FILES_VAR must also be specified.") + endif() + get_filename_component(main_file_dir ${file_arg} DIRECTORY) + if (NOT IS_ABSOLUTE ${main_file_dir}) + set(main_file_dir "${CMAKE_CURRENT_BINARY_DIR}/${main_file_dir}") + endif() + if (NOT IS_ABSOLUTE ${_WCD_OUTPUT_DIR}) + set(_WCD_OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/${_WCD_OUTPUT_DIR}") + endif() + get_filename_component(out_file_dir ${_WCD_OUTPUT_DIR} ABSOLUTE) + string(FIND ${out_file_dir} ${main_file_dir} idx) + if (NOT idx EQUAL 0) + message(FATAL_ERROR "The compiler-specific output directory must be within the same directory as the main file.") + endif() + + if (main_file_dir STREQUAL out_file_dir) + unset(_WCD_OUTPUT_DIR) + else() + string(REPLACE "${main_file_dir}/" "" _WCD_OUTPUT_DIR "${out_file_dir}/") + endif() + endif() + + set(compilers + GNU + Clang + AppleClang + MSVC + SunPro + Intel + ) + + set(_hex_compilers ADSP Borland Embarcadero SunPro) + + foreach(_comp ${_WCD_COMPILERS}) + list(FIND compilers ${_comp} idx) + if (idx EQUAL -1) + message(FATAL_ERROR "Unsupported compiler ${_comp}.") + endif() + if (NOT _need_hex_conversion) + list(FIND _hex_compilers ${_comp} idx) + if (NOT idx EQUAL -1) + set(_need_hex_conversion TRUE) + endif() + endif() + endforeach() + + set(file_content " +// This is a generated file. Do not edit! + +#ifndef ${prefix_arg}_COMPILER_DETECTION_H +#define ${prefix_arg}_COMPILER_DETECTION_H +") + + if (_WCD_PROLOG) + string(APPEND file_content "\n${_WCD_PROLOG}\n") + endif() + + if (_need_hex_conversion) + string(APPEND file_content " +#define ${prefix_arg}_DEC(X) (X) +#define ${prefix_arg}_HEX(X) ( \\ + ((X)>>28 & 0xF) * 10000000 + \\ + ((X)>>24 & 0xF) * 1000000 + \\ + ((X)>>20 & 0xF) * 100000 + \\ + ((X)>>16 & 0xF) * 10000 + \\ + ((X)>>12 & 0xF) * 1000 + \\ + ((X)>>8 & 0xF) * 100 + \\ + ((X)>>4 & 0xF) * 10 + \\ + ((X) & 0xF) \\ + )\n") + endif() + + _check_feature_lists(C_features CXX_features ${_WCD_FEATURES}) + _check_feature_lists(C_bare_features CXX_bare_features ${_WCD_BARE_FEATURES}) + list(REMOVE_DUPLICATES _langs) + + if(_WCD_OUTPUT_FILES_VAR) + get_filename_component(main_file_name ${file_arg} NAME) + set(compiler_file_content_ +"#ifndef ${prefix_arg}_COMPILER_DETECTION_H +# error This file may only be included from ${main_file_name} +#endif\n") + endif() + + foreach(_lang ${_langs}) + set(target_compilers) + foreach(compiler ${_WCD_COMPILERS}) + _load_compiler_variables(${compiler} ${_lang} ${${_lang}_features}) + if(_cmake_oldestSupported_${compiler}) + list(APPEND target_compilers ${compiler}) + endif() + endforeach() + + get_property(known_features GLOBAL PROPERTY CMAKE_${_lang}_KNOWN_FEATURES) + foreach(feature ${${_lang}_features}) + list(FIND known_features ${feature} idx) + if (idx EQUAL -1) + message(FATAL_ERROR "Unsupported feature ${feature}.") + endif() + endforeach() + + if(_lang STREQUAL CXX) + string(APPEND file_content "\n#ifdef __cplusplus\n") + else() + string(APPEND file_content "\n#ifndef __cplusplus\n") + endif() + + compiler_id_detection(ID_CONTENT ${_lang} PREFIX ${prefix_arg}_ + ID_DEFINE + ) + + string(APPEND file_content "${ID_CONTENT}\n") + + set(pp_if "if") + foreach(compiler ${target_compilers}) + string(APPEND file_content "\n# ${pp_if} ${prefix_arg}_COMPILER_IS_${compiler}\n") + + if(_WCD_OUTPUT_FILES_VAR) + set(compile_file_name "${_WCD_OUTPUT_DIR}${prefix_arg}_COMPILER_INFO_${compiler}_${_lang}.h") + string(APPEND file_content "\n# include \"${compile_file_name}\"\n") + endif() + + if(_WCD_OUTPUT_FILES_VAR) + set(compiler_file_content compiler_file_content_${compiler}_${_lang}) + else() + set(compiler_file_content file_content) + endif() + + if(NOT _WCD_ALLOW_UNKNOWN_COMPILER_VERSIONS) + string(APPEND ${compiler_file_content} " +# if !(${_cmake_oldestSupported_${compiler}}) +# error Unsupported compiler version +# endif\n") + endif() + + set(PREFIX ${prefix_arg}_) + if (_need_hex_conversion) + set(MACRO_DEC ${prefix_arg}_DEC) + set(MACRO_HEX ${prefix_arg}_HEX) + else() + set(MACRO_DEC) + set(MACRO_HEX) + endif() + string(CONFIGURE "${_compiler_id_version_compute_${compiler}}" VERSION_BLOCK @ONLY) + string(APPEND ${compiler_file_content} "${VERSION_BLOCK}\n") + set(PREFIX) + set(MACRO_DEC) + set(MACRO_HEX) + + set(pp_if "elif") + foreach(feature ${${_lang}_features}) + string(TOUPPER ${feature} feature_upper) + set(feature_PP "COMPILER_${feature_upper}") + set(_define_item "\n# define ${prefix_arg}_${feature_PP} 0\n") + if (_cmake_feature_test_${compiler}_${feature} STREQUAL "1") + set(_define_item "\n# define ${prefix_arg}_${feature_PP} 1\n") + elseif (_cmake_feature_test_${compiler}_${feature}) + set(_define_item "\n# define ${prefix_arg}_${feature_PP} 0\n") + set(_define_item "\n# if ${_cmake_feature_test_${compiler}_${feature}}\n# define ${prefix_arg}_${feature_PP} 1\n# else${_define_item}# endif\n") + endif() + string(APPEND ${compiler_file_content} "${_define_item}") + endforeach() + endforeach() + if(pp_if STREQUAL "elif") + if(_WCD_ALLOW_UNKNOWN_COMPILERS) + string(APPEND file_content " +# endif\n") + else() + string(APPEND file_content " +# else +# error Unsupported compiler +# endif\n") + endif() + endif() + foreach(feature ${${_lang}_features}) + string(TOUPPER ${feature} feature_upper) + set(feature_PP "COMPILER_${feature_upper}") + set(def_name ${prefix_arg}_${feature_PP}) + _simpledefine(c_restrict RESTRICT restrict "") + _simpledefine(cxx_constexpr CONSTEXPR constexpr "") + _simpledefine(cxx_final FINAL final "") + _simpledefine(cxx_override OVERRIDE override "") + if (feature STREQUAL cxx_static_assert) + set(def_value "${prefix_arg}_STATIC_ASSERT(X)") + set(def_value_msg "${prefix_arg}_STATIC_ASSERT_MSG(X, MSG)") + set(def_fallback "enum { ${prefix_arg}_STATIC_ASSERT_JOIN(${prefix_arg}StaticAssertEnum, __LINE__) = sizeof(${prefix_arg}StaticAssert<X>) }") + string(APPEND file_content "# if defined(${def_name}) && ${def_name} +# define ${def_value} static_assert(X, #X) +# define ${def_value_msg} static_assert(X, MSG) +# else +# define ${prefix_arg}_STATIC_ASSERT_JOIN(X, Y) ${prefix_arg}_STATIC_ASSERT_JOIN_IMPL(X, Y) +# define ${prefix_arg}_STATIC_ASSERT_JOIN_IMPL(X, Y) X##Y +template<bool> struct ${prefix_arg}StaticAssert; +template<> struct ${prefix_arg}StaticAssert<true>{}; +# define ${def_value} ${def_fallback} +# define ${def_value_msg} ${def_fallback} +# endif +\n") + endif() + if (feature STREQUAL cxx_alignas) + set(def_value "${prefix_arg}_ALIGNAS(X)") + string(APPEND file_content " +# if defined(${def_name}) && ${def_name} +# define ${def_value} alignas(X) +# elif ${prefix_arg}_COMPILER_IS_GNU || ${prefix_arg}_COMPILER_IS_Clang || ${prefix_arg}_COMPILER_IS_AppleClang +# define ${def_value} __attribute__ ((__aligned__(X))) +# elif ${prefix_arg}_COMPILER_IS_MSVC +# define ${def_value} __declspec(align(X)) +# else +# define ${def_value} +# endif +\n") + endif() + if (feature STREQUAL cxx_alignof) + set(def_value "${prefix_arg}_ALIGNOF(X)") + string(APPEND file_content " +# if defined(${def_name}) && ${def_name} +# define ${def_value} alignof(X) +# elif ${prefix_arg}_COMPILER_IS_GNU || ${prefix_arg}_COMPILER_IS_Clang || ${prefix_arg}_COMPILER_IS_AppleClang +# define ${def_value} __alignof__(X) +# elif ${prefix_arg}_COMPILER_IS_MSVC +# define ${def_value} __alignof(X) +# endif +\n") + endif() + _simpledefine(cxx_deleted_functions DELETED_FUNCTION "= delete" "") + _simpledefine(cxx_extern_templates EXTERN_TEMPLATE extern "") + if (feature STREQUAL cxx_noexcept) + set(def_value "${prefix_arg}_NOEXCEPT") + string(APPEND file_content " +# if defined(${def_name}) && ${def_name} +# define ${def_value} noexcept +# define ${def_value}_EXPR(X) noexcept(X) +# else +# define ${def_value} +# define ${def_value}_EXPR(X) +# endif +\n") + endif() + if (feature STREQUAL cxx_nullptr) + set(def_value "${prefix_arg}_NULLPTR") + string(APPEND file_content " +# if defined(${def_name}) && ${def_name} +# define ${def_value} nullptr +# elif ${prefix_arg}_COMPILER_IS_GNU +# define ${def_value} __null +# else +# define ${def_value} 0 +# endif +\n") + endif() + if (feature STREQUAL cxx_thread_local) + set(def_value "${prefix_arg}_THREAD_LOCAL") + string(APPEND file_content " +# if defined(${def_name}) && ${def_name} +# define ${def_value} thread_local +# elif ${prefix_arg}_COMPILER_IS_GNU || ${prefix_arg}_COMPILER_IS_Clang || ${prefix_arg}_COMPILER_IS_AppleClang +# define ${def_value} __thread +# elif ${prefix_arg}_COMPILER_IS_MSVC +# define ${def_value} __declspec(thread) +# else +// ${def_value} not defined for this configuration. +# endif +\n") + endif() + if (feature STREQUAL cxx_attribute_deprecated) + set(def_name ${prefix_arg}_${feature_PP}) + set(def_value "${prefix_arg}_DEPRECATED") + string(APPEND file_content " +# ifndef ${def_value} +# if defined(${def_name}) && ${def_name} +# define ${def_value} [[deprecated]] +# define ${def_value}_MSG(MSG) [[deprecated(MSG)]] +# elif ${prefix_arg}_COMPILER_IS_GNU || ${prefix_arg}_COMPILER_IS_Clang +# define ${def_value} __attribute__((__deprecated__)) +# define ${def_value}_MSG(MSG) __attribute__((__deprecated__(MSG))) +# elif ${prefix_arg}_COMPILER_IS_MSVC +# define ${def_value} __declspec(deprecated) +# define ${def_value}_MSG(MSG) __declspec(deprecated(MSG)) +# else +# define ${def_value} +# define ${def_value}_MSG(MSG) +# endif +# endif +\n") + endif() + endforeach() + + foreach(feature ${${_lang}_bare_features}) + string(TOUPPER ${feature} feature_upper) + set(feature_PP "COMPILER_${feature_upper}") + set(def_name ${prefix_arg}_${feature_PP}) + _simplebaredefine(c_restrict restrict "") + _simplebaredefine(cxx_constexpr constexpr "") + _simplebaredefine(cxx_final final "") + _simplebaredefine(cxx_override override "") + if (feature STREQUAL cxx_nullptr) + set(def_value "nullptr") + string(APPEND file_content " +# if !(defined(${def_name}) && ${def_name}) +# if ${prefix_arg}_COMPILER_IS_GNU +# define ${def_value} __null +# else +# define ${def_value} 0 +# endif +# endif +\n") + endif() + _simplebaredefine(cxx_noexcept noexcept "") + endforeach() + + string(APPEND file_content "#endif\n") + + endforeach() + + if(_WCD_OUTPUT_FILES_VAR) + foreach(compiler ${_WCD_COMPILERS}) + foreach(_lang ${_langs}) + if(compiler_file_content_${compiler}_${_lang}) + set(CMAKE_CONFIGURABLE_FILE_CONTENT "${compiler_file_content_}") + string(APPEND CMAKE_CONFIGURABLE_FILE_CONTENT "${compiler_file_content_${compiler}_${_lang}}") + + set(compile_file_name "${_WCD_OUTPUT_DIR}${prefix_arg}_COMPILER_INFO_${compiler}_${_lang}.h") + set(full_path "${main_file_dir}/${compile_file_name}") + list(APPEND ${_WCD_OUTPUT_FILES_VAR} ${full_path}) + configure_file("${CMAKE_ROOT}/Modules/CMakeConfigurableFile.in" + "${full_path}" + @ONLY + ) + endif() + endforeach() + endforeach() + set(${_WCD_OUTPUT_FILES_VAR} ${${_WCD_OUTPUT_FILES_VAR}} PARENT_SCOPE) + endif() + + if (_WCD_EPILOG) + string(APPEND file_content "\n${_WCD_EPILOG}\n") + endif() + string(APPEND file_content "\n#endif") + + set(CMAKE_CONFIGURABLE_FILE_CONTENT ${file_content}) + configure_file("${CMAKE_ROOT}/Modules/CMakeConfigurableFile.in" + "${file_arg}" + @ONLY + ) +endfunction() |