diff --git a/Help/prop_tgt/CXX_STANDARD.rst b/Help/prop_tgt/CXX_STANDARD.rst index e1b6e7873..fb72f3e19 100644 --- a/Help/prop_tgt/CXX_STANDARD.rst +++ b/Help/prop_tgt/CXX_STANDARD.rst @@ -1,14 +1,26 @@ CXX_STANDARD ------------ -The C++ standard whose features are required to build this target. +The C++ standard whose features are requested to build this target. -This property specifies the C++ standard whose features are required +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=c++11`` to the compile line. Supported values are ``98`` 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 CXX_STANDARD 11) + +with a compiler which does not support ``-std=c++11`` or an equivalent +flag will not result in an error or warning, but will instead add the +``-std=c++98`` flag if supported. + This property is initialized by the value of the :variable:`CMAKE_CXX_STANDARD` variable if it is set when a target is created. diff --git a/Modules/Compiler/GNU-CXX.cmake b/Modules/Compiler/GNU-CXX.cmake index 74645258a..d3249850e 100644 --- a/Modules/Compiler/GNU-CXX.cmake +++ b/Modules/Compiler/GNU-CXX.cmake @@ -24,6 +24,8 @@ elseif(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.3) set(CMAKE_CXX11_EXTENSION_COMPILE_OPTION "-std=gnu++0x") endif() +set(CMAKE_CXX_STANDARD_DEFAULT 98) + macro(cmake_record_cxx_compile_features) macro(_get_gcc_features std_version list) record_compiler_features(CXX "-std=${std_version}" ${list}) diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index f375b5f3c..a29a0cd8b 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -2152,8 +2152,8 @@ AddCompilerRequirementFlag(std::string &flags, cmTarget* target, return; } std::string stdProp = lang + "_STANDARD"; - const char *standard = target->GetProperty(stdProp); - if (!standard) + const char *standardProp = target->GetProperty(stdProp); + if (!standardProp) { return; } @@ -2161,12 +2161,46 @@ AddCompilerRequirementFlag(std::string &flags, cmTarget* target, bool ext = target->GetPropertyAsBool(extProp); std::string type = ext ? "EXTENSION" : "STANDARD"; - std::string compile_option = - "CMAKE_" + lang + std::string(standard) - + "_" + type + "_COMPILE_OPTION"; - if (const char *opt = target->GetMakefile()->GetDefinition(compile_option)) + static std::map > langStdMap; + if (langStdMap.empty()) { - this->AppendFlags(flags, opt); + // Maintain sorted order, most recent first. + langStdMap["CXX"].push_back("11"); + langStdMap["CXX"].push_back("98"); + } + + std::string standard(standardProp); + + std::vector& stds = langStdMap[lang]; + + std::vector::const_iterator stdIt = + std::find(stds.begin(), stds.end(), standard); + assert(stdIt != stds.end()); + + const char* defaultStd + = this->Makefile->GetDefinition("CMAKE_" + lang + "_STANDARD_DEFAULT"); + std::vector::const_iterator defaultStdIt; + if (defaultStd) + { + defaultStdIt = std::find(stds.begin(), stds.end(), defaultStd); + assert(defaultStdIt != stds.end()); + } + else + { + defaultStdIt = stds.end() - 1; + } + + for ( ; stdIt <= defaultStdIt; ++stdIt) + { + std::string option_flag = + "CMAKE_" + lang + *stdIt + + "_" + type + "_COMPILE_OPTION"; + + if (const char *opt = target->GetMakefile()->GetDefinition(option_flag)) + { + this->AppendFlags(flags, opt); + return; + } } }