Merge topic 'WriteCompilerDetectionHeader-module'
62a4a67d
Add the WriteCompilerDetectionHeader module.
This commit is contained in:
commit
2e347eb183
|
@ -232,3 +232,4 @@ All Modules
|
|||
/module/UsewxWidgets
|
||||
/module/Use_wxWindows
|
||||
/module/WriteBasicConfigVersionFile
|
||||
/module/WriteCompilerDetectionHeader
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
.. cmake-module:: ../../Modules/WriteCompilerDetectionHeader.cmake
|
|
@ -0,0 +1,5 @@
|
|||
module-WriteCompilerDetectionHeader
|
||||
-----------------------------------
|
||||
|
||||
* The :module:`WriteCompilerDetectionHeader` module was added to allow
|
||||
creation of a portable header file for compiler optional feature detection.
|
|
@ -0,0 +1,401 @@
|
|||
#.rst:
|
||||
# WriteCompilerDetectionHeader
|
||||
# ----------------------------
|
||||
#
|
||||
# This module provides the function write_compiler_detection_header().
|
||||
#
|
||||
# The ``WRITE_COMPILER_DETECTION_HEADER`` 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>
|
||||
# COMPILERS <compiler> [...]
|
||||
# FEATURES <feature> [...]
|
||||
# [VERSION <version>]
|
||||
# [PROLOG <prolog>]
|
||||
# [EPILOG <epilog>]
|
||||
# )
|
||||
#
|
||||
# The ``write_compiler_detection_header`` function generates the
|
||||
# file ``<file>`` with macros which all have the prefix ``<prefix>``.
|
||||
#
|
||||
# ``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_CXX_KNOWN_FEATURES` global property.
|
||||
#
|
||||
# Feature Test Macros
|
||||
# ===================
|
||||
#
|
||||
# For each compiler, a preprocessor test of the compiler version is generated
|
||||
# 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 MSVC
|
||||
# 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_DECL_CXX_FINAL
|
||||
# {
|
||||
# ClimbingStats_DECL_CXX_CONSTEXPR int someInterface() { return 42; }
|
||||
# };
|
||||
#
|
||||
# The ``ClimbingStats_DECL_CXX_FINAL`` macro will expand to ``final`` if the
|
||||
# compiler (and its flags) support the ``cxx_final`` feature, and the
|
||||
# ``ClimbingStats_DECL_CXX_CONSTEXPR`` macro will expand to ``constexpr``
|
||||
# if ``cxx_constexpr`` is supported.
|
||||
#
|
||||
# The following features generate corresponding symbol defines:
|
||||
#
|
||||
# ========================== =================================== =================
|
||||
# Feature Define Symbol
|
||||
# ========================== =================================== =================
|
||||
# ``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``
|
||||
# ========================== =================================== =================
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# ====================== ================================ ===================
|
||||
# Feature Define Symbol
|
||||
# ====================== ================================ ===================
|
||||
# ``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``
|
||||
# ====================== ================================ ===================
|
||||
|
||||
|
||||
#=============================================================================
|
||||
# Copyright 2014 Stephen Kelly <steveire@gmail.com>
|
||||
#
|
||||
# Distributed under the OSI-approved BSD License (the "License");
|
||||
# see accompanying file Copyright.txt for details.
|
||||
#
|
||||
# This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
# See the License for more information.
|
||||
#=============================================================================
|
||||
# (To distribute this file outside of CMake, substitute the full
|
||||
# License text for the above reference.)
|
||||
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/CMakeParseArguments.cmake)
|
||||
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()
|
||||
endfunction()
|
||||
|
||||
function(write_compiler_detection_header
|
||||
file_keyword file_arg
|
||||
prefix_keyword prefix_arg
|
||||
)
|
||||
if (NOT file_keyword STREQUAL FILE)
|
||||
message(FATAL_ERROR "write_compiler_detection_header: FILE parameter missing.")
|
||||
endif()
|
||||
if (NOT prefix_keyword STREQUAL PREFIX)
|
||||
message(FATAL_ERROR "write_compiler_detection_header: PREFIX parameter missing.")
|
||||
endif()
|
||||
set(options)
|
||||
set(oneValueArgs VERSION EPILOG PROLOG)
|
||||
set(multiValueArgs COMPILERS 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)
|
||||
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(NOT _WCD_VERSION)
|
||||
set(_WCD_VERSION ${CMAKE_MINIMUM_REQUIRED_VERSION})
|
||||
endif()
|
||||
if (_WCD_VERSION VERSION_LESS 3.1.0) # Version which introduced this function
|
||||
message(FATAL_ERROR "VERSION parameter too low.")
|
||||
endif()
|
||||
|
||||
set(compilers
|
||||
GNU
|
||||
)
|
||||
foreach(_comp ${_WCD_COMPILERS})
|
||||
list(FIND compilers ${_comp} idx)
|
||||
if (idx EQUAL -1)
|
||||
message(FATAL_ERROR "Unsupported compiler ${_comp}.")
|
||||
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)
|
||||
set(file_content "${file_content}\n${_WCD_PROLOG}\n")
|
||||
endif()
|
||||
|
||||
foreach(feature ${_WCD_FEATURES})
|
||||
if (feature MATCHES "^cxx_")
|
||||
list(APPEND _langs CXX)
|
||||
list(APPEND CXX_features ${feature})
|
||||
else()
|
||||
message(FATAL_ERROR "Unsupported feature ${feature}.")
|
||||
endif()
|
||||
endforeach()
|
||||
list(REMOVE_DUPLICATES _langs)
|
||||
|
||||
foreach(_lang ${_langs})
|
||||
|
||||
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)
|
||||
set(file_content "${file_content}\n#ifdef __cplusplus\n")
|
||||
endif()
|
||||
|
||||
compiler_id_detection(ID_CONTENT ${_lang} PREFIX ${prefix_arg}_
|
||||
ID_DEFINE
|
||||
)
|
||||
|
||||
set(file_content "${file_content}${ID_CONTENT}\n")
|
||||
|
||||
set(pp_if "if")
|
||||
foreach(compiler ${_WCD_COMPILERS})
|
||||
_load_compiler_variables(${compiler} ${_lang} ${${_lang}_features})
|
||||
set(file_content "${file_content}\n# ${pp_if} ${prefix_arg}_COMPILER_IS_${compiler}\n")
|
||||
set(file_content "${file_content}
|
||||
# if !(${_cmake_oldestSupported_${compiler}})
|
||||
# error Unsupported compiler version
|
||||
# endif\n")
|
||||
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()
|
||||
set(file_content "${file_content}${_define_item}")
|
||||
endforeach()
|
||||
endforeach()
|
||||
if(pp_if STREQUAL "elif")
|
||||
set(file_content "${file_content}
|
||||
# else
|
||||
# error Unsupported compiler
|
||||
# endif\n")
|
||||
endif()
|
||||
foreach(feature ${${_lang}_features})
|
||||
string(TOUPPER ${feature} feature_upper)
|
||||
set(feature_PP "COMPILER_${feature_upper}")
|
||||
set(def_name ${prefix_arg}_${feature_PP})
|
||||
if (feature STREQUAL cxx_constexpr)
|
||||
set(def_value "${prefix_arg}_DECL_${feature_upper}")
|
||||
set(file_content "${file_content}
|
||||
# if ${def_name}
|
||||
# define ${def_value} constexpr
|
||||
# else
|
||||
# define ${def_value}
|
||||
# endif
|
||||
\n")
|
||||
endif()
|
||||
if (feature STREQUAL cxx_final)
|
||||
set(def_value "${prefix_arg}_DECL_${feature_upper}")
|
||||
set(file_content "${file_content}
|
||||
# if ${def_name}
|
||||
# define ${def_value} final
|
||||
# else
|
||||
# define ${def_value}
|
||||
# endif
|
||||
\n")
|
||||
endif()
|
||||
if (feature STREQUAL cxx_override)
|
||||
set(def_value "${prefix_arg}_DECL_${feature_upper}")
|
||||
set(file_content "${file_content}
|
||||
# if ${def_name}
|
||||
# define ${def_value} override
|
||||
# else
|
||||
# define ${def_value}
|
||||
# endif
|
||||
\n")
|
||||
endif()
|
||||
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(static_assert_struct "template<bool> struct ${prefix_arg}StaticAssert;\ntemplate<> struct ${prefix_arg}StaticAssert<true>{};\n")
|
||||
set(def_standard "# define ${def_value} static_assert(X, #X)\n# define ${def_value_msg} static_assert(X, MSG)")
|
||||
set(def_alternative "${static_assert_struct}# define ${def_value} sizeof(${prefix_arg}StaticAssert<X>)\n# define ${def_value_msg} sizeof(${prefix_arg}StaticAssert<X>)")
|
||||
set(file_content "${file_content}# if ${def_name}\n${def_standard}\n# else\n${def_alternative}\n# endif\n\n")
|
||||
endif()
|
||||
if (feature STREQUAL cxx_alignas)
|
||||
set(def_value "${prefix_arg}_ALIGNAS(X)")
|
||||
set(file_content "${file_content}
|
||||
# if ${def_name}
|
||||
# define ${def_value} alignas(X)
|
||||
# elif ${prefix_arg}_COMPILER_IS_GNU
|
||||
# define ${def_value} __attribute__ ((__aligned__(X)))
|
||||
# else
|
||||
# define ${def_value}
|
||||
# endif
|
||||
\n")
|
||||
endif()
|
||||
if (feature STREQUAL cxx_alignof)
|
||||
set(def_value "${prefix_arg}_ALIGNOF(X)")
|
||||
set(file_content "${file_content}
|
||||
# if ${def_name}
|
||||
# define ${def_value} alignof(X)
|
||||
# elif ${prefix_arg}_COMPILER_IS_GNU
|
||||
# define ${def_value} __alignof__(X)
|
||||
# endif
|
||||
\n")
|
||||
endif()
|
||||
if (feature STREQUAL cxx_deleted_functions)
|
||||
set(def_value "${prefix_arg}_DELETED_FUNCTION")
|
||||
set(file_content "${file_content}
|
||||
# if ${def_name}
|
||||
# define ${def_value} = delete
|
||||
# else
|
||||
# define ${def_value}
|
||||
# endif
|
||||
\n")
|
||||
endif()
|
||||
if (feature STREQUAL cxx_extern_templates)
|
||||
set(def_value "${prefix_arg}_EXTERN_TEMPLATE")
|
||||
set(file_content "${file_content}
|
||||
# if ${def_name}
|
||||
# define ${def_value} extern
|
||||
# else
|
||||
# define ${def_value}
|
||||
# endif
|
||||
\n")
|
||||
endif()
|
||||
if (feature STREQUAL cxx_noexcept)
|
||||
set(def_value "${prefix_arg}_NOEXCEPT")
|
||||
set(file_content "${file_content}
|
||||
# if ${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")
|
||||
set(file_content "${file_content}
|
||||
# if ${def_name}
|
||||
# define ${def_value} nullptr
|
||||
# else
|
||||
# define ${def_value} static_cast<void*>(0)
|
||||
# endif
|
||||
\n")
|
||||
endif()
|
||||
endforeach()
|
||||
if(_lang STREQUAL CXX)
|
||||
set(file_content "${file_content}#endif\n")
|
||||
endif()
|
||||
|
||||
endforeach()
|
||||
|
||||
if (_WCD_EPILOG)
|
||||
set(file_content "${file_content}\n${_WCD_EPILOG}\n")
|
||||
endif()
|
||||
set(file_content "${file_content}\n#endif")
|
||||
|
||||
set(CMAKE_CONFIGURABLE_FILE_CONTENT ${file_content})
|
||||
configure_file("${CMAKE_ROOT}/Modules/CMakeConfigurableFile.in"
|
||||
"${file_arg}"
|
||||
@ONLY
|
||||
)
|
||||
endfunction()
|
|
@ -411,6 +411,8 @@ if(BUILD_TESTING)
|
|||
ADD_TEST_MACRO(Module.GenerateExportHeader GenerateExportHeader)
|
||||
ADD_TEST_MACRO(Module.FindDependency FindDependency)
|
||||
|
||||
ADD_TEST_MACRO(Module.WriteCompilerDetectionHeader WriteCompilerDetectionHeader)
|
||||
|
||||
if (APPLE OR CMAKE_CXX_COMPILER_ID MATCHES "GNU")
|
||||
include(CheckCXXCompilerFlag)
|
||||
check_cxx_compiler_flag(-fPIE run_pic_test)
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
cmake_minimum_required(VERSION 3.0.0)
|
||||
project(WriteCompilerDetectionHeader)
|
||||
|
||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||
|
||||
include(WriteCompilerDetectionHeader)
|
||||
|
||||
get_property(cxx_known_features GLOBAL PROPERTY CMAKE_CXX_KNOWN_FEATURES)
|
||||
|
||||
write_compiler_detection_header(
|
||||
FILE "${CMAKE_CURRENT_BINARY_DIR}/test_compiler_detection.h"
|
||||
PREFIX TEST
|
||||
COMPILERS GNU
|
||||
VERSION 3.1
|
||||
PROLOG "// something"
|
||||
EPILOG "// more"
|
||||
FEATURES
|
||||
${cxx_known_features}
|
||||
)
|
||||
|
||||
if (NOT CMAKE_CXX_COMPILE_FEATURES)
|
||||
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/dummy.cpp"
|
||||
"int main(int,char**) { return 0; }\n"
|
||||
)
|
||||
add_executable(WriteCompilerDetectionHeader "${CMAKE_CURRENT_BINARY_DIR}/dummy.cpp")
|
||||
|
||||
include(CheckCXXSourceCompiles)
|
||||
check_cxx_source_compiles("#include \"${CMAKE_CURRENT_BINARY_DIR}/test_compiler_detection.h\"\nint main() { return 0; }\n"
|
||||
file_include_works
|
||||
)
|
||||
if (file_include_works)
|
||||
message(SEND_ERROR "Inclusion of ${CMAKE_CURRENT_BINARY_DIR}/test_compiler_detection.h was expected to cause an error, but did not.")
|
||||
endif()
|
||||
return()
|
||||
endif()
|
||||
|
||||
macro(set_defines target true_defs false_defs)
|
||||
set(defines)
|
||||
foreach(def ${true_defs})
|
||||
list(APPEND defines ${def}=1)
|
||||
endforeach()
|
||||
foreach(def ${false_defs})
|
||||
list(APPEND defines ${def}=0)
|
||||
endforeach()
|
||||
target_compile_definitions(${target}
|
||||
PRIVATE
|
||||
${defines}
|
||||
)
|
||||
endmacro()
|
||||
|
||||
if (CMAKE_CXX_COMPILER_ID STREQUAL GNU)
|
||||
# False for C++98 mode.
|
||||
list(APPEND false_defs EXPECTED_COMPILER_CXX_DELEGATING_CONSTRUCTORS)
|
||||
list(APPEND false_defs EXPECTED_COMPILER_CXX_VARIADIC_TEMPLATES)
|
||||
endif()
|
||||
|
||||
add_executable(WriteCompilerDetectionHeader main.cpp)
|
||||
set_property(TARGET WriteCompilerDetectionHeader PROPERTY CXX_STANDARD 98)
|
||||
set_defines(WriteCompilerDetectionHeader "${true_defs}" "${false_defs}")
|
||||
|
||||
if(MSVC)
|
||||
return() # MSVC has only one mode.
|
||||
endif()
|
||||
|
||||
# Since GNU 4.7
|
||||
if (";${CMAKE_CXX_COMPILE_FEATURES};" MATCHES ";cxx_delegating_constructors;")
|
||||
list(APPEND true_defs EXPECTED_COMPILER_CXX_DELEGATING_CONSTRUCTORS)
|
||||
list(REMOVE_ITEM false_defs EXPECTED_COMPILER_CXX_DELEGATING_CONSTRUCTORS)
|
||||
endif()
|
||||
|
||||
# Since GNU 4.4
|
||||
if (";${CMAKE_CXX_COMPILE_FEATURES};" MATCHES ";cxx_variadic_templates;")
|
||||
list(APPEND true_defs EXPECTED_COMPILER_CXX_VARIADIC_TEMPLATES)
|
||||
list(REMOVE_ITEM false_defs EXPECTED_COMPILER_CXX_VARIADIC_TEMPLATES)
|
||||
endif()
|
||||
|
||||
add_executable(WriteCompilerDetectionHeader_11 main.cpp)
|
||||
set_property(TARGET WriteCompilerDetectionHeader_11 PROPERTY CXX_STANDARD 11)
|
||||
set_defines(WriteCompilerDetectionHeader_11 "${true_defs}" "${false_defs}")
|
|
@ -0,0 +1,19 @@
|
|||
|
||||
#include "test_compiler_detection.h"
|
||||
|
||||
#define JOIN_IMPL(A, B) A ## B
|
||||
#define JOIN(A, B) JOIN_IMPL(A, B)
|
||||
#define CHECK(FEATURE) (JOIN(TEST_COMPILER_, FEATURE) == JOIN(EXPECTED_COMPILER_, FEATURE))
|
||||
|
||||
#if !CHECK(CXX_DELEGATING_CONSTRUCTORS)
|
||||
#error cxx_delegating_constructors expected availability did not match.
|
||||
#endif
|
||||
|
||||
#if !CHECK(CXX_VARIADIC_TEMPLATES)
|
||||
#error cxx_variadic_templates expected availability did not match.
|
||||
#endif
|
||||
|
||||
int main()
|
||||
{
|
||||
return 0;
|
||||
}
|
|
@ -54,6 +54,7 @@ add_RunCMake_test(TargetObjects)
|
|||
add_RunCMake_test(TargetSources)
|
||||
add_RunCMake_test(find_dependency)
|
||||
add_RunCMake_test(CompileFeatures)
|
||||
add_RunCMake_test(WriteCompilerDetectionHeader)
|
||||
if(NOT WIN32)
|
||||
add_RunCMake_test(PositionIndependentCode)
|
||||
set(SKIP_VISIBILITY 0)
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
cmake_minimum_required(VERSION 3.0)
|
||||
project(${RunCMake_TEST} CXX)
|
||||
include(${RunCMake_TEST}.cmake NO_POLICY_SCOPE)
|
|
@ -0,0 +1 @@
|
|||
1
|
|
@ -0,0 +1,5 @@
|
|||
CMake Error at .*Modules/WriteCompilerDetectionHeader.cmake:[0-9]+ \(message\):
|
||||
Unparsed arguments: GarbageArg
|
||||
Call Stack \(most recent call first\):
|
||||
ExtraArgs.cmake:4 \(write_compiler_detection_header\)
|
||||
CMakeLists.txt:3 \(include\)
|
|
@ -0,0 +1,10 @@
|
|||
|
||||
include(WriteCompilerDetectionHeader)
|
||||
|
||||
write_compiler_detection_header(
|
||||
FILE "${CMAKE_CURRENT_BINARY_DIR}/somefile"
|
||||
PREFIX Pref
|
||||
GarbageArg
|
||||
COMPILERS GNU
|
||||
FEATURES cxx_final
|
||||
)
|
|
@ -0,0 +1 @@
|
|||
1
|
|
@ -0,0 +1,5 @@
|
|||
CMake Error at .*Modules/WriteCompilerDetectionHeader.cmake:[0-9]+ \(message\):
|
||||
write_compiler_detection_header: FILE parameter missing.
|
||||
Call Stack \(most recent call first\):
|
||||
FileTypo.cmake:4 \(write_compiler_detection_header\)
|
||||
CMakeLists.txt:3 \(include\)
|
|
@ -0,0 +1,7 @@
|
|||
|
||||
include(WriteCompilerDetectionHeader)
|
||||
|
||||
write_compiler_detection_header(
|
||||
FILE_TYPO "${CMAKE_CURRENT_BINARY_DIR}/somefile"
|
||||
PREFIX Pref
|
||||
)
|
|
@ -0,0 +1 @@
|
|||
1
|
|
@ -0,0 +1,11 @@
|
|||
CMake Error at InvalidArgs.cmake:4 \(write_compiler_detection_header\):
|
||||
write_compiler_detection_header Function invoked with incorrect arguments
|
||||
for function named: write_compiler_detection_header
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists.txt:3 \(include\)
|
||||
+
|
||||
CMake Error at InvalidArgs.cmake:6 \(write_compiler_detection_header\):
|
||||
write_compiler_detection_header Function invoked with incorrect arguments
|
||||
for function named: write_compiler_detection_header
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists.txt:3 \(include\)
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
include(WriteCompilerDetectionHeader)
|
||||
|
||||
write_compiler_detection_header()
|
||||
|
||||
write_compiler_detection_header(FILE)
|
|
@ -0,0 +1 @@
|
|||
1
|
|
@ -0,0 +1,5 @@
|
|||
CMake Error at .*Modules/WriteCompilerDetectionHeader.cmake:[0-9]+ \(message\):
|
||||
Unsupported feature cxx_not_a_feature.
|
||||
Call Stack \(most recent call first\):
|
||||
InvalidCXXFeature.cmake:4 \(write_compiler_detection_header\)
|
||||
CMakeLists.txt:3 \(include\)
|
|
@ -0,0 +1,10 @@
|
|||
|
||||
include(WriteCompilerDetectionHeader)
|
||||
|
||||
write_compiler_detection_header(
|
||||
FILE "${CMAKE_CURRENT_BINARY_DIR}/somefile"
|
||||
PREFIX PREF_
|
||||
COMPILERS GNU
|
||||
FEATURES cxx_not_a_feature
|
||||
VERSION 3.1
|
||||
)
|
|
@ -0,0 +1 @@
|
|||
1
|
|
@ -0,0 +1,5 @@
|
|||
CMake Error at .*Modules/WriteCompilerDetectionHeader.cmake:[0-9]+ \(message\):
|
||||
Unsupported compiler NOT_A_COMPILER.
|
||||
Call Stack \(most recent call first\):
|
||||
InvalidCompiler.cmake:4 \(write_compiler_detection_header\)
|
||||
CMakeLists.txt:3 \(include\)
|
|
@ -0,0 +1,10 @@
|
|||
|
||||
include(WriteCompilerDetectionHeader)
|
||||
|
||||
write_compiler_detection_header(
|
||||
FILE "${CMAKE_CURRENT_BINARY_DIR}/somefile"
|
||||
PREFIX PREF_
|
||||
COMPILERS NOT_A_COMPILER
|
||||
FEATURES cxx_final
|
||||
VERSION 3.1
|
||||
)
|
|
@ -0,0 +1 @@
|
|||
1
|
|
@ -0,0 +1,5 @@
|
|||
CMake Error at .*Modules/WriteCompilerDetectionHeader.cmake:[0-9]+ \(message\):
|
||||
Unsupported feature not_a_feature.
|
||||
Call Stack \(most recent call first\):
|
||||
InvalidFeature.cmake:4 \(write_compiler_detection_header\)
|
||||
CMakeLists.txt:3 \(include\)
|
|
@ -0,0 +1,10 @@
|
|||
|
||||
include(WriteCompilerDetectionHeader)
|
||||
|
||||
write_compiler_detection_header(
|
||||
FILE "${CMAKE_CURRENT_BINARY_DIR}/somefile"
|
||||
PREFIX PREF_
|
||||
COMPILERS GNU
|
||||
FEATURES not_a_feature
|
||||
VERSION 3.1
|
||||
)
|
|
@ -0,0 +1 @@
|
|||
1
|
|
@ -0,0 +1,6 @@
|
|||
CMake Error at .*Modules/WriteCompilerDetectionHeader.cmake:[0-9]+ \(message\):
|
||||
Invalid arguments. write_compiler_detection_header requires at least one
|
||||
compiler.
|
||||
Call Stack \(most recent call first\):
|
||||
NoCompiler.cmake:4 \(write_compiler_detection_header\)
|
||||
CMakeLists.txt:3 \(include\)
|
|
@ -0,0 +1,10 @@
|
|||
|
||||
include(WriteCompilerDetectionHeader)
|
||||
|
||||
write_compiler_detection_header(
|
||||
FILE "${CMAKE_CURRENT_BINARY_DIR}/somefile"
|
||||
PREFIX PREF_
|
||||
# COMPILERS
|
||||
FEATURES cxx_final
|
||||
VERSION 3.1
|
||||
)
|
|
@ -0,0 +1 @@
|
|||
1
|
|
@ -0,0 +1,6 @@
|
|||
CMake Error at .*Modules/WriteCompilerDetectionHeader.cmake:[0-9]+ \(message\):
|
||||
Invalid arguments. write_compiler_detection_header requires at least one
|
||||
feature.
|
||||
Call Stack \(most recent call first\):
|
||||
NoFeature.cmake:4 \(write_compiler_detection_header\)
|
||||
CMakeLists.txt:3 \(include\)
|
|
@ -0,0 +1,10 @@
|
|||
|
||||
include(WriteCompilerDetectionHeader)
|
||||
|
||||
write_compiler_detection_header(
|
||||
FILE "${CMAKE_CURRENT_BINARY_DIR}/somefile"
|
||||
PREFIX PREF_
|
||||
COMPILERS GNU
|
||||
# FEATURES
|
||||
VERSION 3.1
|
||||
)
|
|
@ -0,0 +1 @@
|
|||
1
|
|
@ -0,0 +1,5 @@
|
|||
CMake Error at .*Modules/WriteCompilerDetectionHeader.cmake:[0-9]+ \(message\):
|
||||
VERSION parameter too low.
|
||||
Call Stack \(most recent call first\):
|
||||
OldVersion.cmake:4 \(write_compiler_detection_header\)
|
||||
CMakeLists.txt:3 \(include\)
|
|
@ -0,0 +1,10 @@
|
|||
|
||||
include(WriteCompilerDetectionHeader)
|
||||
|
||||
write_compiler_detection_header(
|
||||
FILE "${CMAKE_CURRENT_BINARY_DIR}/somefile"
|
||||
PREFIX Pref
|
||||
VERSION 3.0
|
||||
COMPILERS GNU
|
||||
FEATURES cxx_final
|
||||
)
|
|
@ -0,0 +1 @@
|
|||
1
|
|
@ -0,0 +1,5 @@
|
|||
CMake Error at .*Modules/WriteCompilerDetectionHeader.cmake:[0-9]+ \(message\):
|
||||
write_compiler_detection_header: PREFIX parameter missing.
|
||||
Call Stack \(most recent call first\):
|
||||
PrefixTypo.cmake:4 \(write_compiler_detection_header\)
|
||||
CMakeLists.txt:3 \(include\)
|
|
@ -0,0 +1,7 @@
|
|||
|
||||
include(WriteCompilerDetectionHeader)
|
||||
|
||||
write_compiler_detection_header(
|
||||
FILE "${CMAKE_CURRENT_BINARY_DIR}/somefile"
|
||||
PREFIX_TYPO Pref
|
||||
)
|
|
@ -0,0 +1,12 @@
|
|||
include(RunCMake)
|
||||
|
||||
run_cmake(InvalidArgs)
|
||||
run_cmake(NoCompiler)
|
||||
run_cmake(NoFeature)
|
||||
run_cmake(FileTypo)
|
||||
run_cmake(PrefixTypo)
|
||||
run_cmake(ExtraArgs)
|
||||
run_cmake(OldVersion)
|
||||
run_cmake(InvalidCompiler)
|
||||
run_cmake(InvalidFeature)
|
||||
run_cmake(InvalidCXXFeature)
|
Loading…
Reference in New Issue