summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2016-12-01 20:46:34 (GMT)
committerBrad King <brad.king@kitware.com>2016-12-06 13:58:42 (GMT)
commitf72ba42b7c643b1b217d1b8f6684cec3289e7201 (patch)
tree7277ccca7c933e26b2cfc4aba2401477d7125408 /Source
parent45aa03b97aeeb512264ac2bfbb2028330be254d1 (diff)
downloadCMake-f72ba42b7c643b1b217d1b8f6684cec3289e7201.zip
CMake-f72ba42b7c643b1b217d1b8f6684cec3289e7201.tar.gz
CMake-f72ba42b7c643b1b217d1b8f6684cec3289e7201.tar.bz2
try_compile: Add policy CMP0067 to honor language standards
Projects use `try_compile` to check if they will be able to compile some particular source code. When a language standard variable like `CMAKE_CXX_STANDARD` is set, then the project intends to compile source code using a compiler mode for that standard. Therefore it makes sense for `try_compile` to use that standard in the test project too. Unfortunately this was not done when support for the `CMAKE_CXX_STANDARD` variable was first implemented. Add a policy to introduce the improved behavior in a compatible way. Closes: #16456
Diffstat (limited to 'Source')
-rw-r--r--Source/cmCoreTryCompile.cxx79
-rw-r--r--Source/cmCoreTryCompile.h4
-rw-r--r--Source/cmPolicies.h5
3 files changed, 87 insertions, 1 deletions
diff --git a/Source/cmCoreTryCompile.cxx b/Source/cmCoreTryCompile.cxx
index 3b72440..1b7180c 100644
--- a/Source/cmCoreTryCompile.cxx
+++ b/Source/cmCoreTryCompile.cxx
@@ -54,6 +54,17 @@ static void writeProperty(FILE* fout, std::string const& targetName,
cmOutputConverter::EscapeForCMake(value).c_str());
}
+std::string cmCoreTryCompile::LookupStdVar(std::string const& var,
+ bool warnCMP0067)
+{
+ std::string value = this->Makefile->GetSafeDefinition(var);
+ if (warnCMP0067 && !value.empty()) {
+ value.clear();
+ this->WarnCMP0067.push_back(var);
+ }
+ return value;
+}
+
int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
bool isTryRun)
{
@@ -620,6 +631,74 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
bool const testC = testLangs.find("C") != testLangs.end();
bool const testCxx = testLangs.find("CXX") != testLangs.end();
+ bool warnCMP0067 = false;
+ bool honorStandard = true;
+
+ if (!didCStandard && !didCxxStandard && !didCStandardRequired &&
+ !didCxxStandardRequired && !didCExtensions && !didCxxExtensions) {
+ switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0067)) {
+ case cmPolicies::WARN:
+ warnCMP0067 = this->Makefile->PolicyOptionalWarningEnabled(
+ "CMAKE_POLICY_WARNING_CMP0067");
+ case cmPolicies::OLD:
+ // OLD behavior is to not honor the language standard variables.
+ honorStandard = false;
+ break;
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::REQUIRED_ALWAYS:
+ this->Makefile->IssueMessage(
+ cmake::FATAL_ERROR,
+ cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0067));
+ case cmPolicies::NEW:
+ // NEW behavior is to honor the language standard variables.
+ // We already initialized honorStandard to true.
+ break;
+ }
+ }
+
+ if (honorStandard || warnCMP0067) {
+ if (testC) {
+ if (!didCStandard) {
+ cStandard = this->LookupStdVar("CMAKE_C_STANDARD", warnCMP0067);
+ }
+ if (!didCStandardRequired) {
+ cStandardRequired =
+ this->LookupStdVar("CMAKE_C_STANDARD_REQUIRED", warnCMP0067);
+ }
+ if (!didCExtensions) {
+ cExtensions = this->LookupStdVar("CMAKE_C_EXTENSIONS", warnCMP0067);
+ }
+ }
+ if (testCxx) {
+ if (!didCxxStandard) {
+ cxxStandard = this->LookupStdVar("CMAKE_CXX_STANDARD", warnCMP0067);
+ }
+ if (!didCxxStandardRequired) {
+ cxxStandardRequired =
+ this->LookupStdVar("CMAKE_CXX_STANDARD_REQUIRED", warnCMP0067);
+ }
+ if (!didCxxExtensions) {
+ cxxExtensions =
+ this->LookupStdVar("CMAKE_CXX_EXTENSIONS", warnCMP0067);
+ }
+ }
+ }
+
+ if (!this->WarnCMP0067.empty()) {
+ std::ostringstream w;
+ /* clang-format off */
+ w << cmPolicies::GetPolicyWarning(cmPolicies::CMP0067) << "\n"
+ "For compatibility with older versions of CMake, try_compile "
+ "is not honoring language standard variables in the test project:\n"
+ ;
+ /* clang-format on */
+ for (std::vector<std::string>::iterator vi = this->WarnCMP0067.begin();
+ vi != this->WarnCMP0067.end(); ++vi) {
+ w << " " << *vi << "\n";
+ }
+ this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, w.str());
+ }
+
if (testC) {
if (!cStandard.empty()) {
writeProperty(fout, targetName, "C_STANDARD", cStandard);
diff --git a/Source/cmCoreTryCompile.h b/Source/cmCoreTryCompile.h
index 1c94f09..4b96aed 100644
--- a/Source/cmCoreTryCompile.h
+++ b/Source/cmCoreTryCompile.h
@@ -47,6 +47,10 @@ protected:
std::string OutputFile;
std::string FindErrorMessage;
bool SrcFileSignature;
+
+private:
+ std::vector<std::string> WarnCMP0067;
+ std::string LookupStdVar(std::string const& var, bool warnCMP0067);
};
#endif
diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h
index 9b86435..62e67c7 100644
--- a/Source/cmPolicies.h
+++ b/Source/cmPolicies.h
@@ -197,7 +197,10 @@ class cmMakefile;
3, 4, 0, cmPolicies::WARN) \
SELECT(POLICY, CMP0066, \
"Honor per-config flags in try_compile() source-file signature.", 3, \
- 7, 0, cmPolicies::WARN)
+ 7, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0067, \
+ "Honor language standard in try_compile() source-file signature.", \
+ 3, 8, 0, cmPolicies::WARN)
#define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1)
#define CM_FOR_EACH_POLICY_ID(POLICY) \