Переглянути джерело

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.
Brad King 2 роки тому
батько
коміт
fdda4095a3
3 змінених файлів з 39 додано та 30 видалено
  1. 29 26
      Source/cmCoreTryCompile.cxx
  2. 7 2
      Source/cmCoreTryCompile.h
  3. 3 2
      Source/cmTryRunCommand.cxx

+ 29 - 26
Source/cmCoreTryCompile.cxx

@@ -285,8 +285,8 @@ Arguments cmCoreTryCompile::ParseArgs(
   return arguments;
 }
 
-bool cmCoreTryCompile::TryCompileCode(Arguments& arguments,
-                                      cmStateEnums::TargetType targetType)
+cm::optional<cmTryCompileResult> cmCoreTryCompile::TryCompileCode(
+  Arguments& arguments, cmStateEnums::TargetType targetType)
 {
   this->OutputFile.clear();
   // which signature were we called with ?
@@ -302,7 +302,7 @@ bool cmCoreTryCompile::TryCompileCode(Arguments& arguments,
         arguments.SourceDirectoryOrFile->empty()) {
       this->Makefile->IssueMessage(MessageType::FATAL_ERROR,
                                    "No <srcdir> specified.");
-      return false;
+      return cm::nullopt;
     }
     sourceDirectory = *arguments.SourceDirectoryOrFile;
     projectName = *arguments.ProjectName;
@@ -322,7 +322,7 @@ bool cmCoreTryCompile::TryCompileCode(Arguments& arguments,
   if (!arguments.BinaryDirectory || arguments.BinaryDirectory->empty()) {
     this->Makefile->IssueMessage(MessageType::FATAL_ERROR,
                                  "No <bindir> specified.");
-    return false;
+    return cm::nullopt;
   }
   if (*arguments.BinaryDirectory == unique_binary_directory) {
     // 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,
         cmStrCat("<bindir> is not an absolute path:\n '",
                  *arguments.BinaryDirectory, "'"));
-      return false;
+      return cm::nullopt;
     }
     this->BinaryDirectory = *arguments.BinaryDirectory;
     // 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 ",
                        tgt->GetName(), " of type ",
                        cmState::GetTargetTypeName(tgt->GetType()), "."));
-            return false;
+            return cm::nullopt;
         }
         if (tgt->IsImported()) {
           targets.emplace_back(i);
@@ -379,28 +379,28 @@ bool cmCoreTryCompile::TryCompileCode(Arguments& arguments,
   if (arguments.CopyFileTo && arguments.CopyFileTo->empty()) {
     this->Makefile->IssueMessage(MessageType::FATAL_ERROR,
                                  "COPY_FILE must be followed by a file path");
-    return false;
+    return cm::nullopt;
   }
 
   if (arguments.CopyFileError && arguments.CopyFileError->empty()) {
     this->Makefile->IssueMessage(
       MessageType::FATAL_ERROR,
       "COPY_FILE_ERROR must be followed by a variable name");
-    return false;
+    return cm::nullopt;
   }
 
   if (arguments.CopyFileError && !arguments.CopyFileTo) {
     this->Makefile->IssueMessage(
       MessageType::FATAL_ERROR,
       "COPY_FILE_ERROR may be used only with COPY_FILE");
-    return false;
+    return cm::nullopt;
   }
 
   if (arguments.Sources && arguments.Sources->empty()) {
     this->Makefile->IssueMessage(
       MessageType::FATAL_ERROR,
       "SOURCES must be followed by at least one source file");
-    return false;
+    return cm::nullopt;
   }
 
   if (this->SrcFileSignature) {
@@ -409,19 +409,19 @@ bool cmCoreTryCompile::TryCompileCode(Arguments& arguments,
       this->Makefile->IssueMessage(
         MessageType::FATAL_ERROR,
         "SOURCE_FROM_CONTENT requires exactly two arguments");
-      return false;
+      return cm::nullopt;
     }
     if (arguments.SourceFromVar && arguments.SourceFromVar->size() % 2) {
       this->Makefile->IssueMessage(
         MessageType::FATAL_ERROR,
         "SOURCE_FROM_VAR requires exactly two arguments");
-      return false;
+      return cm::nullopt;
     }
     if (arguments.SourceFromFile && arguments.SourceFromFile->size() % 2) {
       this->Makefile->IssueMessage(
         MessageType::FATAL_ERROR,
         "SOURCE_FROM_FILE requires exactly two arguments");
-      return false;
+      return cm::nullopt;
     }
   } else {
     // only valid for srcfile signatures
@@ -430,19 +430,19 @@ bool cmCoreTryCompile::TryCompileCode(Arguments& arguments,
         MessageType::FATAL_ERROR,
         cmStrCat(arguments.LangProps.begin()->first,
                  " allowed only in source file signature"));
-      return false;
+      return cm::nullopt;
     }
     if (!arguments.CompileDefs.empty()) {
       this->Makefile->IssueMessage(
         MessageType::FATAL_ERROR,
         "COMPILE_DEFINITIONS allowed only in source file signature");
-      return false;
+      return cm::nullopt;
     }
     if (arguments.CopyFileTo) {
       this->Makefile->IssueMessage(
         MessageType::FATAL_ERROR,
         "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"
       << "  " << this->BinaryDirectory << "\n";
     this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
-    return false;
+    return cm::nullopt;
   }
 
   std::string outFileName = this->BinaryDirectory + "/CMakeLists.txt";
@@ -486,7 +486,7 @@ bool cmCoreTryCompile::TryCompileCode(Arguments& arguments,
         const auto& content = (*arguments.SourceFromContent)[i + 1];
         auto out = this->WriteSource(name, content, "SOURCE_FROM_CONTENT");
         if (out.empty()) {
-          return false;
+          return cm::nullopt;
         }
         sources.emplace_back(std::move(out));
       }
@@ -499,7 +499,7 @@ bool cmCoreTryCompile::TryCompileCode(Arguments& arguments,
         const auto& content = this->Makefile->GetDefinition(var);
         auto out = this->WriteSource(name, content, "SOURCE_FROM_VAR");
         if (out.empty()) {
-          return false;
+          return cm::nullopt;
         }
         sources.emplace_back(std::move(out));
       }
@@ -514,7 +514,7 @@ bool cmCoreTryCompile::TryCompileCode(Arguments& arguments,
           const auto& msg =
             cmStrCat("SOURCE_FROM_FILE given invalid filename \"", dst, "\"");
           this->Makefile->IssueMessage(MessageType::FATAL_ERROR, msg);
-          return false;
+          return cm::nullopt;
         }
 
         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,
                                      "\": ", result.GetString());
           this->Makefile->IssueMessage(MessageType::FATAL_ERROR, msg);
-          return false;
+          return cm::nullopt;
         }
 
         sources.emplace_back(std::move(dstPath));
@@ -550,7 +550,7 @@ bool cmCoreTryCompile::TryCompileCode(Arguments& arguments,
         err << cmJoin(langs, " ");
         err << "\nSee project() command to enable other languages.";
         this->Makefile->IssueMessage(MessageType::FATAL_ERROR, err.str());
-        return false;
+        return cm::nullopt;
       }
     }
 
