summaryrefslogtreecommitdiffstats
path: root/Source/cmCoreTryCompile.cxx
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/cmCoreTryCompile.cxx
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/cmCoreTryCompile.cxx')
-rw-r--r--Source/cmCoreTryCompile.cxx79
1 files changed, 79 insertions, 0 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);