summaryrefslogtreecommitdiffstats
path: root/Source/cmCoreTryCompile.cxx
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2016-12-01 19:24:02 (GMT)
committerBrad King <brad.king@kitware.com>2016-12-06 13:58:41 (GMT)
commit45aa03b97aeeb512264ac2bfbb2028330be254d1 (patch)
tree883f2e60ea1539fa93f988b0e32dd983a043e020 /Source/cmCoreTryCompile.cxx
parent3bb2051eef5c3a07f99e9e6549187211758317d6 (diff)
downloadCMake-45aa03b97aeeb512264ac2bfbb2028330be254d1.zip
CMake-45aa03b97aeeb512264ac2bfbb2028330be254d1.tar.gz
CMake-45aa03b97aeeb512264ac2bfbb2028330be254d1.tar.bz2
try_compile: Add options to specify language standards
Give `try_compile` callers a way to control the `CXX_STANDARD`, `CXX_STANDARD_REQUIRED`, and `CXX_EXTENSIONS` properties of the generated test target (or the `C` equivalents) in order to compile a test source for a particular language standard. Issue: #16456
Diffstat (limited to 'Source/cmCoreTryCompile.cxx')
-rw-r--r--Source/cmCoreTryCompile.cxx128
1 files changed, 128 insertions, 0 deletions
diff --git a/Source/cmCoreTryCompile.cxx b/Source/cmCoreTryCompile.cxx
index fbad778..3b72440 100644
--- a/Source/cmCoreTryCompile.cxx
+++ b/Source/cmCoreTryCompile.cxx
@@ -46,6 +46,14 @@ 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());
+}
+
int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
bool isTryRun)
{
@@ -87,6 +95,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 +108,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 +126,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 +152,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 +210,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 +275,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 +616,36 @@ 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();
+
+ 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());