@@ -577,7 +577,7 @@ bool cmCoreTryCompile::TryCompileCode(Arguments& arguments,
         << cmSystemTools::GetLastSystemError();
       /* clang-format on */
       this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
-      return false;
+      return cm::nullopt;
     }
 
     cmValue def = this->Makefile->GetDefinition("CMAKE_MODULE_PATH");
@@ -778,7 +778,7 @@ bool cmCoreTryCompile::TryCompileCode(Arguments& arguments,
         this->Makefile->IssueMessage(MessageType::FATAL_ERROR,
                                      "could not write export file.");
         fclose(fout);
-        return false;
+        return cm::nullopt;
       }
       fprintf(fout, "\ninclude(\"${CMAKE_CURRENT_LIST_DIR}/%s\")\n\n",
               fname.c_str());
@@ -1111,7 +1111,7 @@ bool cmCoreTryCompile::TryCompileCode(Arguments& arguments,
         }
         if (!arguments.CopyFileError) {
           this->Makefile->IssueMessage(MessageType::FATAL_ERROR, emsg.str());
-          return false;
+          return cm::nullopt;
         }
         copyFileErrorMessage = emsg.str();
       }
@@ -1122,7 +1122,10 @@ bool cmCoreTryCompile::TryCompileCode(Arguments& arguments,
       this->Makefile->AddDefinition(copyFileError, copyFileErrorMessage);
     }
   }
-  return res == 0;
+
+  cmTryCompileResult result;
+  result.ExitCode = res;
+  return result;
 }
 
 bool cmCoreTryCompile::IsTemporary(std::string const& path)

+ 7 - 2
Source/cmCoreTryCompile.h

@@ -18,6 +18,11 @@ class cmMakefile;
 template <typename Iter>
 class cmRange;
 
+struct cmTryCompileResult
+{
+  int ExitCode = 1;
+};
+
 /** \class cmCoreTryCompile
  * \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
    * fewer.
    */
-  bool TryCompileCode(Arguments& arguments,
-                      cmStateEnums::TargetType targetType);
+  cm::optional<cmTryCompileResult> TryCompileCode(
+    Arguments& arguments, cmStateEnums::TargetType targetType);
 
   /**
    * Returns \c true if \p path resides within a CMake temporary directory,

+ 3 - 2
Source/cmTryRunCommand.cxx

@@ -109,10 +109,11 @@ bool TryRunCommandImpl::TryRunCode(std::vector<std::string> const& argv)
   }
 
   // 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
-  if (compiled) {
+  if (compileResult && compileResult->ExitCode == 0) {
     if (this->OutputFile.empty()) {
       cmSystemTools::Error(this->FindErrorMessage);
     } else {