cmCoreTryCompile: Return more semantic information from compile step

Update the `TryCompileCode` signature to allow callers to distinguish
between administrative failures and a compilation failure.  Return
results in a structure to which more information can be added later.
This commit is contained in:
Brad King
2022-12-12 10:16:54 -05:00
parent dcb1c9c080
commit fdda4095a3
3 changed files with 39 additions and 30 deletions
+29 -26
View File
@@ -285,8 +285,8 @@ Arguments cmCoreTryCompile::ParseArgs(
return arguments; return arguments;
} }
bool cmCoreTryCompile::TryCompileCode(Arguments& arguments, cm::optional<cmTryCompileResult> cmCoreTryCompile::TryCompileCode(
cmStateEnums::TargetType targetType) Arguments& arguments, cmStateEnums::TargetType targetType)
{ {
this->OutputFile.clear(); this->OutputFile.clear();
// which signature were we called with ? // which signature were we called with ?
@@ -302,7 +302,7 @@ bool cmCoreTryCompile::TryCompileCode(Arguments& arguments,
arguments.SourceDirectoryOrFile->empty()) { arguments.SourceDirectoryOrFile->empty()) {
this->Makefile->IssueMessage(MessageType::FATAL_ERROR, this->Makefile->IssueMessage(MessageType::FATAL_ERROR,
"No <srcdir> specified."); "No <srcdir> specified.");
return false; return cm::nullopt;
} }
sourceDirectory = *arguments.SourceDirectoryOrFile; sourceDirectory = *arguments.SourceDirectoryOrFile;
projectName = *arguments.ProjectName; projectName = *arguments.ProjectName;
@@ -322,7 +322,7 @@ bool cmCoreTryCompile::TryCompileCode(Arguments& arguments,
if (!arguments.BinaryDirectory || arguments.BinaryDirectory->empty()) { if (!arguments.BinaryDirectory || arguments.BinaryDirectory->empty()) {
this->Makefile->IssueMessage(MessageType::FATAL_ERROR, this->Makefile->IssueMessage(MessageType::FATAL_ERROR,
"No <bindir> specified."); "No <bindir> specified.");
return false; return cm::nullopt;
} }
if (*arguments.BinaryDirectory == unique_binary_directory) { if (*arguments.BinaryDirectory == unique_binary_directory) {
// leave empty until we're ready to create it, so we don't try to remove // leave empty until we're ready to create it, so we don't try to remove
@@ -335,7 +335,7 @@ bool cmCoreTryCompile::TryCompileCode(Arguments& arguments,
MessageType::FATAL_ERROR, MessageType::FATAL_ERROR,
cmStrCat("<bindir> is not an absolute path:\n '", cmStrCat("<bindir> is not an absolute path:\n '",
*arguments.BinaryDirectory, "'")); *arguments.BinaryDirectory, "'"));
return false; return cm::nullopt;
} }
this->BinaryDirectory = *arguments.BinaryDirectory; this->BinaryDirectory = *arguments.BinaryDirectory;
// compute the binary dir when TRY_COMPILE is called with a src file // compute the binary dir when TRY_COMPILE is called with a src file
@@ -367,7 +367,7 @@ bool cmCoreTryCompile::TryCompileCode(Arguments& arguments,
"IMPORTED LINK_LIBRARIES. Got ", "IMPORTED LINK_LIBRARIES. Got ",
tgt->GetName(), " of type ", tgt->GetName(), " of type ",
cmState::GetTargetTypeName(tgt->GetType()), ".")); cmState::GetTargetTypeName(tgt->GetType()), "."));
return false; return cm::nullopt;
} }
if (tgt->IsImported()) { if (tgt->IsImported()) {
targets.emplace_back(i); targets.emplace_back(i);
@@ -379,28 +379,28 @@ bool cmCoreTryCompile::TryCompileCode(Arguments& arguments,
if (arguments.CopyFileTo && arguments.CopyFileTo->empty()) { if (arguments.CopyFileTo && arguments.CopyFileTo->empty()) {
this->Makefile->IssueMessage(MessageType::FATAL_ERROR, this->Makefile->IssueMessage(MessageType::FATAL_ERROR,
"COPY_FILE must be followed by a file path"); "COPY_FILE must be followed by a file path");
return false; return cm::nullopt;
} }
if (arguments.CopyFileError && arguments.CopyFileError->empty()) { if (arguments.CopyFileError && arguments.CopyFileError->empty()) {
this->Makefile->IssueMessage( this->Makefile->IssueMessage(
MessageType::FATAL_ERROR, MessageType::FATAL_ERROR,
"COPY_FILE_ERROR must be followed by a variable name"); "COPY_FILE_ERROR must be followed by a variable name");
return false; return cm::nullopt;
} }
if (arguments.CopyFileError && !arguments.CopyFileTo) { if (arguments.CopyFileError && !arguments.CopyFileTo) {
this->Makefile->IssueMessage( this->Makefile->IssueMessage(
MessageType::FATAL_ERROR, MessageType::FATAL_ERROR,
"COPY_FILE_ERROR may be used only with COPY_FILE"); "COPY_FILE_ERROR may be used only with COPY_FILE");
return false; return cm::nullopt;
} }
if (arguments.Sources && arguments.Sources->empty()) { if (arguments.Sources && arguments.Sources->empty()) {
this->Makefile->IssueMessage( this->Makefile->IssueMessage(
MessageType::FATAL_ERROR, MessageType::FATAL_ERROR,
"SOURCES must be followed by at least one source file"); "SOURCES must be followed by at least one source file");
return false; return cm::nullopt;
} }
if (this->SrcFileSignature) { if (this->SrcFileSignature) {
@@ -409,19 +409,19 @@ bool cmCoreTryCompile::TryCompileCode(Arguments& arguments,
this->Makefile->IssueMessage( this->Makefile->IssueMessage(
MessageType::FATAL_ERROR, MessageType::FATAL_ERROR,
"SOURCE_FROM_CONTENT requires exactly two arguments"); "SOURCE_FROM_CONTENT requires exactly two arguments");
return false; return cm::nullopt;
} }
if (arguments.SourceFromVar && arguments.SourceFromVar->size() % 2) { if (arguments.SourceFromVar && arguments.SourceFromVar->size() % 2) {
this->Makefile->IssueMessage( this->Makefile->IssueMessage(
MessageType::FATAL_ERROR, MessageType::FATAL_ERROR,
"SOURCE_FROM_VAR requires exactly two arguments"); "SOURCE_FROM_VAR requires exactly two arguments");
return false; return cm::nullopt;
} }
if (arguments.SourceFromFile && arguments.SourceFromFile->size() % 2) { if (arguments.SourceFromFile && arguments.SourceFromFile->size() % 2) {
this->Makefile->IssueMessage( this->Makefile->IssueMessage(
MessageType::FATAL_ERROR, MessageType::FATAL_ERROR,
"SOURCE_FROM_FILE requires exactly two arguments"); "SOURCE_FROM_FILE requires exactly two arguments");
return false; return cm::nullopt;
} }
} else { } else {
// only valid for srcfile signatures // only valid for srcfile signatures
@@ -430,19 +430,19 @@ bool cmCoreTryCompile::TryCompileCode(Arguments& arguments,
MessageType::FATAL_ERROR, MessageType::FATAL_ERROR,
cmStrCat(arguments.LangProps.begin()->first, cmStrCat(arguments.LangProps.begin()->first,
" allowed only in source file signature")); " allowed only in source file signature"));
return false; return cm::nullopt;
} }
if (!arguments.CompileDefs.empty()) { if (!arguments.CompileDefs.empty()) {
this->Makefile->IssueMessage( this->Makefile->IssueMessage(
MessageType::FATAL_ERROR, MessageType::FATAL_ERROR,
"COMPILE_DEFINITIONS allowed only in source file signature"); "COMPILE_DEFINITIONS allowed only in source file signature");
return false; return cm::nullopt;
} }
if (arguments.CopyFileTo) { if (arguments.CopyFileTo) {
this->Makefile->IssueMessage( this->Makefile->IssueMessage(
MessageType::FATAL_ERROR, MessageType::FATAL_ERROR,
"COPY_FILE allowed only in source file signature"); "COPY_FILE allowed only in source file signature");
return false; return cm::nullopt;
} }
} }
@@ -462,7 +462,7 @@ bool cmCoreTryCompile::TryCompileCode(Arguments& arguments,
e << "Attempt at a recursive or nested TRY_COMPILE in directory\n" e << "Attempt at a recursive or nested TRY_COMPILE in directory\n"
<< " " << this->BinaryDirectory << "\n"; << " " << this->BinaryDirectory << "\n";
this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str()); this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
return false; return cm::nullopt;
} }
std::string outFileName = this->BinaryDirectory + "/CMakeLists.txt"; std::string outFileName = this->BinaryDirectory + "/CMakeLists.txt";
@@ -486,7 +486,7 @@ bool cmCoreTryCompile::TryCompileCode(Arguments& arguments,
const auto& content = (*arguments.SourceFromContent)[i + 1]; const auto& content = (*arguments.SourceFromContent)[i + 1];
auto out = this->WriteSource(name, content, "SOURCE_FROM_CONTENT"); auto out = this->WriteSource(name, content, "SOURCE_FROM_CONTENT");
if (out.empty()) { if (out.empty()) {
return false; return cm::nullopt;
} }
sources.emplace_back(std::move(out)); sources.emplace_back(std::move(out));
} }
@@ -499,7 +499,7 @@ bool cmCoreTryCompile::TryCompileCode(Arguments& arguments,
const auto& content = this->Makefile->GetDefinition(var); const auto& content = this->Makefile->GetDefinition(var);
auto out = this->WriteSource(name, content, "SOURCE_FROM_VAR"); auto out = this->WriteSource(name, content, "SOURCE_FROM_VAR");
if (out.empty()) { if (out.empty()) {
return false; return cm::nullopt;
} }
sources.emplace_back(std::move(out)); sources.emplace_back(std::move(out));
} }
@@ -514,7 +514,7 @@ bool cmCoreTryCompile::TryCompileCode(Arguments& arguments,
const auto& msg = const auto& msg =
cmStrCat("SOURCE_FROM_FILE given invalid filename \"", dst, "\""); cmStrCat("SOURCE_FROM_FILE given invalid filename \"", dst, "\"");
this->Makefile->IssueMessage(MessageType::FATAL_ERROR, msg); this->Makefile->IssueMessage(MessageType::FATAL_ERROR, msg);
return false; return cm::nullopt;
} }
auto dstPath = cmStrCat(this->BinaryDirectory, "/", dst); auto dstPath = cmStrCat(this->BinaryDirectory, "/", dst);
@@ -523,7 +523,7 @@ bool cmCoreTryCompile::TryCompileCode(Arguments& arguments,
const auto& msg = cmStrCat("SOURCE_FROM_FILE failed to copy \"", src, const auto& msg = cmStrCat("SOURCE_FROM_FILE failed to copy \"", src,
"\": ", result.GetString()); "\": ", result.GetString());
this->Makefile->IssueMessage(MessageType::FATAL_ERROR, msg); this->Makefile->IssueMessage(MessageType::FATAL_ERROR, msg);
return false; return cm::nullopt;
} }
sources.emplace_back(std::move(dstPath)); sources.emplace_back(std::move(dstPath));
@@ -550,7 +550,7 @@ bool cmCoreTryCompile::TryCompileCode(Arguments& arguments,
err << cmJoin(langs, " "); err << cmJoin(langs, " ");
err << "\nSee project() command to enable other languages."; err << "\nSee project() command to enable other languages.";
this->Makefile->IssueMessage(MessageType::FATAL_ERROR, err.str()); this->Makefile->IssueMessage(MessageType::FATAL_ERROR, err.str());
return false; return cm::nullopt;
} }
} }
@@ -577,7 +577,7 @@ bool cmCoreTryCompile::TryCompileCode(Arguments& arguments,
<< cmSystemTools::GetLastSystemError(); << cmSystemTools::GetLastSystemError();
/* clang-format on */ /* clang-format on */
this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str()); this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
return false; return cm::nullopt;
} }
cmValue def = this->Makefile->GetDefinition("CMAKE_MODULE_PATH"); cmValue def = this->Makefile->GetDefinition("CMAKE_MODULE_PATH");
@@ -778,7 +778,7 @@ bool cmCoreTryCompile::TryCompileCode(Arguments& arguments,
this->Makefile->IssueMessage(MessageType::FATAL_ERROR, this->Makefile->IssueMessage(MessageType::FATAL_ERROR,
"could not write export file."); "could not write export file.");
fclose(fout); fclose(fout);
return false; return cm::nullopt;
} }
fprintf(fout, "\ninclude(\"${CMAKE_CURRENT_LIST_DIR}/%s\")\n\n", fprintf(fout, "\ninclude(\"${CMAKE_CURRENT_LIST_DIR}/%s\")\n\n",
fname.c_str()); fname.c_str());
@@ -1111,7 +1111,7 @@ bool cmCoreTryCompile::TryCompileCode(Arguments& arguments,
} }
if (!arguments.CopyFileError) { if (!arguments.CopyFileError) {
this->Makefile->IssueMessage(MessageType::FATAL_ERROR, emsg.str()); this->Makefile->IssueMessage(MessageType::FATAL_ERROR, emsg.str());
return false; return cm::nullopt;
} }
copyFileErrorMessage = emsg.str(); copyFileErrorMessage = emsg.str();
} }
@@ -1122,7 +1122,10 @@ bool cmCoreTryCompile::TryCompileCode(Arguments& arguments,
this->Makefile->AddDefinition(copyFileError, copyFileErrorMessage); this->Makefile->AddDefinition(copyFileError, copyFileErrorMessage);
} }
} }
return res == 0;
cmTryCompileResult result;
result.ExitCode = res;
return result;
} }
bool cmCoreTryCompile::IsTemporary(std::string const& path) bool cmCoreTryCompile::IsTemporary(std::string const& path)
+7 -2
View File
@@ -18,6 +18,11 @@ class cmMakefile;
template <typename Iter> template <typename Iter>
class cmRange; class cmRange;
struct cmTryCompileResult
{
int ExitCode = 1;
};
/** \class cmCoreTryCompile /** \class cmCoreTryCompile
* \brief Base class for cmTryCompileCommand and cmTryRunCommand * \brief Base class for cmTryCompileCommand and cmTryRunCommand
* *
@@ -80,8 +85,8 @@ public:
* This function requires at least two \p arguments and will crash if given * This function requires at least two \p arguments and will crash if given
* fewer. * fewer.
*/ */
bool TryCompileCode(Arguments& arguments, cm::optional<cmTryCompileResult> TryCompileCode(
cmStateEnums::TargetType targetType); Arguments& arguments, cmStateEnums::TargetType targetType);
/** /**
* Returns \c true if \p path resides within a CMake temporary directory, * Returns \c true if \p path resides within a CMake temporary directory,
+3 -2
View File
@@ -109,10 +109,11 @@ bool TryRunCommandImpl::TryRunCode(std::vector<std::string> const& argv)
} }
// do the try compile // do the try compile
bool compiled = this->TryCompileCode(arguments, cmStateEnums::EXECUTABLE); cm::optional<cmTryCompileResult> compileResult =
this->TryCompileCode(arguments, cmStateEnums::EXECUTABLE);
// now try running the command if it compiled // now try running the command if it compiled
if (compiled) { if (compileResult && compileResult->ExitCode == 0) {
if (this->OutputFile.empty()) { if (this->OutputFile.empty()) {
cmSystemTools::Error(this->FindErrorMessage); cmSystemTools::Error(this->FindErrorMessage);
} else { } else {