| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249 | 
							- /* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
 
-    file Copyright.txt or https://cmake.org/licensing for details.  */
 
- #include "cmGeneratorExpressionEvaluationFile.h"
 
- #include <memory>
 
- #include <sstream>
 
- #include <utility>
 
- #include "cmsys/FStream.hxx"
 
- #include "cmGeneratedFileStream.h"
 
- #include "cmGlobalGenerator.h"
 
- #include "cmListFileCache.h"
 
- #include "cmLocalGenerator.h"
 
- #include "cmMakefile.h"
 
- #include "cmMessageType.h"
 
- #include "cmSourceFile.h"
 
- #include "cmSystemTools.h"
 
- cmGeneratorExpressionEvaluationFile::cmGeneratorExpressionEvaluationFile(
 
-   std::string input, std::string target,
 
-   std::unique_ptr<cmCompiledGeneratorExpression> outputFileExpr,
 
-   std::unique_ptr<cmCompiledGeneratorExpression> condition,
 
-   bool inputIsContent, mode_t permissions,
 
-   cmPolicies::PolicyStatus policyStatusCMP0070)
 
-   : Input(std::move(input))
 
-   , Target(std::move(target))
 
-   , OutputFileExpr(std::move(outputFileExpr))
 
-   , Condition(std::move(condition))
 
-   , InputIsContent(inputIsContent)
 
-   , PolicyStatusCMP0070(policyStatusCMP0070)
 
-   , Permissions(permissions)
 
- {
 
- }
 
- void cmGeneratorExpressionEvaluationFile::Generate(
 
-   cmLocalGenerator* lg, const std::string& config, const std::string& lang,
 
-   cmCompiledGeneratorExpression* inputExpression,
 
-   std::map<std::string, std::string>& outputFiles, mode_t perm)
 
- {
 
-   std::string rawCondition = this->Condition->GetInput();
 
-   cmGeneratorTarget* target = lg->FindGeneratorTargetToUse(this->Target);
 
-   if (!rawCondition.empty()) {
 
-     std::string condResult =
 
-       this->Condition->Evaluate(lg, config, target, nullptr, nullptr, lang);
 
-     if (condResult == "0") {
 
-       return;
 
-     }
 
-     if (condResult != "1") {
 
-       std::ostringstream e;
 
-       e << "Evaluation file condition \"" << rawCondition
 
-         << "\" did "
 
-            "not evaluate to valid content. Got \""
 
-         << condResult << "\".";
 
-       lg->IssueMessage(MessageType::FATAL_ERROR, e.str());
 
-       return;
 
-     }
 
-   }
 
-   const std::string outputFileName =
 
-     this->GetOutputFileName(lg, target, config, lang);
 
-   const std::string& outputContent =
 
-     inputExpression->Evaluate(lg, config, target, nullptr, nullptr, lang);
 
-   auto it = outputFiles.find(outputFileName);
 
-   if (it != outputFiles.end()) {
 
-     if (it->second == outputContent) {
 
-       return;
 
-     }
 
-     std::ostringstream e;
 
-     e << "Evaluation file to be written multiple times with different "
 
-          "content. "
 
-          "This is generally caused by the content evaluating the "
 
-          "configuration type, language, or location of object files:\n "
 
-       << outputFileName;
 
-     lg->IssueMessage(MessageType::FATAL_ERROR, e.str());
 
-     return;
 
-   }
 
-   lg->GetMakefile()->AddCMakeOutputFile(outputFileName);
 
-   this->Files.push_back(outputFileName);
 
-   outputFiles[outputFileName] = outputContent;
 
-   cmGeneratedFileStream fout(outputFileName);
 
-   fout.SetCopyIfDifferent(true);
 
-   fout << outputContent;
 
-   if (fout.Close() && perm) {
 
-     cmSystemTools::SetPermissions(outputFileName.c_str(), perm);
 
-   }
 
- }
 
- void cmGeneratorExpressionEvaluationFile::CreateOutputFile(
 
-   cmLocalGenerator* lg, std::string const& config)
 
- {
 
-   std::vector<std::string> enabledLanguages;
 
-   cmGlobalGenerator* gg = lg->GetGlobalGenerator();
 
-   cmGeneratorTarget* target = lg->FindGeneratorTargetToUse(this->Target);
 
-   gg->GetEnabledLanguages(enabledLanguages);
 
-   for (std::string const& le : enabledLanguages) {
 
-     std::string const name = this->GetOutputFileName(lg, target, config, le);
 
-     cmSourceFile* sf = lg->GetMakefile()->GetOrCreateGeneratedSource(name);
 
-     // Tell the build system generators that there is no build rule
 
-     // to generate the file.
 
-     sf->SetProperty("__CMAKE_GENERATED_BY_CMAKE", "1");
 
-     gg->SetFilenameTargetDepends(
 
-       sf, this->OutputFileExpr->GetSourceSensitiveTargets());
 
-   }
 
- }
 
- void cmGeneratorExpressionEvaluationFile::Generate(cmLocalGenerator* lg)
 
