cmake/Source/cmGeneratorExpressionEvaluationFile.cxx

162 lines
5.1 KiB
C++
Raw Normal View History

2016-10-30 18:24:19 +01:00
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
2013-11-03 12:27:13 +02:00
#include "cmGeneratorExpressionEvaluationFile.h"
2017-07-20 19:35:53 +02:00
#include "cmConfigure.h"
#include "cmsys/FStream.hxx"
2017-04-14 19:02:05 +02:00
#include <sstream>
#include <utility>
2016-07-09 11:21:54 +02:00
#include "cmGeneratedFileStream.h"
2015-04-27 22:25:09 +02:00
#include "cmGlobalGenerator.h"
2016-10-30 18:24:19 +01:00
#include "cmListFileCache.h"
2016-07-09 11:21:54 +02:00
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
2015-04-27 22:25:09 +02:00
#include "cmSourceFile.h"
2016-10-30 18:24:19 +01:00
#include "cmSystemTools.h"
2017-04-14 19:02:05 +02:00
#include "cm_auto_ptr.hxx"
2016-10-30 18:24:19 +01:00
#include "cmake.h"
2013-11-03 12:27:13 +02:00
cmGeneratorExpressionEvaluationFile::cmGeneratorExpressionEvaluationFile(
2016-07-09 11:21:54 +02:00
const std::string& input,
2016-10-30 18:24:19 +01:00
CM_AUTO_PTR<cmCompiledGeneratorExpression> outputFileExpr,
CM_AUTO_PTR<cmCompiledGeneratorExpression> condition, bool inputIsContent)
2016-07-09 11:21:54 +02:00
: Input(input)
, OutputFileExpr(outputFileExpr)
, Condition(condition)
, InputIsContent(inputIsContent)
2013-11-03 12:27:13 +02:00
{
}
2016-07-09 11:21:54 +02:00
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)
2013-11-03 12:27:13 +02:00
{
std::string rawCondition = this->Condition->GetInput();
2016-07-09 11:21:54 +02:00
if (!rawCondition.empty()) {
2016-10-30 18:24:19 +01:00
std::string condResult = this->Condition->Evaluate(
lg, config, false, CM_NULLPTR, CM_NULLPTR, CM_NULLPTR, lang);
2016-07-09 11:21:54 +02:00
if (condResult == "0") {
2013-11-03 12:27:13 +02:00
return;
2016-07-09 11:21:54 +02:00
}
if (condResult != "1") {
2015-04-27 22:25:09 +02:00
std::ostringstream e;
2016-07-09 11:21:54 +02:00
e << "Evaluation file condition \"" << rawCondition
<< "\" did "
"not evaluate to valid content. Got \""
<< condResult << "\".";
2015-11-17 17:22:37 +01:00
lg->IssueMessage(cmake::FATAL_ERROR, e.str());
2013-11-03 12:27:13 +02:00
return;
}
2016-07-09 11:21:54 +02:00
}
2013-11-03 12:27:13 +02:00
2016-10-30 18:24:19 +01:00
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);
2016-07-09 11:21:54 +02:00
std::map<std::string, std::string>::iterator it =
outputFiles.find(outputFileName);
if (it != outputFiles.end()) {
if (it->second == outputContent) {
2013-11-03 12:27:13 +02:00
return;
2016-07-09 11:21:54 +02:00
}
2015-04-27 22:25:09 +02:00
std::ostringstream e;
2017-07-20 19:35:53 +02:00
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 "
2015-08-17 11:37:30 +02:00
<< outputFileName;
2015-11-17 17:22:37 +01:00
lg->IssueMessage(cmake::FATAL_ERROR, e.str());
2013-11-03 12:27:13 +02:00
return;
2016-07-09 11:21:54 +02:00
}
2013-11-03 12:27:13 +02:00
2016-07-09 11:21:54 +02:00
lg->GetMakefile()->AddCMakeOutputFile(outputFileName);
2013-11-03 12:27:13 +02:00
this->Files.push_back(outputFileName);
outputFiles[outputFileName] = outputContent;
2015-04-27 22:25:09 +02:00
cmGeneratedFileStream fout(outputFileName.c_str());
fout.SetCopyIfDifferent(true);
fout << outputContent;
2016-07-09 11:21:54 +02:00
if (fout.Close() && perm) {
2015-04-27 22:25:09 +02:00
cmSystemTools::SetPermissions(outputFileName.c_str(), perm);
2016-07-09 11:21:54 +02:00
}
2015-04-27 22:25:09 +02:00
}
2013-11-03 12:27:13 +02:00
2015-04-27 22:25:09 +02:00
void cmGeneratorExpressionEvaluationFile::CreateOutputFile(
2016-07-09 11:21:54 +02:00
cmLocalGenerator* lg, std::string const& config)
2015-04-27 22:25:09 +02:00
{
2015-08-17 11:37:30 +02:00
std::vector<std::string> enabledLanguages;
2016-07-09 11:21:54 +02:00
cmGlobalGenerator* gg = lg->GetGlobalGenerator();
2015-08-17 11:37:30 +02:00
gg->GetEnabledLanguages(enabledLanguages);
2015-04-27 22:25:09 +02:00
2016-07-09 11:21:54 +02:00
for (std::vector<std::string>::const_iterator le = enabledLanguages.begin();
le != enabledLanguages.end(); ++le) {
2016-10-30 18:24:19 +01:00
std::string name = this->OutputFileExpr->Evaluate(
lg, config, false, CM_NULLPTR, CM_NULLPTR, CM_NULLPTR, *le);
2015-11-17 17:22:37 +01:00
cmSourceFile* sf = lg->GetMakefile()->GetOrCreateSource(name);
2015-08-17 11:37:30 +02:00
sf->SetProperty("GENERATED", "1");
2016-07-09 11:21:54 +02:00
gg->SetFilenameTargetDepends(
sf, this->OutputFileExpr->GetSourceSensitiveTargets());
}
2013-11-03 12:27:13 +02:00
}
2016-07-09 11:21:54 +02:00
void cmGeneratorExpressionEvaluationFile::Generate(cmLocalGenerator* lg)
2013-11-03 12:27:13 +02:00
{
2015-04-27 22:25:09 +02:00
mode_t perm = 0;
2013-11-03 12:27:13 +02:00
std::string inputContent;
2016-07-09 11:21:54 +02:00
if (this->InputIsContent) {
2013-11-03 12:27:13 +02:00
inputContent = this->Input;
2016-07-09 11:21:54 +02:00
} else {
lg->GetMakefile()->AddCMakeDependFile(this->Input);
2015-04-27 22:25:09 +02:00
cmSystemTools::GetPermissions(this->Input.c_str(), perm);
2014-08-03 19:52:23 +02:00
cmsys::ifstream fin(this->Input.c_str());
2016-07-09 11:21:54 +02:00
if (!fin) {
2015-04-27 22:25:09 +02:00
std::ostringstream e;
2013-11-03 12:27:13 +02:00
e << "Evaluation file \"" << this->Input << "\" cannot be read.";
2016-03-13 13:35:51 +01:00
lg->IssueMessage(cmake::FATAL_ERROR, e.str());
2013-11-03 12:27:13 +02:00
return;
2016-07-09 11:21:54 +02:00
}
2013-11-03 12:27:13 +02:00
std::string line;
std::string sep;
2016-07-09 11:21:54 +02:00
while (cmSystemTools::GetLineFromStream(fin, line)) {
2013-11-03 12:27:13 +02:00
inputContent += sep + line;
sep = "\n";
}
2016-07-09 11:21:54 +02:00
inputContent += sep;
}
2013-11-03 12:27:13 +02:00
cmListFileBacktrace lfbt = this->OutputFileExpr->GetBacktrace();
2015-11-17 17:22:37 +01:00
cmGeneratorExpression contentGE(lfbt);
2016-10-30 18:24:19 +01:00
CM_AUTO_PTR<cmCompiledGeneratorExpression> inputExpression =
2016-07-09 11:21:54 +02:00
contentGE.Parse(inputContent);
2013-11-03 12:27:13 +02:00
std::map<std::string, std::string> outputFiles;
std::vector<std::string> allConfigs;
2015-11-17 17:22:37 +01:00
lg->GetMakefile()->GetConfigurations(allConfigs);
2013-11-03 12:27:13 +02:00
2016-07-09 11:21:54 +02:00
if (allConfigs.empty()) {
2015-04-27 22:25:09 +02:00
allConfigs.push_back("");
2016-07-09 11:21:54 +02:00
}
2015-08-17 11:37:30 +02:00
std::vector<std::string> enabledLanguages;
2016-07-09 11:21:54 +02:00
cmGlobalGenerator* gg = lg->GetGlobalGenerator();
2015-08-17 11:37:30 +02:00
gg->GetEnabledLanguages(enabledLanguages);
2016-07-09 11:21:54 +02:00
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) {
2015-11-17 17:22:37 +01:00
this->Generate(lg, *li, *le, inputExpression.get(), outputFiles, perm);
2016-07-09 11:21:54 +02:00
if (cmSystemTools::GetFatalErrorOccured()) {
2015-08-17 11:37:30 +02:00
return;
2013-11-03 12:27:13 +02:00
}
}
2016-07-09 11:21:54 +02:00
}
2013-11-03 12:27:13 +02:00
}