diff --git a/Help/variable/CMAKE_CXX_KNOWN_FEATURES.rst b/Help/variable/CMAKE_CXX_KNOWN_FEATURES.rst index 7466d444eb..d49bb68292 100644 --- a/Help/variable/CMAKE_CXX_KNOWN_FEATURES.rst +++ b/Help/variable/CMAKE_CXX_KNOWN_FEATURES.rst @@ -6,3 +6,10 @@ List of C++ features known to this version of CMake. The features listed in this variable 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_CXX_COMPILE_FEATURES` variable. + +The features known to this version of CMake are: + +``cxx_auto_type`` + Automatic type deduction, as defined in N1984_. + + .. _N1984: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1984.pdf diff --git a/Modules/Compiler/GNU-CXX-FeatureTests.cmake b/Modules/Compiler/GNU-CXX-FeatureTests.cmake new file mode 100644 index 0000000000..b36315fed2 --- /dev/null +++ b/Modules/Compiler/GNU-CXX-FeatureTests.cmake @@ -0,0 +1,8 @@ + +# Reference: http://gcc.gnu.org/projects/cxx0x.html + +set(_oldestSupported "(__GNUC__ * 100 + __GNUC_MINOR__) >= 408") +# TODO: Should be supported by GNU 4.4 +set(GNU44_CXX11 "${_oldestSupported} && __cplusplus >= 201103L") +set(_cmake_feature_test_cxx_auto_type "${GNU44_CXX11}") +set(_oldestSupported) diff --git a/Modules/Compiler/GNU-CXX.cmake b/Modules/Compiler/GNU-CXX.cmake index 3ee8639efa..7acad5285a 100644 --- a/Modules/Compiler/GNU-CXX.cmake +++ b/Modules/Compiler/GNU-CXX.cmake @@ -23,3 +23,15 @@ elseif(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.3) set(CMAKE_CXX11_STANDARD_COMPILE_OPTION "-std=c++0x") set(CMAKE_CXX11_EXTENSION_COMPILE_OPTION "-std=gnu++0x") endif() + +macro(cmake_record_cxx_compile_features) + macro(_get_gcc_features std_version list) + record_compiler_features(CXX "-std=${std_version}" ${list}) + endmacro() + + if (UNIX AND NOT APPLE AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.8) + _get_gcc_features(c++11 CMAKE_CXX11_COMPILE_FEATURES) + else() + set(_result 0) + endif() +endmacro() diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index 64163de175..0b3c43e22f 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -41,7 +41,8 @@ #include // for isspace #include -#define FOR_EACH_CXX_FEATURE(F) +#define FOR_EACH_CXX_FEATURE(F) \ + F(cxx_auto_type) class cmMakefile::Internals { @@ -2453,6 +2454,12 @@ const char* cmMakefile::GetDefinition(const std::string& name) const { this->Internal->VarUsageStack.top().insert(name); } + if (name == "CMAKE_CXX_KNOWN_FEATURES") + { +#define STRING_LIST_ELEMENT(F) ";" #F + return FOR_EACH_CXX_FEATURE(STRING_LIST_ELEMENT) + 1; +#undef STRING_LIST_ELEMENT + } const char* def = this->Internal->VarStack.top().Get(name); if(!def) { @@ -4520,7 +4527,15 @@ AddRequiredTargetFeature(cmTarget *target, const std::string& feature, if (!isCxxFeature) { cmOStringStream e; - e << "specified unknown feature \"" << feature << "\" specified for " + if (error) + { + e << "specified"; + } + else + { + e << "Specified"; + } + e << " unknown feature \"" << feature << "\" for " "target \"" << target->GetName() << "\"."; if (error) { diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index aaa24c743c..fc58f1e774 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -197,6 +197,10 @@ if(BUILD_TESTING) ADD_TEST_MACRO(TarTest TarTest) ADD_TEST_MACRO(SystemInformation SystemInformation) ADD_TEST_MACRO(MathTest MathTest) + if(CMAKE_CXX_COMPILER_ID STREQUAL GNU + AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.8) + ADD_TEST_MACRO(CompileFeatures CompileFeatures) + endif() # assume no resources building to test set(TEST_RESOURCES FALSE) # for windows and cygwin assume we have resources diff --git a/Tests/CompileFeatures/CMakeLists.txt b/Tests/CompileFeatures/CMakeLists.txt new file mode 100644 index 0000000000..471b560c25 --- /dev/null +++ b/Tests/CompileFeatures/CMakeLists.txt @@ -0,0 +1,24 @@ + +cmake_minimum_required(VERSION 3.0) + +project(CompileFeatures) + +macro(run_test feature) + if (";${CMAKE_CXX_COMPILE_FEATURES};" MATCHES ${feature}) + add_library(test_${feature} OBJECT ${feature}.cpp) + set_property(TARGET test_${feature} + PROPERTY COMPILE_FEATURES "${feature}" + ) + else() + message("Not supported: ${feature}") + endif() +endmacro() + +foreach(feature ${CMAKE_CXX_KNOWN_FEATURES}) + run_test(${feature}) +endforeach() + +add_executable(CompileFeatures main.cpp) +set_property(TARGET CompileFeatures + PROPERTY COMPILE_FEATURES "cxx_auto_type" +) diff --git a/Tests/CompileFeatures/cxx_auto_type.cpp b/Tests/CompileFeatures/cxx_auto_type.cpp new file mode 100644 index 0000000000..7dbf04f678 --- /dev/null +++ b/Tests/CompileFeatures/cxx_auto_type.cpp @@ -0,0 +1,5 @@ + +void someFunc() +{ + auto x = 3.14; +} diff --git a/Tests/CompileFeatures/main.cpp b/Tests/CompileFeatures/main.cpp new file mode 100644 index 0000000000..3a8e0fcea3 --- /dev/null +++ b/Tests/CompileFeatures/main.cpp @@ -0,0 +1,6 @@ + +int main(int,char**) +{ + auto value = 0; + return value; +} diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt index 851de429dd..dd769ac065 100644 --- a/Tests/RunCMake/CMakeLists.txt +++ b/Tests/RunCMake/CMakeLists.txt @@ -53,6 +53,7 @@ add_RunCMake_test(ObjectLibrary) add_RunCMake_test(TargetObjects) add_RunCMake_test(TargetSources) add_RunCMake_test(find_dependency) +add_RunCMake_test(CompileFeatures) if(NOT WIN32) add_RunCMake_test(PositionIndependentCode) set(SKIP_VISIBILITY 0) diff --git a/Tests/RunCMake/CompileFeatures/CMakeLists.txt b/Tests/RunCMake/CompileFeatures/CMakeLists.txt new file mode 100644 index 0000000000..3482e6baf2 --- /dev/null +++ b/Tests/RunCMake/CompileFeatures/CMakeLists.txt @@ -0,0 +1,3 @@ +cmake_minimum_required(VERSION 3.0) +project(${RunCMake_TEST} CXX) +include(${RunCMake_TEST}.cmake) diff --git a/Tests/RunCMake/CompileFeatures/NotAFeature-result.txt b/Tests/RunCMake/CompileFeatures/NotAFeature-result.txt new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/Tests/RunCMake/CompileFeatures/NotAFeature-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CompileFeatures/NotAFeature-stderr.txt b/Tests/RunCMake/CompileFeatures/NotAFeature-stderr.txt new file mode 100644 index 0000000000..ff60e50a59 --- /dev/null +++ b/Tests/RunCMake/CompileFeatures/NotAFeature-stderr.txt @@ -0,0 +1,2 @@ +CMake Error in CMakeLists.txt: + Specified unknown feature "not_a_feature" for target "somelib". diff --git a/Tests/RunCMake/CompileFeatures/NotAFeature.cmake b/Tests/RunCMake/CompileFeatures/NotAFeature.cmake new file mode 100644 index 0000000000..35246c8bdc --- /dev/null +++ b/Tests/RunCMake/CompileFeatures/NotAFeature.cmake @@ -0,0 +1,3 @@ + +add_library(somelib STATIC empty.cpp) +set_property(TARGET somelib PROPERTY COMPILE_FEATURES "not_a_feature") diff --git a/Tests/RunCMake/CompileFeatures/RunCMakeTest.cmake b/Tests/RunCMake/CompileFeatures/RunCMakeTest.cmake new file mode 100644 index 0000000000..3c999e67d8 --- /dev/null +++ b/Tests/RunCMake/CompileFeatures/RunCMakeTest.cmake @@ -0,0 +1,3 @@ +include(RunCMake) + +run_cmake(NotAFeature) diff --git a/Tests/RunCMake/CompileFeatures/empty.cpp b/Tests/RunCMake/CompileFeatures/empty.cpp new file mode 100644 index 0000000000..bfbbddeb90 --- /dev/null +++ b/Tests/RunCMake/CompileFeatures/empty.cpp @@ -0,0 +1,7 @@ +#ifdef _WIN32 +__declspec(dllexport) +#endif +int empty() +{ + return 0; +} diff --git a/Tests/SystemInformation/SystemInformation.in b/Tests/SystemInformation/SystemInformation.in index 92b24e2fc5..954a2fe58f 100644 --- a/Tests/SystemInformation/SystemInformation.in +++ b/Tests/SystemInformation/SystemInformation.in @@ -25,6 +25,8 @@ CMAKE_CXX98_STANDARD_COMPILE_OPTION == "${CMAKE_CXX98_STANDARD_COMPILE_OPTION}" CMAKE_CXX11_STANDARD_COMPILE_OPTION == "${CMAKE_CXX11_STANDARD_COMPILE_OPTION}" CMAKE_CXX98_EXTENSION_COMPILE_OPTION == "${CMAKE_CXX98_EXTENSION_COMPILE_OPTION}" CMAKE_CXX11_EXTENSION_COMPILE_OPTION == "${CMAKE_CXX11_EXTENSION_COMPILE_OPTION}" +CMAKE_CXX_COMPILE_FEATURES == "${CMAKE_CXX_COMPILE_FEATURES}" +CMAKE_CXX11_COMPILE_FEATURES == "${CMAKE_CXX11_COMPILE_FEATURES}" // C shared library flag CMAKE_SHARED_LIBRARY_C_FLAGS == "${CMAKE_SHARED_LIBRARY_C_FLAGS}"