cmGeneratorExpressionEvaluationFile.cxx 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
  2. file Copyright.txt or https://cmake.org/licensing for details. */
  3. #include "cmGeneratorExpressionEvaluationFile.h"
  4. #include "cmGeneratedFileStream.h"
  5. #include "cmGlobalGenerator.h"
  6. #include "cmListFileCache.h"
  7. #include "cmLocalGenerator.h"
  8. #include "cmMakefile.h"
  9. #include "cmSourceFile.h"
  10. #include "cmSystemTools.h"
  11. #include "cmake.h"
  12. #include <cmConfigure.h>
  13. #include <cmsys/FStream.hxx>
  14. #include <sstream>
  15. #include <utility>
  16. cmGeneratorExpressionEvaluationFile::cmGeneratorExpressionEvaluationFile(
  17. const std::string& input,
  18. CM_AUTO_PTR<cmCompiledGeneratorExpression> outputFileExpr,
  19. CM_AUTO_PTR<cmCompiledGeneratorExpression> condition, bool inputIsContent)
  20. : Input(input)
  21. , OutputFileExpr(outputFileExpr)
  22. , Condition(condition)
  23. , InputIsContent(inputIsContent)
  24. {
  25. }
  26. void cmGeneratorExpressionEvaluationFile::Generate(
  27. cmLocalGenerator* lg, const std::string& config, const std::string& lang,
  28. cmCompiledGeneratorExpression* inputExpression,
  29. std::map<std::string, std::string>& outputFiles, mode_t perm)
  30. {
  31. std::string rawCondition = this->Condition->GetInput();
  32. if (!rawCondition.empty()) {
  33. std::string condResult = this->Condition->Evaluate(
  34. lg, config, false, CM_NULLPTR, CM_NULLPTR, CM_NULLPTR, lang);
  35. if (condResult == "0") {
  36. return;
  37. }
  38. if (condResult != "1") {
  39. std::ostringstream e;
  40. e << "Evaluation file condition \"" << rawCondition
  41. << "\" did "
  42. "not evaluate to valid content. Got \""
  43. << condResult << "\".";
  44. lg->IssueMessage(cmake::FATAL_ERROR, e.str());
  45. return;
  46. }
  47. }
  48. const std::string outputFileName = this->OutputFileExpr->Evaluate(
  49. lg, config, false, CM_NULLPTR, CM_NULLPTR, CM_NULLPTR, lang);
  50. const std::string outputContent = inputExpression->Evaluate(
  51. lg, config, false, CM_NULLPTR, CM_NULLPTR, CM_NULLPTR, lang);
  52. std::map<std::string, std::string>::iterator it =
  53. outputFiles.find(outputFileName);
  54. if (it != outputFiles.end()) {
  55. if (it->second == outputContent) {
  56. return;
  57. }
  58. std::ostringstream e;
  59. e << "Evaluation file to be written multiple times for different "
  60. "configurations or languages with different content:\n "
  61. << outputFileName;
  62. lg->IssueMessage(cmake::FATAL_ERROR, e.str());
  63. return;
  64. }
  65. lg->GetMakefile()->AddCMakeOutputFile(outputFileName);
  66. this->Files.push_back(outputFileName);
  67. outputFiles[outputFileName] = outputContent;
  68. cmGeneratedFileStream fout(outputFileName.c_str());
  69. fout.SetCopyIfDifferent(true);
  70. fout << outputContent;
  71. if (fout.Close() && perm) {
  72. cmSystemTools::SetPermissions(outputFileName.c_str(), perm);
  73. }
  74. }
  75. void cmGeneratorExpressionEvaluationFile::CreateOutputFile(
  76. cmLocalGenerator* lg, std::string const& config)
  77. {
  78. std::vector<std::string> enabledLanguages;
  79. cmGlobalGenerator* gg = lg->GetGlobalGenerator();
  80. gg->GetEnabledLanguages(enabledLanguages);
  81. for (std::vector<std::string>::const_iterator le = enabledLanguages.begin();
  82. le != enabledLanguages.end(); ++le) {
  83. std::string name = this->OutputFileExpr->Evaluate(
  84. lg, config, false, CM_NULLPTR, CM_NULLPTR, CM_NULLPTR, *le);
  85. cmSourceFile* sf = lg->GetMakefile()->GetOrCreateSource(name);
  86. sf->SetProperty("GENERATED", "1");
  87. gg->SetFilenameTargetDepends(
  88. sf, this->OutputFileExpr->GetSourceSensitiveTargets());
  89. }
  90. }
  91. void cmGeneratorExpressionEvaluationFile::Generate(cmLocalGenerator* lg)
  92. {
  93. mode_t perm = 0;
  94. std::string inputContent;
  95. if (this->InputIsContent) {
  96. inputContent = this->Input;
  97. } else {
  98. lg->GetMakefile()->AddCMakeDependFile(this->Input);
  99. cmSystemTools::GetPermissions(this->Input.c_str(), perm);
  100. cmsys::ifstream fin(this->Input.c_str());
  101. if (!fin) {
  102. std::ostringstream e;
  103. e << "Evaluation file \"" << this->Input << "\" cannot be read.";
  104. lg->IssueMessage(cmake::FATAL_ERROR, e.str());
  105. return;
  106. }
  107. std::string line;
  108. std::string sep;
  109. while (cmSystemTools::GetLineFromStream(fin, line)) {
  110. inputContent += sep + line;
  111. sep = "\n";
  112. }
  113. inputContent += sep;
  114. }
  115. cmListFileBacktrace lfbt = this->OutputFileExpr->GetBacktrace();
  116. cmGeneratorExpression contentGE(lfbt);
  117. CM_AUTO_PTR<cmCompiledGeneratorExpression> inputExpression =
  118. contentGE.Parse(inputContent);
  119. std::map<std::string, std::string> outputFiles;
  120. std::vector<std::string> allConfigs;
  121. lg->GetMakefile()->GetConfigurations(allConfigs);
  122. if (allConfigs.empty()) {
  123. allConfigs.push_back("");
  124. }
  125. std::vector<std::string> enabledLanguages;
  126. cmGlobalGenerator* gg = lg->GetGlobalGenerator();
  127. gg->GetEnabledLanguages(enabledLanguages);
  128. for (std::vector<std::string>::const_iterator le = enabledLanguages.begin();
  129. le != enabledLanguages.end(); ++le) {
  130. for (std::vector<std::string>::const_iterator li = allConfigs.begin();
  131. li != allConfigs.end(); ++li) {
  132. this->Generate(lg, *li, *le, inputExpression.get(), outputFiles, perm);
  133. if (cmSystemTools::GetFatalErrorOccured()) {
  134. return;
  135. }
  136. }
  137. }
  138. }