Features: Extend concept to C language.
Add properties and variables corresponding to CXX equivalents. Add features for c_function_prototypes (C90), c_restrict (C99), c_variadic_macros (C99) and c_static_assert (C11). This feature set can be extended later. Add a <PREFIX>_RESTRICT symbol define to WriteCompilerDetectionHeader to conditionally represent the c_restrict feature.
This commit is contained in:
parent
775458dede
commit
e0890d03a4
|
@ -8,7 +8,8 @@ Add expected compiler features to a target.
|
||||||
target_compile_features(<target> <PRIVATE|PUBLIC|INTERFACE> <feature> [...])
|
target_compile_features(<target> <PRIVATE|PUBLIC|INTERFACE> <feature> [...])
|
||||||
|
|
||||||
Specify compiler features required when compiling a given target. If the
|
Specify compiler features required when compiling a given target. If the
|
||||||
feature is not listed in the :variable:`CMAKE_CXX_COMPILE_FEATURES` variable,
|
feature is not listed in the :variable:`CMAKE_C_COMPILE_FEATURES` variable
|
||||||
|
or :variable:`CMAKE_CXX_COMPILE_FEATURES` variable,
|
||||||
then an error will be reported by CMake. If the use of the feature requires
|
then an error will be reported by CMake. If the use of the feature requires
|
||||||
an additional compiler flag, such as ``-std=c++11``, the flag will be added
|
an additional compiler flag, such as ``-std=c++11``, the flag will be added
|
||||||
automatically.
|
automatically.
|
||||||
|
|
|
@ -16,6 +16,7 @@ Properties of Global Scope
|
||||||
/prop_gbl/ALLOW_DUPLICATE_CUSTOM_TARGETS
|
/prop_gbl/ALLOW_DUPLICATE_CUSTOM_TARGETS
|
||||||
/prop_gbl/AUTOGEN_TARGETS_FOLDER
|
/prop_gbl/AUTOGEN_TARGETS_FOLDER
|
||||||
/prop_gbl/AUTOMOC_TARGETS_FOLDER
|
/prop_gbl/AUTOMOC_TARGETS_FOLDER
|
||||||
|
/prop_gbl/CMAKE_C_KNOWN_FEATURES
|
||||||
/prop_gbl/CMAKE_CXX_KNOWN_FEATURES
|
/prop_gbl/CMAKE_CXX_KNOWN_FEATURES
|
||||||
/prop_gbl/DEBUG_CONFIGURATIONS
|
/prop_gbl/DEBUG_CONFIGURATIONS
|
||||||
/prop_gbl/DISABLED_FEATURES
|
/prop_gbl/DISABLED_FEATURES
|
||||||
|
@ -93,6 +94,9 @@ Properties on Targets
|
||||||
/prop_tgt/BUILD_WITH_INSTALL_RPATH
|
/prop_tgt/BUILD_WITH_INSTALL_RPATH
|
||||||
/prop_tgt/BUNDLE_EXTENSION
|
/prop_tgt/BUNDLE_EXTENSION
|
||||||
/prop_tgt/BUNDLE
|
/prop_tgt/BUNDLE
|
||||||
|
/prop_tgt/C_EXTENSIONS
|
||||||
|
/prop_tgt/C_STANDARD
|
||||||
|
/prop_tgt/C_STANDARD_REQUIRED
|
||||||
/prop_tgt/COMPATIBLE_INTERFACE_BOOL
|
/prop_tgt/COMPATIBLE_INTERFACE_BOOL
|
||||||
/prop_tgt/COMPATIBLE_INTERFACE_NUMBER_MAX
|
/prop_tgt/COMPATIBLE_INTERFACE_NUMBER_MAX
|
||||||
/prop_tgt/COMPATIBLE_INTERFACE_NUMBER_MIN
|
/prop_tgt/COMPATIBLE_INTERFACE_NUMBER_MIN
|
||||||
|
|
|
@ -260,6 +260,10 @@ Variables for Languages
|
||||||
:maxdepth: 1
|
:maxdepth: 1
|
||||||
|
|
||||||
/variable/CMAKE_COMPILER_IS_GNULANG
|
/variable/CMAKE_COMPILER_IS_GNULANG
|
||||||
|
/variable/CMAKE_C_COMPILE_FEATURES
|
||||||
|
/variable/CMAKE_C_EXTENSIONS
|
||||||
|
/variable/CMAKE_C_STANDARD
|
||||||
|
/variable/CMAKE_C_STANDARD_REQUIRED
|
||||||
/variable/CMAKE_CXX_COMPILE_FEATURES
|
/variable/CMAKE_CXX_COMPILE_FEATURES
|
||||||
/variable/CMAKE_CXX_EXTENSIONS
|
/variable/CMAKE_CXX_EXTENSIONS
|
||||||
/variable/CMAKE_CXX_STANDARD
|
/variable/CMAKE_CXX_STANDARD
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
CMAKE_C_KNOWN_FEATURES
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
List of C features known to this version of CMake.
|
||||||
|
|
||||||
|
The features listed in this global property may be known to be available to the
|
||||||
|
C compiler. If the feature is available with the C compiler, it will
|
||||||
|
be listed in the :variable:`CMAKE_C_COMPILE_FEATURES` variable.
|
||||||
|
|
||||||
|
The features listed here may be used with the :command:`target_compile_features`
|
||||||
|
command.
|
||||||
|
|
||||||
|
The features known to this version of CMake are:
|
||||||
|
|
||||||
|
``c_function_prototypes``
|
||||||
|
Function prototypes, as defined in ``ISO/IEC 9899:1990``.
|
||||||
|
|
||||||
|
``c_restrict``
|
||||||
|
``restrict`` keyword, as defined in ``ISO/IEC 9899:1999``.
|
||||||
|
|
||||||
|
``c_static_assert``
|
||||||
|
Static assert, as defined in ``ISO/IEC 9899:2011``.
|
||||||
|
|
||||||
|
``c_variadic_macros``
|
||||||
|
Variadic macros, as defined in ``ISO/IEC 9899:1999``.
|
|
@ -0,0 +1,8 @@
|
||||||
|
C_EXTENSIONS
|
||||||
|
------------
|
||||||
|
|
||||||
|
Boolean specifying whether compiler specific extensions are requested.
|
||||||
|
|
||||||
|
This property specifies whether compiler specific extensions should be
|
||||||
|
used. For some compilers, this results in adding a flag such
|
||||||
|
as ``-std=gnu11`` instead of ``-std=c11`` to the compile line.
|
|
@ -0,0 +1,27 @@
|
||||||
|
C_STANDARD
|
||||||
|
----------
|
||||||
|
|
||||||
|
The C standard whose features are requested to build this target.
|
||||||
|
|
||||||
|
This property specifies the C standard whose features are requested
|
||||||
|
to build this target. For some compilers, this results in adding a
|
||||||
|
flag such as ``-std=c11`` to the compile line.
|
||||||
|
|
||||||
|
Supported values are ``90``, ``99`` and ``11``.
|
||||||
|
|
||||||
|
If the value requested does not result in a compile flag being added for
|
||||||
|
the compiler in use, a previous standard flag will be added instead. This
|
||||||
|
means that using:
|
||||||
|
|
||||||
|
.. code-block:: cmake
|
||||||
|
|
||||||
|
set_property(TARGET tgt PROPERTY C_STANDARD 11)
|
||||||
|
|
||||||
|
with a compiler which does not support ``-std=c11`` or an equivalent
|
||||||
|
flag will not result in an error or warning, but will instead add the
|
||||||
|
``-std=c99`` or ``-std=c90`` flag if supported. This "decay" behavior may
|
||||||
|
be controlled with the :prop_tgt:`C_STANDARD_REQUIRED` target property.
|
||||||
|
|
||||||
|
This property is initialized by the value of
|
||||||
|
the :variable:`CMAKE_C_STANDARD` variable if it is set when a target
|
||||||
|
is created.
|
|
@ -0,0 +1,14 @@
|
||||||
|
C_STANDARD_REQUIRED
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
Boolean describing whether the value of :prop_tgt:`C_STANDARD` is a requirement.
|
||||||
|
|
||||||
|
If this property is set to ``ON``, then the value of the
|
||||||
|
:prop_tgt:`C_STANDARD` target property is treated as a requirement. If this
|
||||||
|
property is ``OFF`` or unset, the :prop_tgt:`C_STANDARD` target property is
|
||||||
|
treated as optional and may "decay" to a previous standard if the requested is
|
||||||
|
not available.
|
||||||
|
|
||||||
|
This property is initialized by the value of
|
||||||
|
the :variable:`CMAKE_C_STANDARD_REQUIRED` variable if it is set when a
|
||||||
|
target is created.
|
|
@ -7,6 +7,12 @@ target-language-features
|
||||||
:variable:`CMAKE_CXX_STANDARD` and :variable:`CMAKE_CXX_EXTENSIONS`
|
:variable:`CMAKE_CXX_STANDARD` and :variable:`CMAKE_CXX_EXTENSIONS`
|
||||||
variables may be set to initialize the target properties.
|
variables may be set to initialize the target properties.
|
||||||
|
|
||||||
|
* New :prop_tgt:`C_STANDARD` and :prop_tgt:`C_EXTENSIONS` target
|
||||||
|
properties may specify values which CMake uses to compute required
|
||||||
|
compile options such as ``-std=c11`` or ``-std=gnu11``. The
|
||||||
|
:variable:`CMAKE_C_STANDARD` and :variable:`CMAKE_C_EXTENSIONS`
|
||||||
|
variables may be set to initialize the target properties.
|
||||||
|
|
||||||
* New :prop_tgt:`COMPILE_FEATURES` target property may contain a list
|
* New :prop_tgt:`COMPILE_FEATURES` target property may contain a list
|
||||||
of features required to compile a target. CMake uses this
|
of features required to compile a target. CMake uses this
|
||||||
information to ensure that the compiler in use is capable of building
|
information to ensure that the compiler in use is capable of building
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
CMAKE_C_COMPILE_FEATURES
|
||||||
|
------------------------
|
||||||
|
|
||||||
|
List of features known to the C compiler
|
||||||
|
|
||||||
|
These features are known to be available for use with the C compiler. This
|
||||||
|
list is a subset of the features listed in the :prop_gbl:`CMAKE_C_KNOWN_FEATURES`
|
||||||
|
global property.
|
|
@ -0,0 +1,8 @@
|
||||||
|
CMAKE_C_EXTENSIONS
|
||||||
|
------------------
|
||||||
|
|
||||||
|
Default value for ``C_EXTENSIONS`` property of targets.
|
||||||
|
|
||||||
|
This variable is used to initialize the :prop_tgt:`C_EXTENSIONS`
|
||||||
|
property on all targets. See that target property for additional
|
||||||
|
information.
|
|
@ -0,0 +1,8 @@
|
||||||
|
CMAKE_C_STANDARD
|
||||||
|
----------------
|
||||||
|
|
||||||
|
Default value for ``C_STANDARD`` property of targets.
|
||||||
|
|
||||||
|
This variable is used to initialize the :prop_tgt:`C_STANDARD`
|
||||||
|
property on all targets. See that target property for additional
|
||||||
|
information.
|
|
@ -0,0 +1,8 @@
|
||||||
|
CMAKE_C_STANDARD_REQUIRED
|
||||||
|
-------------------------
|
||||||
|
|
||||||
|
Default value for ``C_STANDARD_REQUIRED`` property of targets.
|
||||||
|
|
||||||
|
This variable is used to initialize the :prop_tgt:`C_STANDARD_REQUIRED`
|
||||||
|
property on all targets. See that target property for additional
|
||||||
|
information.
|
|
@ -2,6 +2,11 @@ set(CMAKE_C_COMPILER "@CMAKE_C_COMPILER@")
|
||||||
set(CMAKE_C_COMPILER_ARG1 "@CMAKE_C_COMPILER_ARG1@")
|
set(CMAKE_C_COMPILER_ARG1 "@CMAKE_C_COMPILER_ARG1@")
|
||||||
set(CMAKE_C_COMPILER_ID "@CMAKE_C_COMPILER_ID@")
|
set(CMAKE_C_COMPILER_ID "@CMAKE_C_COMPILER_ID@")
|
||||||
set(CMAKE_C_COMPILER_VERSION "@CMAKE_C_COMPILER_VERSION@")
|
set(CMAKE_C_COMPILER_VERSION "@CMAKE_C_COMPILER_VERSION@")
|
||||||
|
set(CMAKE_C_COMPILE_FEATURES "@CMAKE_C_COMPILE_FEATURES@")
|
||||||
|
set(CMAKE_C90_COMPILE_FEATURES "@CMAKE_C90_COMPILE_FEATURES@")
|
||||||
|
set(CMAKE_C99_COMPILE_FEATURES "@CMAKE_C99_COMPILE_FEATURES@")
|
||||||
|
set(CMAKE_C11_COMPILE_FEATURES "@CMAKE_C11_COMPILE_FEATURES@")
|
||||||
|
|
||||||
set(CMAKE_C_PLATFORM_ID "@CMAKE_C_PLATFORM_ID@")
|
set(CMAKE_C_PLATFORM_ID "@CMAKE_C_PLATFORM_ID@")
|
||||||
set(CMAKE_C_SIMULATE_ID "@CMAKE_C_SIMULATE_ID@")
|
set(CMAKE_C_SIMULATE_ID "@CMAKE_C_SIMULATE_ID@")
|
||||||
set(CMAKE_C_SIMULATE_VERSION "@CMAKE_C_SIMULATE_VERSION@")
|
set(CMAKE_C_SIMULATE_VERSION "@CMAKE_C_SIMULATE_VERSION@")
|
||||||
|
|
|
@ -14,7 +14,45 @@
|
||||||
|
|
||||||
function(cmake_determine_compile_features lang)
|
function(cmake_determine_compile_features lang)
|
||||||
|
|
||||||
if(lang STREQUAL CXX AND COMMAND cmake_record_cxx_compile_features)
|
if(lang STREQUAL C AND COMMAND cmake_record_c_compile_features)
|
||||||
|
message(STATUS "Detecting ${lang} compile features")
|
||||||
|
|
||||||
|
set(CMAKE_C90_COMPILE_FEATURES)
|
||||||
|
set(CMAKE_C99_COMPILE_FEATURES)
|
||||||
|
set(CMAKE_C11_COMPILE_FEATURES)
|
||||||
|
|
||||||
|
include("${CMAKE_ROOT}/Modules/Internal/FeatureTesting.cmake")
|
||||||
|
|
||||||
|
cmake_record_c_compile_features()
|
||||||
|
|
||||||
|
if(NOT _result EQUAL 0)
|
||||||
|
message(STATUS "Detecting ${lang} compile features - failed")
|
||||||
|
return()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (CMAKE_C99_COMPILE_FEATURES AND CMAKE_C11_COMPILE_FEATURES)
|
||||||
|
list(REMOVE_ITEM CMAKE_C11_COMPILE_FEATURES ${CMAKE_C99_COMPILE_FEATURES})
|
||||||
|
endif()
|
||||||
|
if (CMAKE_C90_COMPILE_FEATURES AND CMAKE_C99_COMPILE_FEATURES)
|
||||||
|
list(REMOVE_ITEM CMAKE_C99_COMPILE_FEATURES ${CMAKE_C90_COMPILE_FEATURES})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(NOT CMAKE_C_COMPILE_FEATURES)
|
||||||
|
set(CMAKE_C_COMPILE_FEATURES
|
||||||
|
${CMAKE_C90_COMPILE_FEATURES}
|
||||||
|
${CMAKE_C99_COMPILE_FEATURES}
|
||||||
|
${CMAKE_C11_COMPILE_FEATURES}
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(CMAKE_C_COMPILE_FEATURES ${CMAKE_C_COMPILE_FEATURES} PARENT_SCOPE)
|
||||||
|
set(CMAKE_C90_COMPILE_FEATURES ${CMAKE_C90_COMPILE_FEATURES} PARENT_SCOPE)
|
||||||
|
set(CMAKE_C99_COMPILE_FEATURES ${CMAKE_C99_COMPILE_FEATURES} PARENT_SCOPE)
|
||||||
|
set(CMAKE_C11_COMPILE_FEATURES ${CMAKE_C11_COMPILE_FEATURES} PARENT_SCOPE)
|
||||||
|
|
||||||
|
message(STATUS "Detecting ${lang} compile features - done")
|
||||||
|
|
||||||
|
elseif(lang STREQUAL CXX AND COMMAND cmake_record_cxx_compile_features)
|
||||||
message(STATUS "Detecting ${lang} compile features")
|
message(STATUS "Detecting ${lang} compile features")
|
||||||
|
|
||||||
set(CMAKE_CXX98_COMPILE_FEATURES)
|
set(CMAKE_CXX98_COMPILE_FEATURES)
|
||||||
|
|
|
@ -73,6 +73,9 @@ else()
|
||||||
# Try to identify the ABI and configure it into CMakeCCompiler.cmake
|
# Try to identify the ABI and configure it into CMakeCCompiler.cmake
|
||||||
include(${CMAKE_ROOT}/Modules/CMakeDetermineCompilerABI.cmake)
|
include(${CMAKE_ROOT}/Modules/CMakeDetermineCompilerABI.cmake)
|
||||||
CMAKE_DETERMINE_COMPILER_ABI(C ${CMAKE_ROOT}/Modules/CMakeCCompilerABI.c)
|
CMAKE_DETERMINE_COMPILER_ABI(C ${CMAKE_ROOT}/Modules/CMakeCCompilerABI.c)
|
||||||
|
# Try to identify the compiler features
|
||||||
|
include(${CMAKE_ROOT}/Modules/CMakeDetermineCompileFeatures.cmake)
|
||||||
|
CMAKE_DETERMINE_COMPILE_FEATURES(C)
|
||||||
|
|
||||||
# Re-configure to save learned information.
|
# Re-configure to save learned information.
|
||||||
configure_file(
|
configure_file(
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
|
||||||
|
set(_cmake_oldestSupported "(__GNUC__ * 100 + __GNUC_MINOR__) >= 407")
|
||||||
|
|
||||||
|
set(GNU46_C11 "${_cmake_oldestSupported} && __STDC_VERSION__ >= 201112L")
|
||||||
|
set(_cmake_feature_test_c_static_assert "${GNU46_C11}")
|
||||||
|
# Since 4.4 at least:
|
||||||
|
set(GNU44_C99 "${_cmake_oldestSupported} && __STDC_VERSION__ >= 199901L")
|
||||||
|
set(_cmake_feature_test_c_restrict "${GNU44_C99}")
|
||||||
|
set(_cmake_feature_test_c_variadic_macros "${GNU44_C99}")
|
||||||
|
|
||||||
|
set(GNU_C90 "${_cmake_oldestSupported} && !defined(__STDC_VERSION__)")
|
||||||
|
set(_cmake_feature_test_c_function_prototypes "${GNU_C90}")
|
|
@ -1,2 +1,34 @@
|
||||||
include(Compiler/GNU)
|
include(Compiler/GNU)
|
||||||
__compiler_gnu(C)
|
__compiler_gnu(C)
|
||||||
|
|
||||||
|
if (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.7)
|
||||||
|
set(CMAKE_C90_STANDARD_COMPILE_OPTION "-std=c90")
|
||||||
|
set(CMAKE_C90_EXTENSION_COMPILE_OPTION "-std=gnu90")
|
||||||
|
|
||||||
|
set(CMAKE_C99_STANDARD_COMPILE_OPTION "-std=c99")
|
||||||
|
set(CMAKE_C99_EXTENSION_COMPILE_OPTION "-std=gnu99")
|
||||||
|
|
||||||
|
set(CMAKE_C11_STANDARD_COMPILE_OPTION "-std=c11")
|
||||||
|
set(CMAKE_C11_EXTENSION_COMPILE_OPTION "-std=gnu11")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# This may change in a future GNU version.
|
||||||
|
set(CMAKE_C_STANDARD_DEFAULT 90)
|
||||||
|
|
||||||
|
macro(cmake_record_c_compile_features)
|
||||||
|
macro(_get_gcc_features std_version list)
|
||||||
|
record_compiler_features(C "-std=${std_version}" ${list})
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
if (UNIX AND NOT APPLE AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.7)
|
||||||
|
_get_gcc_features(c90 CMAKE_C90_COMPILE_FEATURES)
|
||||||
|
if (_result EQUAL 0)
|
||||||
|
_get_gcc_features(c99 CMAKE_C99_COMPILE_FEATURES)
|
||||||
|
endif()
|
||||||
|
if (_result EQUAL 0)
|
||||||
|
_get_gcc_features(c11 CMAKE_C11_COMPILE_FEATURES)
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
|
set(_result 0)
|
||||||
|
endif()
|
||||||
|
endmacro()
|
||||||
|
|
|
@ -43,7 +43,8 @@
|
||||||
# Possible compiler identifiers are documented with the
|
# Possible compiler identifiers are documented with the
|
||||||
# :variable:`CMAKE_<LANG>_COMPILER_ID` variable.
|
# :variable:`CMAKE_<LANG>_COMPILER_ID` variable.
|
||||||
# Available features in this version of CMake are listed in the
|
# Available features in this version of CMake are listed in the
|
||||||
# :prop_gbl:`CMAKE_CXX_KNOWN_FEATURES` global property.
|
# :prop_gbl:`CMAKE_C_KNOWN_FEATURES` and
|
||||||
|
# :prop_gbl:`CMAKE_CXX_KNOWN_FEATURES` global properties.
|
||||||
#
|
#
|
||||||
# Feature Test Macros
|
# Feature Test Macros
|
||||||
# ===================
|
# ===================
|
||||||
|
@ -102,6 +103,7 @@
|
||||||
# ========================== =================================== =================
|
# ========================== =================================== =================
|
||||||
# Feature Define Symbol
|
# Feature Define Symbol
|
||||||
# ========================== =================================== =================
|
# ========================== =================================== =================
|
||||||
|
# ``c_restrict`` ``<PREFIX>_RESTRICT`` ``restrict``
|
||||||
# ``cxx_constexpr`` ``<PREFIX>_CONSTEXPR`` ``constexpr``
|
# ``cxx_constexpr`` ``<PREFIX>_CONSTEXPR`` ``constexpr``
|
||||||
# ``cxx_deleted_functions`` ``<PREFIX>_DELETED_FUNCTION`` ``= delete``
|
# ``cxx_deleted_functions`` ``<PREFIX>_DELETED_FUNCTION`` ``= delete``
|
||||||
# ``cxx_extern_templates`` ``<PREFIX>_EXTERN_TEMPLATE`` ``extern``
|
# ``cxx_extern_templates`` ``<PREFIX>_EXTERN_TEMPLATE`` ``extern``
|
||||||
|
@ -221,6 +223,9 @@ function(write_compiler_detection_header
|
||||||
if (feature MATCHES "^cxx_")
|
if (feature MATCHES "^cxx_")
|
||||||
list(APPEND _langs CXX)
|
list(APPEND _langs CXX)
|
||||||
list(APPEND CXX_features ${feature})
|
list(APPEND CXX_features ${feature})
|
||||||
|
elseif (feature MATCHES "^c_")
|
||||||
|
list(APPEND _langs C)
|
||||||
|
list(APPEND C_features ${feature})
|
||||||
else()
|
else()
|
||||||
message(FATAL_ERROR "Unsupported feature ${feature}.")
|
message(FATAL_ERROR "Unsupported feature ${feature}.")
|
||||||
endif()
|
endif()
|
||||||
|
@ -239,6 +244,8 @@ function(write_compiler_detection_header
|
||||||
|
|
||||||
if(_lang STREQUAL CXX)
|
if(_lang STREQUAL CXX)
|
||||||
set(file_content "${file_content}\n#ifdef __cplusplus\n")
|
set(file_content "${file_content}\n#ifdef __cplusplus\n")
|
||||||
|
else()
|
||||||
|
set(file_content "${file_content}\n#ifndef __cplusplus\n")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
compiler_id_detection(ID_CONTENT ${_lang} PREFIX ${prefix_arg}_
|
compiler_id_detection(ID_CONTENT ${_lang} PREFIX ${prefix_arg}_
|
||||||
|
@ -279,6 +286,16 @@ function(write_compiler_detection_header
|
||||||
string(TOUPPER ${feature} feature_upper)
|
string(TOUPPER ${feature} feature_upper)
|
||||||
set(feature_PP "COMPILER_${feature_upper}")
|
set(feature_PP "COMPILER_${feature_upper}")
|
||||||
set(def_name ${prefix_arg}_${feature_PP})
|
set(def_name ${prefix_arg}_${feature_PP})
|
||||||
|
if (feature STREQUAL c_restrict)
|
||||||
|
set(def_value "${prefix_arg}_RESTRICT")
|
||||||
|
set(file_content "${file_content}
|
||||||
|
# if ${def_name}
|
||||||
|
# define ${def_value} restrict
|
||||||
|
# else
|
||||||
|
# define ${def_value}
|
||||||
|
# endif
|
||||||
|
\n")
|
||||||
|
endif()
|
||||||
if (feature STREQUAL cxx_constexpr)
|
if (feature STREQUAL cxx_constexpr)
|
||||||
set(def_value "${prefix_arg}_DECL_${feature_upper}")
|
set(def_value "${prefix_arg}_DECL_${feature_upper}")
|
||||||
set(file_content "${file_content}
|
set(file_content "${file_content}
|
||||||
|
@ -382,9 +399,8 @@ function(write_compiler_detection_header
|
||||||
\n")
|
\n")
|
||||||
endif()
|
endif()
|
||||||
endforeach()
|
endforeach()
|
||||||
if(_lang STREQUAL CXX)
|
|
||||||
set(file_content "${file_content}#endif\n")
|
set(file_content "${file_content}#endif\n")
|
||||||
endif()
|
|
||||||
|
|
||||||
endforeach()
|
endforeach()
|
||||||
|
|
||||||
|
|
|
@ -2201,6 +2201,10 @@ AddCompilerRequirementFlag(std::string &flags, cmTarget* target,
|
||||||
// Maintain sorted order, most recent first.
|
// Maintain sorted order, most recent first.
|
||||||
langStdMap["CXX"].push_back("11");
|
langStdMap["CXX"].push_back("11");
|
||||||
langStdMap["CXX"].push_back("98");
|
langStdMap["CXX"].push_back("98");
|
||||||
|
|
||||||
|
langStdMap["C"].push_back("11");
|
||||||
|
langStdMap["C"].push_back("99");
|
||||||
|
langStdMap["C"].push_back("90");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string standard(standardProp);
|
std::string standard(standardProp);
|
||||||
|
|
|
@ -4973,6 +4973,10 @@ void cmMakefile::RecordPolicies(cmPolicies::PolicyMap& pm)
|
||||||
}
|
}
|
||||||
|
|
||||||
#define FEATURE_STRING(F) , #F
|
#define FEATURE_STRING(F) , #F
|
||||||
|
static const char * const C_FEATURES[] = {
|
||||||
|
0
|
||||||
|
FOR_EACH_C_FEATURE(FEATURE_STRING)
|
||||||
|
};
|
||||||
|
|
||||||
static const char * const CXX_FEATURES[] = {
|
static const char * const CXX_FEATURES[] = {
|
||||||
0
|
0
|
||||||
|
@ -4980,6 +4984,11 @@ static const char * const CXX_FEATURES[] = {
|
||||||
};
|
};
|
||||||
#undef FEATURE_STRING
|
#undef FEATURE_STRING
|
||||||
|
|
||||||
|
static const char * const C_STANDARDS[] = {
|
||||||
|
"90"
|
||||||
|
, "99"
|
||||||
|
, "11"
|
||||||
|
};
|
||||||
static const char * const CXX_STANDARDS[] = {
|
static const char * const CXX_STANDARDS[] = {
|
||||||
"98"
|
"98"
|
||||||
, "11"
|
, "11"
|
||||||
|
@ -4995,10 +5004,13 @@ AddRequiredTargetFeature(cmTarget *target, const std::string& feature,
|
||||||
target->AppendProperty("COMPILE_FEATURES", feature.c_str());
|
target->AppendProperty("COMPILE_FEATURES", feature.c_str());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
bool isCFeature = std::find_if(cmArrayBegin(C_FEATURES) + 1,
|
||||||
|
cmArrayEnd(C_FEATURES), cmStrCmp(feature))
|
||||||
|
!= cmArrayEnd(C_FEATURES);
|
||||||
bool isCxxFeature = std::find_if(cmArrayBegin(CXX_FEATURES) + 1,
|
bool isCxxFeature = std::find_if(cmArrayBegin(CXX_FEATURES) + 1,
|
||||||
cmArrayEnd(CXX_FEATURES), cmStrCmp(feature))
|
cmArrayEnd(CXX_FEATURES), cmStrCmp(feature))
|
||||||
!= cmArrayEnd(CXX_FEATURES);
|
!= cmArrayEnd(CXX_FEATURES);
|
||||||
if (!isCxxFeature)
|
if (!isCFeature && !isCxxFeature)
|
||||||
{
|
{
|
||||||
cmOStringStream e;
|
cmOStringStream e;
|
||||||
if (error)
|
if (error)
|
||||||
|
@ -5022,7 +5034,7 @@ AddRequiredTargetFeature(cmTarget *target, const std::string& feature,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string lang = "CXX";
|
std::string lang = isCFeature ? "C" : "CXX";
|
||||||
|
|
||||||
const char* featuresKnown =
|
const char* featuresKnown =
|
||||||
this->GetDefinition("CMAKE_" + lang + "_COMPILE_FEATURES");
|
this->GetDefinition("CMAKE_" + lang + "_COMPILE_FEATURES");
|
||||||
|
@ -5071,6 +5083,16 @@ AddRequiredTargetFeature(cmTarget *target, const std::string& feature,
|
||||||
|
|
||||||
target->AppendProperty("COMPILE_FEATURES", feature.c_str());
|
target->AppendProperty("COMPILE_FEATURES", feature.c_str());
|
||||||
|
|
||||||
|
return isCFeature
|
||||||
|
? this->AddRequiredTargetCFeature(target, feature)
|
||||||
|
: this->AddRequiredTargetCxxFeature(target, feature);
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool cmMakefile::
|
||||||
|
AddRequiredTargetCxxFeature(cmTarget *target,
|
||||||
|
const std::string& feature) const
|
||||||
|
{
|
||||||
bool needCxx98 = false;
|
bool needCxx98 = false;
|
||||||
bool needCxx11 = false;
|
bool needCxx11 = false;
|
||||||
|
|
||||||
|
@ -5136,3 +5158,93 @@ AddRequiredTargetFeature(cmTarget *target, const std::string& feature,
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool cmMakefile::
|
||||||
|
AddRequiredTargetCFeature(cmTarget *target, const std::string& feature) const
|
||||||
|
{
|
||||||
|
bool needC90 = false;
|
||||||
|
bool needC99 = false;
|
||||||
|
bool needC11 = false;
|
||||||
|
|
||||||
|
if (const char *propC90 =
|
||||||
|
this->GetDefinition("CMAKE_C90_COMPILE_FEATURES"))
|
||||||
|
{
|
||||||
|
std::vector<std::string> props;
|
||||||
|
cmSystemTools::ExpandListArgument(propC90, props);
|
||||||
|
needC90 = std::find(props.begin(), props.end(), feature) != props.end();
|
||||||
|
}
|
||||||
|
if (const char *propC99 =
|
||||||
|
this->GetDefinition("CMAKE_C99_COMPILE_FEATURES"))
|
||||||
|
{
|
||||||
|
std::vector<std::string> props;
|
||||||
|
cmSystemTools::ExpandListArgument(propC99, props);
|
||||||
|
needC99 = std::find(props.begin(), props.end(), feature) != props.end();
|
||||||
|
}
|
||||||
|
if (const char *propC11 =
|
||||||
|
this->GetDefinition("CMAKE_C11_COMPILE_FEATURES"))
|
||||||
|
{
|
||||||
|
std::vector<std::string> props;
|
||||||
|
cmSystemTools::ExpandListArgument(propC11, props);
|
||||||
|
needC11 = std::find(props.begin(), props.end(), feature) != props.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *existingCStandard = target->GetProperty("C_STANDARD");
|
||||||
|
if (existingCStandard)
|
||||||
|
{
|
||||||
|
if (std::find_if(cmArrayBegin(C_STANDARDS), cmArrayEnd(C_STANDARDS),
|
||||||
|
cmStrCmp(existingCStandard)) == cmArrayEnd(C_STANDARDS))
|
||||||
|
{
|
||||||
|
cmOStringStream e;
|
||||||
|
e << "The C_STANDARD property on target \"" << target->GetName()
|
||||||
|
<< "\" contained an invalid value: \"" << existingCStandard << "\".";
|
||||||
|
this->IssueMessage(cmake::FATAL_ERROR, e.str().c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const char * const *existingCIt = existingCStandard
|
||||||
|
? std::find_if(cmArrayBegin(C_STANDARDS),
|
||||||
|
cmArrayEnd(C_STANDARDS),
|
||||||
|
cmStrCmp(existingCStandard))
|
||||||
|
: cmArrayEnd(C_STANDARDS);
|
||||||
|
|
||||||
|
bool setC90 = needC90 && !existingCStandard;
|
||||||
|
bool setC99 = needC99 && !existingCStandard;
|
||||||
|
bool setC11 = needC11 && !existingCStandard;
|
||||||
|
|
||||||
|
if (needC11 && existingCStandard && existingCIt <
|
||||||
|
std::find_if(cmArrayBegin(C_STANDARDS),
|
||||||
|
cmArrayEnd(C_STANDARDS),
|
||||||
|
cmStrCmp("11")))
|
||||||
|
{
|
||||||
|
setC11 = true;
|
||||||
|
}
|
||||||
|
else if(needC99 && existingCStandard && existingCIt <
|
||||||
|
std::find_if(cmArrayBegin(C_STANDARDS),
|
||||||
|
cmArrayEnd(C_STANDARDS),
|
||||||
|
cmStrCmp("99")))
|
||||||
|
{
|
||||||
|
setC99 = true;
|
||||||
|
}
|
||||||
|
else if(needC90 && existingCStandard && existingCIt <
|
||||||
|
std::find_if(cmArrayBegin(C_STANDARDS),
|
||||||
|
cmArrayEnd(C_STANDARDS),
|
||||||
|
cmStrCmp("90")))
|
||||||
|
{
|
||||||
|
setC90 = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (setC11)
|
||||||
|
{
|
||||||
|
target->SetProperty("C_STANDARD", "11");
|
||||||
|
}
|
||||||
|
else if (setC99)
|
||||||
|
{
|
||||||
|
target->SetProperty("C_STANDARD", "99");
|
||||||
|
}
|
||||||
|
else if (setC90)
|
||||||
|
{
|
||||||
|
target->SetProperty("C_STANDARD", "90");
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
|
@ -1098,6 +1098,12 @@ private:
|
||||||
std::vector<cmSourceFile*> QtUiFilesWithOptions;
|
std::vector<cmSourceFile*> QtUiFilesWithOptions;
|
||||||
|
|
||||||
unsigned int NumLastMatches;
|
unsigned int NumLastMatches;
|
||||||
|
|
||||||
|
bool AddRequiredTargetCFeature(cmTarget *target,
|
||||||
|
const std::string& feature) const;
|
||||||
|
|
||||||
|
bool AddRequiredTargetCxxFeature(cmTarget *target,
|
||||||
|
const std::string& feature) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
|
|
@ -314,6 +314,9 @@ void cmTarget::SetMakefile(cmMakefile* mf)
|
||||||
this->SetPropertyDefault("MACOSX_BUNDLE", 0);
|
this->SetPropertyDefault("MACOSX_BUNDLE", 0);
|
||||||
this->SetPropertyDefault("MACOSX_RPATH", 0);
|
this->SetPropertyDefault("MACOSX_RPATH", 0);
|
||||||
this->SetPropertyDefault("NO_SYSTEM_FROM_IMPORTED", 0);
|
this->SetPropertyDefault("NO_SYSTEM_FROM_IMPORTED", 0);
|
||||||
|
this->SetPropertyDefault("C_STANDARD", 0);
|
||||||
|
this->SetPropertyDefault("C_STANDARD_REQUIRED", 0);
|
||||||
|
this->SetPropertyDefault("C_EXTENSIONS", 0);
|
||||||
this->SetPropertyDefault("CXX_STANDARD", 0);
|
this->SetPropertyDefault("CXX_STANDARD", 0);
|
||||||
this->SetPropertyDefault("CXX_STANDARD_REQUIRED", 0);
|
this->SetPropertyDefault("CXX_STANDARD_REQUIRED", 0);
|
||||||
this->SetPropertyDefault("CXX_EXTENSIONS", 0);
|
this->SetPropertyDefault("CXX_EXTENSIONS", 0);
|
||||||
|
|
|
@ -2273,12 +2273,16 @@ const char *cmake::GetProperty(const std::string& prop,
|
||||||
}
|
}
|
||||||
this->SetProperty("ENABLED_LANGUAGES", lang.c_str());
|
this->SetProperty("ENABLED_LANGUAGES", lang.c_str());
|
||||||
}
|
}
|
||||||
|
#define STRING_LIST_ELEMENT(F) ";" #F
|
||||||
|
if (prop == "CMAKE_C_KNOWN_FEATURES")
|
||||||
|
{
|
||||||
|
return FOR_EACH_C_FEATURE(STRING_LIST_ELEMENT) + 1;
|
||||||
|
}
|
||||||
if (prop == "CMAKE_CXX_KNOWN_FEATURES")
|
if (prop == "CMAKE_CXX_KNOWN_FEATURES")
|
||||||
{
|
{
|
||||||
#define STRING_LIST_ELEMENT(F) ";" #F
|
|
||||||
return FOR_EACH_CXX_FEATURE(STRING_LIST_ELEMENT) + 1;
|
return FOR_EACH_CXX_FEATURE(STRING_LIST_ELEMENT) + 1;
|
||||||
#undef STRING_LIST_ELEMENT
|
|
||||||
}
|
}
|
||||||
|
#undef STRING_LIST_ELEMENT
|
||||||
return this->Properties.GetPropertyValue(prop, scope, chain);
|
return this->Properties.GetPropertyValue(prop, scope, chain);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -458,6 +458,12 @@ private:
|
||||||
{"-Wno-dev", "Suppress developer warnings."},\
|
{"-Wno-dev", "Suppress developer warnings."},\
|
||||||
{"-Wdev", "Enable developer warnings."}
|
{"-Wdev", "Enable developer warnings."}
|
||||||
|
|
||||||
|
#define FOR_EACH_C_FEATURE(F) \
|
||||||
|
F(c_function_prototypes) \
|
||||||
|
F(c_restrict) \
|
||||||
|
F(c_static_assert) \
|
||||||
|
F(c_variadic_macros)
|
||||||
|
|
||||||
#define FOR_EACH_CXX_FEATURE(F) \
|
#define FOR_EACH_CXX_FEATURE(F) \
|
||||||
F(cxx_alias_templates) \
|
F(cxx_alias_templates) \
|
||||||
F(cxx_alignas) \
|
F(cxx_alignas) \
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
cmake_minimum_required(VERSION 3.0)
|
cmake_minimum_required(VERSION 3.0)
|
||||||
project(target_compile_features)
|
project(target_compile_features)
|
||||||
|
|
||||||
if (NOT CMAKE_CXX_COMPILE_FEATURES)
|
if (NOT CMAKE_CXX_COMPILE_FEATURES AND NOT CMAKE_C_COMPILE_FEATURES)
|
||||||
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/test_dummy.cpp"
|
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/test_dummy.cpp"
|
||||||
"int main(int,char**) { return 0; }\n"
|
"int main(int,char**) { return 0; }\n"
|
||||||
)
|
)
|
||||||
|
@ -11,15 +11,35 @@ endif()
|
||||||
|
|
||||||
set(CMAKE_VERBOSE_MAKEFILE ON)
|
set(CMAKE_VERBOSE_MAKEFILE ON)
|
||||||
|
|
||||||
add_executable(target_compile_features main.cpp)
|
if (CMAKE_C_COMPILE_FEATURES)
|
||||||
target_compile_features(target_compile_features
|
add_executable(target_compile_features main.c)
|
||||||
|
target_compile_features(target_compile_features
|
||||||
|
PRIVATE c_restrict
|
||||||
|
)
|
||||||
|
|
||||||
|
add_library(lib_restrict lib_restrict.c)
|
||||||
|
target_compile_features(lib_restrict
|
||||||
|
PUBLIC c_restrict
|
||||||
|
)
|
||||||
|
|
||||||
|
add_executable(restrict_user restrict_user.c)
|
||||||
|
target_link_libraries(restrict_user lib_restrict)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (CMAKE_CXX_COMPILE_FEATURES)
|
||||||
|
if (CMAKE_C_COMPILE_FEATURES)
|
||||||
|
set(target_suffix _cxx)
|
||||||
|
endif()
|
||||||
|
add_executable(target_compile_features${target_suffix} main.cpp)
|
||||||
|
target_compile_features(target_compile_features${target_suffix}
|
||||||
PRIVATE cxx_auto_type
|
PRIVATE cxx_auto_type
|
||||||
)
|
)
|
||||||
|
|
||||||
add_library(lib_auto_type lib_auto_type.cpp)
|
add_library(lib_auto_type lib_auto_type.cpp)
|
||||||
target_compile_features(lib_auto_type
|
target_compile_features(lib_auto_type
|
||||||
PUBLIC cxx_auto_type
|
PUBLIC cxx_auto_type
|
||||||
)
|
)
|
||||||
|
|
||||||
add_executable(lib_user lib_user.cpp)
|
add_executable(lib_user lib_user.cpp)
|
||||||
target_link_libraries(lib_user lib_auto_type)
|
target_link_libraries(lib_user lib_auto_type)
|
||||||
|
endif()
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
|
||||||
|
#include "lib_restrict.h"
|
||||||
|
|
||||||
|
int foo(int * restrict a, int * restrict b)
|
||||||
|
{
|
||||||
|
(void)a;
|
||||||
|
(void)b;
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
|
||||||
|
#ifndef LIB_RESTRICT_H
|
||||||
|
#define LIB_RESTRICT_H
|
||||||
|
|
||||||
|
int foo(int * restrict a, int * restrict b);
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,12 @@
|
||||||
|
|
||||||
|
int foo(int * restrict a, int * restrict b)
|
||||||
|
{
|
||||||
|
(void)a;
|
||||||
|
(void)b;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
|
||||||
|
#include "lib_restrict.h"
|
||||||
|
|
||||||
|
int bar(int * restrict a, int * restrict b)
|
||||||
|
{
|
||||||
|
(void)a;
|
||||||
|
(void)b;
|
||||||
|
return foo(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 3.0)
|
||||||
|
|
||||||
project(CompileFeatures)
|
project(CompileFeatures)
|
||||||
|
|
||||||
if (NOT CMAKE_CXX_COMPILE_FEATURES)
|
if (NOT CMAKE_C_COMPILE_FEATURES AND NOT CMAKE_CXX_COMPILE_FEATURES)
|
||||||
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/dummy.cpp"
|
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/dummy.cpp"
|
||||||
"int main(int,char**) { return 0; }\n"
|
"int main(int,char**) { return 0; }\n"
|
||||||
)
|
)
|
||||||
|
@ -22,6 +22,10 @@ macro(run_test feature lang)
|
||||||
endif()
|
endif()
|
||||||
endmacro()
|
endmacro()
|
||||||
|
|
||||||
|
get_property(c_features GLOBAL PROPERTY CMAKE_C_KNOWN_FEATURES)
|
||||||
|
foreach(feature ${c_features})
|
||||||
|
run_test(${feature} C)
|
||||||
|
endforeach()
|
||||||
get_property(cxx_features GLOBAL PROPERTY CMAKE_CXX_KNOWN_FEATURES)
|
get_property(cxx_features GLOBAL PROPERTY CMAKE_CXX_KNOWN_FEATURES)
|
||||||
foreach(feature ${cxx_features})
|
foreach(feature ${cxx_features})
|
||||||
run_test(${feature} CXX)
|
run_test(${feature} CXX)
|
||||||
|
@ -34,9 +38,11 @@ if (CMAKE_CXX_COMPILER_ID STREQUAL GNU
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
set(C_ext c)
|
||||||
|
set(C_standard_flag 11)
|
||||||
set(CXX_ext cpp)
|
set(CXX_ext cpp)
|
||||||
set(CXX_standard_flag 11)
|
set(CXX_standard_flag 11)
|
||||||
foreach(lang CXX)
|
foreach(lang CXX C)
|
||||||
if (CMAKE_${lang}_COMPILE_FEATURES)
|
if (CMAKE_${lang}_COMPILE_FEATURES)
|
||||||
foreach(feature ${${lang}_non_features})
|
foreach(feature ${${lang}_non_features})
|
||||||
message("Testing feature : ${feature}")
|
message("Testing feature : ${feature}")
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
|
||||||
|
int someFunc(int a, int b);
|
||||||
|
|
||||||
|
int someFunc(int a, int b)
|
||||||
|
{
|
||||||
|
(void)a;
|
||||||
|
(void)b;
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
|
||||||
|
int f (int * restrict a, int * restrict b)
|
||||||
|
{
|
||||||
|
(void)a;
|
||||||
|
(void)b;
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,2 @@
|
||||||
|
|
||||||
|
_Static_assert(1, "Static assert test");
|
|
@ -0,0 +1,15 @@
|
||||||
|
|
||||||
|
int someFunc(int i1, char c, int i2)
|
||||||
|
{
|
||||||
|
(void)i1;
|
||||||
|
(void)c;
|
||||||
|
(void)i2;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define FUNC_WRAPPER(...) someFunc(__VA_ARGS__)
|
||||||
|
|
||||||
|
void otherFunc()
|
||||||
|
{
|
||||||
|
FUNC_WRAPPER(42, 'a', 7);
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
|
||||||
|
int foo(int * restrict a, int * restrict b)
|
||||||
|
{
|
||||||
|
(void)a;
|
||||||
|
(void)b;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -26,7 +26,10 @@ target_link_libraries(sharediface INTERFACE sharedlib)
|
||||||
add_library(use_auto_type INTERFACE)
|
add_library(use_auto_type INTERFACE)
|
||||||
target_compile_features(use_auto_type INTERFACE cxx_auto_type)
|
target_compile_features(use_auto_type INTERFACE cxx_auto_type)
|
||||||
|
|
||||||
install(TARGETS headeronly sharediface use_auto_type
|
add_library(use_c_restrict INTERFACE)
|
||||||
|
target_compile_features(use_c_restrict INTERFACE c_restrict)
|
||||||
|
|
||||||
|
install(TARGETS headeronly sharediface use_auto_type use_c_restrict
|
||||||
EXPORT expInterface
|
EXPORT expInterface
|
||||||
)
|
)
|
||||||
install(TARGETS sharedlib
|
install(TARGETS sharedlib
|
||||||
|
|
|
@ -17,6 +17,7 @@ set_property(TARGET bld::sharediface APPEND PROPERTY INTERFACE_LINK_LIBRARIES de
|
||||||
add_executable(interfacetest_bld interfacetest.cpp)
|
add_executable(interfacetest_bld interfacetest.cpp)
|
||||||
target_link_libraries(interfacetest_bld bld::sharediface)
|
target_link_libraries(interfacetest_bld bld::sharediface)
|
||||||
|
|
||||||
|
include(CheckCSourceCompiles)
|
||||||
include(CheckCXXSourceCompiles)
|
include(CheckCXXSourceCompiles)
|
||||||
|
|
||||||
macro(do_try_compile prefix)
|
macro(do_try_compile prefix)
|
||||||
|
@ -41,6 +42,26 @@ macro(do_try_compile prefix)
|
||||||
message(SEND_ERROR "${prefix} try_compile with IMPORTED INTERFACE target failed!\n\n${OUTPUT}")
|
message(SEND_ERROR "${prefix} try_compile with IMPORTED INTERFACE target failed!\n\n${OUTPUT}")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if (";${CMAKE_C_COMPILE_FEATURES};" MATCHES ";c_restrict;")
|
||||||
|
set(CMAKE_REQUIRED_LIBRARIES ${prefix}::use_c_restrict)
|
||||||
|
check_c_source_compiles(
|
||||||
|
"
|
||||||
|
int foo(int * restrict a, int * restrict b)
|
||||||
|
{
|
||||||
|
(void)a;
|
||||||
|
(void)b;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
" ${prefix}IMPORTED_IFACE_C_RESTRICT)
|
||||||
|
|
||||||
|
if(NOT ${prefix}IMPORTED_IFACE_C_RESTRICT)
|
||||||
|
message(SEND_ERROR "${prefix} try_compile with IMPORTED INTERFACE target failed!\n\n${OUTPUT}")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
if (";${CMAKE_CXX_COMPILE_FEATURES};" MATCHES ";cxx_auto_type;")
|
if (";${CMAKE_CXX_COMPILE_FEATURES};" MATCHES ";cxx_auto_type;")
|
||||||
set(CMAKE_REQUIRED_LIBRARIES ${prefix}::use_auto_type)
|
set(CMAKE_REQUIRED_LIBRARIES ${prefix}::use_auto_type)
|
||||||
check_cxx_source_compiles(
|
check_cxx_source_compiles(
|
||||||
|
|
|
@ -6,6 +6,7 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||||
include(WriteCompilerDetectionHeader)
|
include(WriteCompilerDetectionHeader)
|
||||||
|
|
||||||
get_property(cxx_known_features GLOBAL PROPERTY CMAKE_CXX_KNOWN_FEATURES)
|
get_property(cxx_known_features GLOBAL PROPERTY CMAKE_CXX_KNOWN_FEATURES)
|
||||||
|
get_property(c_known_features GLOBAL PROPERTY CMAKE_C_KNOWN_FEATURES)
|
||||||
|
|
||||||
write_compiler_detection_header(
|
write_compiler_detection_header(
|
||||||
FILE "${CMAKE_CURRENT_BINARY_DIR}/test_compiler_detection.h"
|
FILE "${CMAKE_CURRENT_BINARY_DIR}/test_compiler_detection.h"
|
||||||
|
@ -15,10 +16,10 @@ write_compiler_detection_header(
|
||||||
PROLOG "// something"
|
PROLOG "// something"
|
||||||
EPILOG "// more"
|
EPILOG "// more"
|
||||||
FEATURES
|
FEATURES
|
||||||
${cxx_known_features}
|
${cxx_known_features} ${c_known_features}
|
||||||
)
|
)
|
||||||
|
|
||||||
if (NOT CMAKE_CXX_COMPILE_FEATURES)
|
if (NOT CMAKE_CXX_COMPILE_FEATURES AND NOT CMAKE_C_COMPILE_FEATURES)
|
||||||
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/dummy.cpp"
|
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/dummy.cpp"
|
||||||
"int main(int,char**) { return 0; }\n"
|
"int main(int,char**) { return 0; }\n"
|
||||||
)
|
)
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
1
|
|
@ -0,0 +1,8 @@
|
||||||
|
CMake Error at NoSupportedCFeatures.cmake:[0-9]+ \(target_compile_features\):
|
||||||
|
target_compile_features no known features for C compiler
|
||||||
|
|
||||||
|
"[^"]*"
|
||||||
|
|
||||||
|
version *[.0-9]+\.
|
||||||
|
Call Stack \(most recent call first\):
|
||||||
|
CMakeLists.txt:3 \(include\)
|
|
@ -0,0 +1,5 @@
|
||||||
|
|
||||||
|
enable_language(C)
|
||||||
|
|
||||||
|
add_library(no_features empty.c)
|
||||||
|
target_compile_features(no_features PRIVATE c_static_assert)
|
|
@ -0,0 +1 @@
|
||||||
|
1
|
|
@ -0,0 +1,6 @@
|
||||||
|
CMake Error in CMakeLists.txt:
|
||||||
|
No known features for C compiler
|
||||||
|
|
||||||
|
"[^"]*"
|
||||||
|
|
||||||
|
version *[.0-9]+\.
|
|
@ -0,0 +1,5 @@
|
||||||
|
|
||||||
|
enable_language(C)
|
||||||
|
|
||||||
|
add_library(no_features empty.c)
|
||||||
|
target_compile_features(no_features PRIVATE $<1:c_static_assert>)
|
|
@ -9,11 +9,20 @@ run_cmake(NotAFeature_OriginDebugTransitive)
|
||||||
run_cmake(NotAFeature_OriginDebug_target_compile_features)
|
run_cmake(NotAFeature_OriginDebug_target_compile_features)
|
||||||
|
|
||||||
run_cmake(generate_feature_list)
|
run_cmake(generate_feature_list)
|
||||||
|
file(READ
|
||||||
|
"${RunCMake_BINARY_DIR}/generate_feature_list-build/c_features.txt"
|
||||||
|
C_FEATURES
|
||||||
|
)
|
||||||
file(READ
|
file(READ
|
||||||
"${RunCMake_BINARY_DIR}/generate_feature_list-build/cxx_features.txt"
|
"${RunCMake_BINARY_DIR}/generate_feature_list-build/cxx_features.txt"
|
||||||
CXX_FEATURES
|
CXX_FEATURES
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if (NOT C_FEATURES)
|
||||||
|
run_cmake(NoSupportedCFeatures)
|
||||||
|
run_cmake(NoSupportedCFeaturesGenex)
|
||||||
|
endif()
|
||||||
|
|
||||||
if (NOT CXX_FEATURES)
|
if (NOT CXX_FEATURES)
|
||||||
run_cmake(NoSupportedCxxFeatures)
|
run_cmake(NoSupportedCxxFeatures)
|
||||||
run_cmake(NoSupportedCxxFeaturesGenex)
|
run_cmake(NoSupportedCxxFeaturesGenex)
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
#ifdef _WIN32
|
||||||
|
__declspec(dllexport)
|
||||||
|
#endif
|
||||||
|
int empty()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -1,4 +1,10 @@
|
||||||
|
|
||||||
|
enable_language(C)
|
||||||
|
|
||||||
|
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/c_features.txt"
|
||||||
|
"${CMAKE_C_COMPILE_FEATURES}"
|
||||||
|
)
|
||||||
|
|
||||||
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/cxx_features.txt"
|
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/cxx_features.txt"
|
||||||
"${CMAKE_CXX_COMPILE_FEATURES}"
|
"${CMAKE_CXX_COMPILE_FEATURES}"
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
-- Detecting C compiler ABI info
|
-- Detecting C compiler ABI info
|
||||||
-- Detecting C compiler ABI info - failed
|
-- Detecting C compiler ABI info - failed.*
|
||||||
-- Configuring done
|
-- Configuring done
|
||||||
-- Generating done
|
-- Generating done
|
||||||
|
|
|
@ -9,3 +9,5 @@ run_cmake(imported_target)
|
||||||
run_cmake(no_target)
|
run_cmake(no_target)
|
||||||
run_cmake(not_a_cxx_feature)
|
run_cmake(not_a_cxx_feature)
|
||||||
run_cmake(no_matching_cxx_feature)
|
run_cmake(no_matching_cxx_feature)
|
||||||
|
run_cmake(not_a_c_feature)
|
||||||
|
run_cmake(no_matching_c_feature)
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
#ifdef _WIN32
|
||||||
|
__declspec(dllexport)
|
||||||
|
#endif
|
||||||
|
int empty()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
1
|
|
@ -0,0 +1,8 @@
|
||||||
|
CMake Error at no_matching_c_feature.cmake:[0-9][0-9]? \((target_compile_features|message)\):
|
||||||
|
The compiler feature "gnu_c_dummy" is not known to C compiler
|
||||||
|
|
||||||
|
"GNU"
|
||||||
|
|
||||||
|
version 4.8.1.
|
||||||
|
Call Stack \(most recent call first\):
|
||||||
|
CMakeLists.txt:3 \(include\)
|
|
@ -0,0 +1,15 @@
|
||||||
|
|
||||||
|
if (NOT ";${CMAKE_C_COMPILE_FEATURES};" MATCHES ";gnu_c_typeof;")
|
||||||
|
# Simulate passing the test.
|
||||||
|
message(SEND_ERROR
|
||||||
|
"The compiler feature \"gnu_c_dummy\" is not known to C compiler\n\"GNU\"\nversion 4.8.1."
|
||||||
|
)
|
||||||
|
return()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
add_executable(main empty.c)
|
||||||
|
|
||||||
|
target_compile_features(main
|
||||||
|
PRIVATE
|
||||||
|
gnu_c_typeof
|
||||||
|
)
|
|
@ -0,0 +1 @@
|
||||||
|
1
|
|
@ -0,0 +1,5 @@
|
||||||
|
CMake Error at not_a_c_feature.cmake:3 \(target_compile_features\):
|
||||||
|
target_compile_features specified unknown feature "c_not_a_feature" for
|
||||||
|
target "main".
|
||||||
|
Call Stack \(most recent call first\):
|
||||||
|
CMakeLists.txt:3 \(include\)
|
|
@ -0,0 +1,6 @@
|
||||||
|
|
||||||
|
add_executable(main empty.c)
|
||||||
|
target_compile_features(main
|
||||||
|
PRIVATE
|
||||||
|
c_not_a_feature
|
||||||
|
)
|
|
@ -19,6 +19,16 @@ CMAKE_COMPILER_IS_GNUCC == "${CMAKE_COMPILER_IS_GNUCC}"
|
||||||
CMAKE_COMPILER_IS_GNUCXX == "${CMAKE_COMPILER_IS_GNUCXX}"
|
CMAKE_COMPILER_IS_GNUCXX == "${CMAKE_COMPILER_IS_GNUCXX}"
|
||||||
CMAKE_C_COMPILER_ID == "${CMAKE_C_COMPILER_ID}"
|
CMAKE_C_COMPILER_ID == "${CMAKE_C_COMPILER_ID}"
|
||||||
CMAKE_C_COMPILER_VERSION == "${CMAKE_C_COMPILER_VERSION}"
|
CMAKE_C_COMPILER_VERSION == "${CMAKE_C_COMPILER_VERSION}"
|
||||||
|
CMAKE_C90_STANDARD_COMPILE_OPTION == "${CMAKE_C90_STANDARD_COMPILE_OPTION}"
|
||||||
|
CMAKE_C99_STANDARD_COMPILE_OPTION == "${CMAKE_C99_STANDARD_COMPILE_OPTION}"
|
||||||
|
CMAKE_C11_STANDARD_COMPILE_OPTION == "${CMAKE_C11_STANDARD_COMPILE_OPTION}"
|
||||||
|
CMAKE_C90_EXTENSION_COMPILE_OPTION == "${CMAKE_C90_EXTENSION_COMPILE_OPTION}"
|
||||||
|
CMAKE_C99_EXTENSION_COMPILE_OPTION == "${CMAKE_C99_EXTENSION_COMPILE_OPTION}"
|
||||||
|
CMAKE_C11_EXTENSION_COMPILE_OPTION == "${CMAKE_C11_EXTENSION_COMPILE_OPTION}"
|
||||||
|
CMAKE_C_COMPILE_FEATURES == "${CMAKE_C_COMPILE_FEATURES}"
|
||||||
|
CMAKE_C90_COMPILE_FEATURES == "${CMAKE_C90_COMPILE_FEATURES}"
|
||||||
|
CMAKE_C99_COMPILE_FEATURES == "${CMAKE_C99_COMPILE_FEATURES}"
|
||||||
|
CMAKE_C11_COMPILE_FEATURES == "${CMAKE_C11_COMPILE_FEATURES}"
|
||||||
CMAKE_CXX_COMPILER_ID == "${CMAKE_CXX_COMPILER_ID}"
|
CMAKE_CXX_COMPILER_ID == "${CMAKE_CXX_COMPILER_ID}"
|
||||||
CMAKE_CXX_COMPILER_VERSION == "${CMAKE_CXX_COMPILER_VERSION}"
|
CMAKE_CXX_COMPILER_VERSION == "${CMAKE_CXX_COMPILER_VERSION}"
|
||||||
CMAKE_CXX98_STANDARD_COMPILE_OPTION == "${CMAKE_CXX98_STANDARD_COMPILE_OPTION}"
|
CMAKE_CXX98_STANDARD_COMPILE_OPTION == "${CMAKE_CXX98_STANDARD_COMPILE_OPTION}"
|
||||||
|
|
Loading…
Reference in New Issue