- {
 
-   std::string inputContent;
 
-   if (this->InputIsContent) {
 
-     inputContent = this->Input;
 
-   } else {
 
-     const std::string inputFileName = this->GetInputFileName(lg);
 
-     lg->GetMakefile()->AddCMakeDependFile(inputFileName);
 
-     if (!this->Permissions) {
 
-       cmSystemTools::GetPermissions(inputFileName.c_str(), this->Permissions);
 
-     }
 
-     cmsys::ifstream fin(inputFileName.c_str());
 
-     if (!fin) {
 
-       std::ostringstream e;
 
-       e << "Evaluation file \"" << inputFileName << "\" cannot be read.";
 
-       lg->IssueMessage(MessageType::FATAL_ERROR, e.str());
 
-       return;
 
-     }
 
-     std::string line;
 
-     std::string sep;
 
-     while (cmSystemTools::GetLineFromStream(fin, line)) {
 
-       inputContent += sep + line;
 
-       sep = "\n";
 
-     }
 
-     inputContent += sep;
 
-   }
 
-   cmListFileBacktrace lfbt = this->OutputFileExpr->GetBacktrace();
 
-   cmGeneratorExpression contentGE(lfbt);
 
-   std::unique_ptr<cmCompiledGeneratorExpression> inputExpression =
 
-     contentGE.Parse(inputContent);
 
-   std::map<std::string, std::string> outputFiles;
 
-   std::vector<std::string> allConfigs =
 
-     lg->GetMakefile()->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
 
-   std::vector<std::string> enabledLanguages;
 
-   cmGlobalGenerator* gg = lg->GetGlobalGenerator();
 
-   gg->GetEnabledLanguages(enabledLanguages);
 
-   for (std::string const& le : enabledLanguages) {
 
-     for (std::string const& li : allConfigs) {
 
-       this->Generate(lg, li, le, inputExpression.get(), outputFiles,
 
-                      this->Permissions);
 
-       if (cmSystemTools::GetFatalErrorOccured()) {
 
-         return;
 
-       }
 
-     }
 
-   }
 
- }
 
- std::string cmGeneratorExpressionEvaluationFile::GetInputFileName(
 
-   cmLocalGenerator* lg)
 
- {
 
-   std::string inputFileName = this->Input;
 
-   if (cmSystemTools::FileIsFullPath(inputFileName)) {
 
-     inputFileName = cmSystemTools::CollapseFullPath(inputFileName);
 
-   } else {
 
-     inputFileName = this->FixRelativePath(inputFileName, PathForInput, lg);
 
-   }
 
-   return inputFileName;
 
- }
 
- std::string cmGeneratorExpressionEvaluationFile::GetOutputFileName(
 
-   cmLocalGenerator* lg, cmGeneratorTarget* target, const std::string& config,
 
-   const std::string& lang)
 
- {
 
-   std::string outputFileName =
 
-     this->OutputFileExpr->Evaluate(lg, config, target, nullptr, nullptr, lang);
 
-   if (cmSystemTools::FileIsFullPath(outputFileName)) {
 
-     outputFileName = cmSystemTools::CollapseFullPath(outputFileName);
 
-   } else {
 
-     outputFileName = this->FixRelativePath(outputFileName, PathForOutput, lg);
 
-   }
 
-   return outputFileName;
 
- }
 
- std::string cmGeneratorExpressionEvaluationFile::FixRelativePath(
 
-   std::string const& relativePath, PathRole role, cmLocalGenerator* lg)
 
- {
 
-   std::string resultPath;
 
-   switch (this->PolicyStatusCMP0070) {
 
-     case cmPolicies::WARN: {
 
-       std::string arg;
 
-       switch (role) {
 
-         case PathForInput:
 
-           arg = "INPUT";
 
-           break;
 
-         case PathForOutput:
 
-           arg = "OUTPUT";
 
-           break;
 
-       }
 
-       std::ostringstream w;
 
-       /* clang-format off */
 
-       w <<
 
-         cmPolicies::GetPolicyWarning(cmPolicies::CMP0070) << "\n"
 
-         "file(GENERATE) given relative " << arg << " path:\n"
 
-         "  " << relativePath << "\n"
 
-         "This is not defined behavior unless CMP0070 is set to NEW.  "
 
-         "For compatibility with older versions of CMake, the previous "
 
-         "undefined behavior will be used."
 
-         ;
 
-       /* clang-format on */
 
-       lg->IssueMessage(MessageType::AUTHOR_WARNING, w.str());
 
-     }
 
-       CM_FALLTHROUGH;
 
-     case cmPolicies::OLD:
 
-       // OLD behavior is to use the relative path unchanged,
 
-       // which ends up being used relative to the working dir.
 
-       resultPath = relativePath;
 
-       break;
 
-     case cmPolicies::REQUIRED_IF_USED:
 
-     case cmPolicies::REQUIRED_ALWAYS:
 
-     case cmPolicies::NEW:
 
-       // NEW behavior is to interpret the relative path with respect
 
-       // to the current source or binary directory.
 
-       switch (role) {
 
-         case PathForInput:
 
-           resultPath = cmSystemTools::CollapseFullPath(
 
-             relativePath, lg->GetCurrentSourceDirectory());
 
-           break;
 
-         case PathForOutput:
 
-           resultPath = cmSystemTools::CollapseFullPath(
 
-             relativePath, lg->GetCurrentBinaryDirectory());
 
-           break;
 
-       }
 
-       break;
 
-   }
 
-   return resultPath;
 
- }
 
 
  |