diff options
author | Brad King <brad.king@kitware.com> | 2016-12-01 20:46:34 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2016-12-06 13:58:42 (GMT) |
commit | f72ba42b7c643b1b217d1b8f6684cec3289e7201 (patch) | |
tree | 7277ccca7c933e26b2cfc4aba2401477d7125408 /Source | |
parent | 45aa03b97aeeb512264ac2bfbb2028330be254d1 (diff) | |
download | CMake-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.cxx | 79 | ||||
-rw-r--r-- | Source/cmCoreTryCompile.h | 4 | ||||
-rw-r--r-- | Source/cmPolicies.h | 5 |
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) \ |