summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Kelly <steveire@gmail.com>2014-03-28 15:09:35 (GMT)
committerStephen Kelly <steveire@gmail.com>2014-05-07 10:17:49 (GMT)
commit1df2116bfaa4c575404ae1eef225aed1530d668a (patch)
tree99a8fd5375d47f6359fd269c0d9e3ab030bc131e
parentc4f4dac2d550f0a8a44530187eac2ad03191c981 (diff)
downloadCMake-1df2116bfaa4c575404ae1eef225aed1530d668a.zip
CMake-1df2116bfaa4c575404ae1eef225aed1530d668a.tar.gz
CMake-1df2116bfaa4c575404ae1eef225aed1530d668a.tar.bz2
Features: Decay language flag if requested is not available.
Use the highest standard compile flags available if requested language version is too new. This supports use-cases like set(CMAKE_CXX_STANDARD 14) # Compiled with -std=c++11 with GNU 4.7, which has no -std=c++14 # or equivalent flag add_executable(main main.cpp) This can be used in combination with preprocessor defines which communicate the availability of certain language features for optional use.
-rw-r--r--Help/prop_tgt/CXX_STANDARD.rst16
-rw-r--r--Modules/Compiler/GNU-CXX.cmake2
-rw-r--r--Source/cmLocalGenerator.cxx48
3 files changed, 57 insertions, 9 deletions
diff --git a/Help/prop_tgt/CXX_STANDARD.rst b/Help/prop_tgt/CXX_STANDARD.rst
index e1b6e78..fb72f3e 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 7464525..d324985 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 f375b5f..a29a0cd 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<std::string, std::vector<std::string> > 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<std::string>& stds = langStdMap[lang];
+
+ std::vector<std::string>::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<std::string>::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;
+ }
}
}