diff options
Diffstat (limited to 'Source/cmGeneratorExpressionEvaluationFile.cxx')
-rw-r--r-- | Source/cmGeneratorExpressionEvaluationFile.cxx | 163 |
1 files changed, 163 insertions, 0 deletions
diff --git a/Source/cmGeneratorExpressionEvaluationFile.cxx b/Source/cmGeneratorExpressionEvaluationFile.cxx new file mode 100644 index 0000000..c01c4fc --- /dev/null +++ b/Source/cmGeneratorExpressionEvaluationFile.cxx @@ -0,0 +1,163 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2013 Stephen Kelly <steveire@gmail.com> + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ + +#include "cmGeneratorExpressionEvaluationFile.h" + +#include "cmGeneratedFileStream.h" +#include "cmGlobalGenerator.h" +#include "cmLocalGenerator.h" +#include "cmMakefile.h" +#include "cmSourceFile.h" +#include <cmsys/FStream.hxx> + +#include <assert.h> + +cmGeneratorExpressionEvaluationFile::cmGeneratorExpressionEvaluationFile( + const std::string& input, + CM_AUTO_PTR<cmCompiledGeneratorExpression> outputFileExpr, + CM_AUTO_PTR<cmCompiledGeneratorExpression> condition, bool inputIsContent) + : Input(input) + , OutputFileExpr(outputFileExpr) + , Condition(condition) + , InputIsContent(inputIsContent) +{ +} + +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(); + if (!rawCondition.empty()) { + std::string condResult = this->Condition->Evaluate( + lg, config, false, CM_NULLPTR, CM_NULLPTR, CM_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(cmake::FATAL_ERROR, e.str()); + return; + } + } + + const std::string outputFileName = this->OutputFileExpr->Evaluate( + lg, config, false, CM_NULLPTR, CM_NULLPTR, CM_NULLPTR, lang); + const std::string outputContent = inputExpression->Evaluate( + lg, config, false, CM_NULLPTR, CM_NULLPTR, CM_NULLPTR, lang); + + std::map<std::string, std::string>::iterator it = + outputFiles.find(outputFileName); + + if (it != outputFiles.end()) { + if (it->second == outputContent) { + return; + } + std::ostringstream e; + e << "Evaluation file to be written multiple times for different " + "configurations or languages with different content:\n " + << outputFileName; + lg->IssueMessage(cmake::FATAL_ERROR, e.str()); + return; + } + + lg->GetMakefile()->AddCMakeOutputFile(outputFileName); + this->Files.push_back(outputFileName); + outputFiles[outputFileName] = outputContent; + + cmGeneratedFileStream fout(outputFileName.c_str()); + 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(); + gg->GetEnabledLanguages(enabledLanguages); + + for (std::vector<std::string>::const_iterator le = enabledLanguages.begin(); + le != enabledLanguages.end(); ++le) { + std::string name = this->OutputFileExpr->Evaluate( + lg, config, false, CM_NULLPTR, CM_NULLPTR, CM_NULLPTR, *le); + cmSourceFile* sf = lg->GetMakefile()->GetOrCreateSource(name); + sf->SetProperty("GENERATED", "1"); + + gg->SetFilenameTargetDepends( + sf, this->OutputFileExpr->GetSourceSensitiveTargets()); + } +} + +void cmGeneratorExpressionEvaluationFile::Generate(cmLocalGenerator* lg) +{ + mode_t perm = 0; + std::string inputContent; + if (this->InputIsContent) { + inputContent = this->Input; + } else { + lg->GetMakefile()->AddCMakeDependFile(this->Input); + cmSystemTools::GetPermissions(this->Input.c_str(), perm); + cmsys::ifstream fin(this->Input.c_str()); + if (!fin) { + std::ostringstream e; + e << "Evaluation file \"" << this->Input << "\" cannot be read."; + lg->IssueMessage(cmake::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); + CM_AUTO_PTR<cmCompiledGeneratorExpression> inputExpression = + contentGE.Parse(inputContent); + + std::map<std::string, std::string> outputFiles; + + std::vector<std::string> allConfigs; + lg->GetMakefile()->GetConfigurations(allConfigs); + + if (allConfigs.empty()) { + allConfigs.push_back(""); + } + + std::vector<std::string> enabledLanguages; + cmGlobalGenerator* gg = lg->GetGlobalGenerator(); + gg->GetEnabledLanguages(enabledLanguages); + + for (std::vector<std::string>::const_iterator le = enabledLanguages.begin(); + le != enabledLanguages.end(); ++le) { + for (std::vector<std::string>::const_iterator li = allConfigs.begin(); + li != allConfigs.end(); ++li) { + this->Generate(lg, *li, *le, inputExpression.get(), outputFiles, perm); + if (cmSystemTools::GetFatalErrorOccured()) { + return; + } + } + } +} |