mirror of
https://github.com/Kitware/CMake.git
synced 2026-01-06 05:40:54 -06:00
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
This commit is contained in:
@@ -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());
|
||||
|
||||
Reference in New Issue
Block a user