summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2016-12-07 14:22:22 (GMT)
committerCMake Topic Stage <kwrobot@kitware.com>2016-12-07 14:22:22 (GMT)
commita0d64ecf8b9eac29cbfeb7461cf3bcb1688f7aa7 (patch)
tree99011b6e805e6032e1679d0fa98ecd5f8e846458 /Source
parent0478314e13e6d04a0100cc3be4ab84540a8beaa5 (diff)
parentf72ba42b7c643b1b217d1b8f6684cec3289e7201 (diff)
downloadCMake-a0d64ecf8b9eac29cbfeb7461cf3bcb1688f7aa7.zip
CMake-a0d64ecf8b9eac29cbfeb7461cf3bcb1688f7aa7.tar.gz
CMake-a0d64ecf8b9eac29cbfeb7461cf3bcb1688f7aa7.tar.bz2
Merge topic 'try_compile-lang-std'
f72ba42b try_compile: Add policy CMP0067 to honor language standards 45aa03b9 try_compile: Add options to specify language standards 3bb2051e try_compile: Stop processing when test build system fails to generate
Diffstat (limited to 'Source')
-rw-r--r--Source/cmCoreTryCompile.cxx207
-rw-r--r--Source/cmCoreTryCompile.h4
-rw-r--r--Source/cmMakefile.cxx16
-rw-r--r--Source/cmPolicies.h5
4 files changed, 225 insertions, 7 deletions
diff --git a/Source/cmCoreTryCompile.cxx b/Source/cmCoreTryCompile.cxx
index fbad778..1b7180c 100644
--- a/Source/cmCoreTryCompile.cxx
+++ b/Source/cmCoreTryCompile.cxx
@@ -46,6 +46,25 @@ static std::string const kCMAKE_TRY_COMPILE_PLATFORM_VARIABLES =
"CMAKE_TRY_COMPILE_PLATFORM_VARIABLES";
static std::string const kCMAKE_WARN_DEPRECATED = "CMAKE_WARN_DEPRECATED";
+static void writeProperty(FILE* fout, std::string const& targetName,
+ std::string const& prop, std::string const& value)
+{
+ fprintf(fout, "set_property(TARGET %s PROPERTY %s %s)\n", targetName.c_str(),
+ cmOutputConverter::EscapeForCMake(prop).c_str(),
+ 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)
{
@@ -87,6 +106,12 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
std::string outputVariable;
std::string copyFile;
std::string copyFileError;
+ std::string cStandard;
+ std::string cxxStandard;
+ std::string cStandardRequired;
+ std::string cxxStandardRequired;
+ std::string cExtensions;
+ std::string cxxExtensions;
std::vector<std::string> targets;
std::string libsToLink = " ";
bool useOldLinkLibs = true;
@@ -94,6 +119,12 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
bool didOutputVariable = false;
bool didCopyFile = false;
bool didCopyFileError = false;
+ bool didCStandard = false;
+ bool didCxxStandard = false;
+ bool didCStandardRequired = false;
+ bool didCxxStandardRequired = false;
+ bool didCExtensions = false;
+ bool didCxxExtensions = false;
bool useSources = argv[2] == "SOURCES";
std::vector<std::string> sources;
@@ -106,6 +137,12 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
DoingOutputVariable,
DoingCopyFile,
DoingCopyFileError,
+ DoingCStandard,
+ DoingCxxStandard,
+ DoingCStandardRequired,
+ DoingCxxStandardRequired,
+ DoingCExtensions,
+ DoingCxxExtensions,
DoingSources
};
Doing doing = useSources ? DoingSources : DoingNone;
@@ -126,6 +163,24 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
} else if (argv[i] == "COPY_FILE_ERROR") {
doing = DoingCopyFileError;
didCopyFileError = true;
+ } else if (argv[i] == "C_STANDARD") {
+ doing = DoingCStandard;
+ didCStandard = true;
+ } else if (argv[i] == "CXX_STANDARD") {
+ doing = DoingCxxStandard;
+ didCxxStandard = true;
+ } else if (argv[i] == "C_STANDARD_REQUIRED") {
+ doing = DoingCStandardRequired;
+ didCStandardRequired = true;
+ } else if (argv[i] == "CXX_STANDARD_REQUIRED") {
+ doing = DoingCxxStandardRequired;
+ didCxxStandardRequired = true;
+ } else if (argv[i] == "C_EXTENSIONS") {
+ doing = DoingCExtensions;
+ didCExtensions = true;
+ } else if (argv[i] == "CXX_EXTENSIONS") {
+ doing = DoingCxxExtensions;
+ didCxxExtensions = true;
} else if (doing == DoingCMakeFlags) {
cmakeFlags.push_back(argv[i]);
} else if (doing == DoingCompileDefinitions) {
@@ -166,6 +221,24 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
} else if (doing == DoingCopyFileError) {
copyFileError = argv[i];
doing = DoingNone;
+ } else if (doing == DoingCStandard) {
+ cStandard = argv[i];
+ doing = DoingNone;
+ } else if (doing == DoingCxxStandard) {
+ cxxStandard = argv[i];
+ doing = DoingNone;
+ } else if (doing == DoingCStandardRequired) {
+ cStandardRequired = argv[i];
+ doing = DoingNone;
+ } else if (doing == DoingCxxStandardRequired) {
+ cxxStandardRequired = argv[i];
+ doing = DoingNone;
+ } else if (doing == DoingCExtensions) {
+ cExtensions = argv[i];
+ doing = DoingNone;
+ } else if (doing == DoingCxxExtensions) {
+ cxxExtensions = argv[i];
+ doing = DoingNone;
} else if (doing == DoingSources) {
sources.push_back(argv[i]);
} else if (i == 3) {
@@ -213,6 +286,42 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
return -1;
}
+ if (didCStandard && !this->SrcFileSignature) {
+ this->Makefile->IssueMessage(
+ cmake::FATAL_ERROR, "C_STANDARD allowed only in source file signature.");
+ return -1;
+ }
+ if (didCxxStandard && !this->SrcFileSignature) {
+ this->Makefile->IssueMessage(
+ cmake::FATAL_ERROR,
+ "CXX_STANDARD allowed only in source file signature.");
+ return -1;
+ }
+ if (didCStandardRequired && !this->SrcFileSignature) {
+ this->Makefile->IssueMessage(
+ cmake::FATAL_ERROR,
+ "C_STANDARD_REQUIRED allowed only in source file signature.");
+ return -1;
+ }
+ if (didCxxStandardRequired && !this->SrcFileSignature) {
+ this->Makefile->IssueMessage(
+ cmake::FATAL_ERROR,
+ "CXX_STANDARD_REQUIRED allowed only in source file signature.");
+ return -1;
+ }
+ if (didCExtensions && !this->SrcFileSignature) {
+ this->Makefile->IssueMessage(
+ cmake::FATAL_ERROR,
+ "C_EXTENSIONS allowed only in source file signature.");
+ return -1;
+ }
+ if (didCxxExtensions && !this->SrcFileSignature) {
+ this->Makefile->IssueMessage(
+ cmake::FATAL_ERROR,
+ "CXX_EXTENSIONS allowed only in source file signature.");
+ return -1;
+ }
+
// compute the binary dir when TRY_COMPILE is called with a src file
// signature
if (this->SrcFileSignature) {
@@ -518,6 +627,104 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
}
}
fprintf(fout, ")\n");
+
+ 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);
+ }
+ if (!cStandardRequired.empty()) {
+ writeProperty(fout, targetName, "C_STANDARD_REQUIRED",
+ cStandardRequired);
+ }
+ if (!cExtensions.empty()) {
+ writeProperty(fout, targetName, "C_EXTENSIONS", cExtensions);
+ }
+ }
+
+ if (testCxx) {
+ if (!cxxStandard.empty()) {
+ writeProperty(fout, targetName, "CXX_STANDARD", cxxStandard);
+ }
+ if (!cxxStandardRequired.empty()) {
+ writeProperty(fout, targetName, "CXX_STANDARD_REQUIRED",
+ cxxStandardRequired);
+ }
+ if (!cxxExtensions.empty()) {
+ writeProperty(fout, targetName, "CXX_EXTENSIONS", cxxExtensions);
+ }
+ }
+
if (useOldLinkLibs) {
fprintf(fout, "target_link_libraries(%s ${LINK_LIBRARIES})\n",
targetName.c_str());
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/cmMakefile.cxx b/Source/cmMakefile.cxx
index ed0f73b..f52fe26 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -3158,8 +3158,10 @@ int cmMakefile::TryCompile(const std::string& srcdir,
cmGlobalGenerator* gg =
cm.CreateGlobalGenerator(this->GetGlobalGenerator()->GetName());
if (!gg) {
- cmSystemTools::Error(
- "Internal CMake error, TryCompile bad GlobalGenerator");
+ this->IssueMessage(cmake::INTERNAL_ERROR, "Global generator '" +
+ this->GetGlobalGenerator()->GetName() +
+ "' could not be created.");
+ cmSystemTools::SetFatalErrorOccured();
// return to the original directory
cmSystemTools::ChangeDirectory(cwd);
this->IsSourceFileTryCompile = false;
@@ -3222,8 +3224,9 @@ int cmMakefile::TryCompile(const std::string& srcdir,
cmStateEnums::INTERNAL);
}
if (cm.Configure() != 0) {
- cmSystemTools::Error(
- "Internal CMake error, TryCompile configure of cmake failed");
+ this->IssueMessage(cmake::FATAL_ERROR,
+ "Failed to configure test project build system.");
+ cmSystemTools::SetFatalErrorOccured();
// return to the original directory
cmSystemTools::ChangeDirectory(cwd);
this->IsSourceFileTryCompile = false;
@@ -3231,8 +3234,9 @@ int cmMakefile::TryCompile(const std::string& srcdir,
}
if (cm.Generate() != 0) {
- cmSystemTools::Error(
- "Internal CMake error, TryCompile generation of cmake failed");
+ this->IssueMessage(cmake::FATAL_ERROR,
+ "Failed to generate test project build system.");
+ cmSystemTools::SetFatalErrorOccured();
// return to the original directory
cmSystemTools::ChangeDirectory(cwd);
this->IsSourceFileTryCompile = false;
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) \