file: Add GENERATE command to produce files at generate time
The idea is to write to a temp file which contains generator expressions, and at generate time, evaluate the generator expressions, and write the result to a file. Because executables on Windows are limited in the length of command line it is possible to use, it is common to write command line arguments to a file instead and specify the file as a source of arguments. This new FILE(GENERATE) subcommand allows the use of generator expressions to create such files so that they can be used with add_custom_command for example.
This commit is contained in:
parent
272431a84f
commit
b983a58bdf
|
@ -52,6 +52,7 @@
|
||||||
#include "cmFindProgramCommand.cxx"
|
#include "cmFindProgramCommand.cxx"
|
||||||
#include "cmForEachCommand.cxx"
|
#include "cmForEachCommand.cxx"
|
||||||
#include "cmFunctionCommand.cxx"
|
#include "cmFunctionCommand.cxx"
|
||||||
|
#include "cmGeneratorExpressionEvaluationFile.cxx"
|
||||||
#include "cmGetCMakePropertyCommand.cxx"
|
#include "cmGetCMakePropertyCommand.cxx"
|
||||||
#include "cmGetDirectoryPropertyCommand.cxx"
|
#include "cmGetDirectoryPropertyCommand.cxx"
|
||||||
#include "cmGetFilenameComponentCommand.cxx"
|
#include "cmGetFilenameComponentCommand.cxx"
|
||||||
|
|
|
@ -167,6 +167,10 @@ bool cmFileCommand
|
||||||
{
|
{
|
||||||
return this->HandleTimestampCommand(args);
|
return this->HandleTimestampCommand(args);
|
||||||
}
|
}
|
||||||
|
else if ( subCommand == "GENERATE" )
|
||||||
|
{
|
||||||
|
return this->HandleGenerateCommand(args);
|
||||||
|
}
|
||||||
|
|
||||||
std::string e = "does not recognize sub-command "+subCommand;
|
std::string e = "does not recognize sub-command "+subCommand;
|
||||||
this->SetError(e.c_str());
|
this->SetError(e.c_str());
|
||||||
|
@ -3249,6 +3253,80 @@ cmFileCommand::HandleUploadCommand(std::vector<std::string> const& args)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void cmFileCommand::AddEvaluationFile(const std::string &inputName,
|
||||||
|
const std::string &outputExpr,
|
||||||
|
const std::string &condition,
|
||||||
|
bool inputIsContent
|
||||||
|
)
|
||||||
|
{
|
||||||
|
cmListFileBacktrace lfbt;
|
||||||
|
this->Makefile->GetBacktrace(lfbt);
|
||||||
|
|
||||||
|
cmGeneratorExpression outputGe(lfbt);
|
||||||
|
cmsys::auto_ptr<cmCompiledGeneratorExpression> outputCge
|
||||||
|
= outputGe.Parse(outputExpr);
|
||||||
|
|
||||||
|
cmGeneratorExpression conditionGe(lfbt);
|
||||||
|
cmsys::auto_ptr<cmCompiledGeneratorExpression> conditionCge
|
||||||
|
= conditionGe.Parse(condition);
|
||||||
|
|
||||||
|
this->Makefile->GetLocalGenerator()
|
||||||
|
->GetGlobalGenerator()->AddEvaluationFile(inputName,
|
||||||
|
outputCge,
|
||||||
|
this->Makefile,
|
||||||
|
conditionCge,
|
||||||
|
inputIsContent);
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool cmFileCommand::HandleGenerateCommand(
|
||||||
|
std::vector<std::string> const& args)
|
||||||
|
{
|
||||||
|
if (args.size() < 5)
|
||||||
|
{
|
||||||
|
this->SetError("Incorrect arguments to GENERATE subcommand.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (args[1] != "OUTPUT")
|
||||||
|
{
|
||||||
|
this->SetError("Incorrect arguments to GENERATE subcommand.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
std::string condition;
|
||||||
|
if (args.size() > 5)
|
||||||
|
{
|
||||||
|
if (args[5] != "CONDITION")
|
||||||
|
{
|
||||||
|
this->SetError("Incorrect arguments to GENERATE subcommand.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (args.size() != 7)
|
||||||
|
{
|
||||||
|
this->SetError("Incorrect arguments to GENERATE subcommand.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
condition = args[6];
|
||||||
|
if (condition.empty())
|
||||||
|
{
|
||||||
|
this->SetError("CONDITION of sub-command GENERATE must not be empty if "
|
||||||
|
"specified.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::string output = args[2];
|
||||||
|
const bool inputIsContent = args[3] != "INPUT";
|
||||||
|
if (inputIsContent && args[3] != "CONTENT")
|
||||||
|
{
|
||||||
|
this->SetError("Incorrect arguments to GENERATE subcommand.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
std::string input = args[4];
|
||||||
|
|
||||||
|
this->AddEvaluationFile(input, output, condition, inputIsContent);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool cmFileCommand::HandleTimestampCommand(
|
bool cmFileCommand::HandleTimestampCommand(
|
||||||
std::vector<std::string> const& args)
|
std::vector<std::string> const& args)
|
||||||
|
|
|
@ -88,6 +88,9 @@ public:
|
||||||
" file(UPLOAD filename url [INACTIVITY_TIMEOUT timeout]\n"
|
" file(UPLOAD filename url [INACTIVITY_TIMEOUT timeout]\n"
|
||||||
" [TIMEOUT timeout] [STATUS status] [LOG log] [SHOW_PROGRESS])\n"
|
" [TIMEOUT timeout] [STATUS status] [LOG log] [SHOW_PROGRESS])\n"
|
||||||
" file(TIMESTAMP filename variable [<format string>] [UTC])\n"
|
" file(TIMESTAMP filename variable [<format string>] [UTC])\n"
|
||||||
|
" file(GENERATE OUTPUT output_file\n"
|
||||||
|
" <INPUT input_file|CONTENT input_content>\n"
|
||||||
|
" CONDITION expression)\n"
|
||||||
"WRITE will write a message into a file called 'filename'. It "
|
"WRITE will write a message into a file called 'filename'. It "
|
||||||
"overwrites the file if it already exists, and creates the file "
|
"overwrites the file if it already exists, and creates the file "
|
||||||
"if it does not exist. (If the file is a build input, use "
|
"if it does not exist. (If the file is a build input, use "
|
||||||
|
@ -231,6 +234,15 @@ public:
|
||||||
"it prints status messages, and NO_SOURCE_PERMISSIONS is default. "
|
"it prints status messages, and NO_SOURCE_PERMISSIONS is default. "
|
||||||
"Installation scripts generated by the install() command use this "
|
"Installation scripts generated by the install() command use this "
|
||||||
"signature (with some undocumented options for internal use)."
|
"signature (with some undocumented options for internal use)."
|
||||||
|
"\n"
|
||||||
|
"GENERATE will write an <output_file> with content from an "
|
||||||
|
"<input_file>, or from <input_content>. The output is generated "
|
||||||
|
"conditionally based on the content of the <condition>. The file is "
|
||||||
|
"written at CMake generate-time and the input may contain generator "
|
||||||
|
"expressions. The <condition>, <output_file> and <input_file> may "
|
||||||
|
"also contain generator expressions. The <condition> must evaluate to "
|
||||||
|
"either '0' or '1'. The <output_file> must evaluate to a unique name "
|
||||||
|
"among all configurations and among all invocations of file(GENERATE)."
|
||||||
// Undocumented INSTALL options:
|
// Undocumented INSTALL options:
|
||||||
// - RENAME <name>
|
// - RENAME <name>
|
||||||
// - OPTIONAL
|
// - OPTIONAL
|
||||||
|
@ -269,6 +281,13 @@ protected:
|
||||||
bool HandleUploadCommand(std::vector<std::string> const& args);
|
bool HandleUploadCommand(std::vector<std::string> const& args);
|
||||||
|
|
||||||
bool HandleTimestampCommand(std::vector<std::string> const& args);
|
bool HandleTimestampCommand(std::vector<std::string> const& args);
|
||||||
|
bool HandleGenerateCommand(std::vector<std::string> const& args);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void AddEvaluationFile(const std::string &inputName,
|
||||||
|
const std::string &outputExpr,
|
||||||
|
const std::string &condition,
|
||||||
|
bool inputIsContent);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,151 @@
|
||||||
|
/*============================================================================
|
||||||
|
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 "cmMakefile.h"
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
cmGeneratorExpressionEvaluationFile::cmGeneratorExpressionEvaluationFile(
|
||||||
|
const std::string &input,
|
||||||
|
cmsys::auto_ptr<cmCompiledGeneratorExpression> outputFileExpr,
|
||||||
|
cmMakefile *makefile,
|
||||||
|
cmsys::auto_ptr<cmCompiledGeneratorExpression> condition,
|
||||||
|
bool inputIsContent)
|
||||||
|
: Input(input),
|
||||||
|
OutputFileExpr(outputFileExpr),
|
||||||
|
Makefile(makefile),
|
||||||
|
Condition(condition),
|
||||||
|
InputIsContent(inputIsContent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void cmGeneratorExpressionEvaluationFile::Generate(const char *config,
|
||||||
|
cmCompiledGeneratorExpression* inputExpression,
|
||||||
|
std::map<std::string, std::string> &outputFiles)
|
||||||
|
{
|
||||||
|
std::string rawCondition = this->Condition->GetInput();
|
||||||
|
if (!rawCondition.empty())
|
||||||
|
{
|
||||||
|
std::string condResult = this->Condition->Evaluate(this->Makefile, config);
|
||||||
|
if (condResult == "0")
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (condResult != "1")
|
||||||
|
{
|
||||||
|
cmOStringStream e;
|
||||||
|
e << "Evaluation file condition \"" << rawCondition << "\" did "
|
||||||
|
"not evaluate to valid content. Got \"" << condResult << "\".";
|
||||||
|
this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str().c_str());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string outputFileName
|
||||||
|
= this->OutputFileExpr->Evaluate(this->Makefile, config);
|
||||||
|
const std::string outputContent
|
||||||
|
= inputExpression->Evaluate(this->Makefile, config);
|
||||||
|
|
||||||
|
std::map<std::string, std::string>::iterator it
|
||||||
|
= outputFiles.find(outputFileName);
|
||||||
|
|
||||||
|
if(it != outputFiles.end())
|
||||||
|
{
|
||||||
|
if (it->second == outputContent)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
cmOStringStream e;
|
||||||
|
e << "Evaluation file to be written multiple times for different "
|
||||||
|
"configurations with different content:\n " << outputFileName;
|
||||||
|
this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str().c_str());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->Files.push_back(outputFileName);
|
||||||
|
outputFiles[outputFileName] = outputContent;
|
||||||
|
|
||||||
|
std::ofstream fout(outputFileName.c_str());
|
||||||
|
|
||||||
|
if(!fout)
|
||||||
|
{
|
||||||
|
cmOStringStream e;
|
||||||
|
e << "Evaluation file \"" << outputFileName << "\" cannot be written.";
|
||||||
|
this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str().c_str());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fout << outputContent;
|
||||||
|
|
||||||
|
fout.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void cmGeneratorExpressionEvaluationFile::Generate()
|
||||||
|
{
|
||||||
|
std::string inputContent;
|
||||||
|
if (this->InputIsContent)
|
||||||
|
{
|
||||||
|
inputContent = this->Input;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::ifstream fin(this->Input.c_str());
|
||||||
|
if(!fin)
|
||||||
|
{
|
||||||
|
cmOStringStream e;
|
||||||
|
e << "Evaluation file \"" << this->Input << "\" cannot be read.";
|
||||||
|
this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str().c_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);
|
||||||
|
cmsys::auto_ptr<cmCompiledGeneratorExpression> inputExpression
|
||||||
|
= contentGE.Parse(inputContent);
|
||||||
|
|
||||||
|
std::map<std::string, std::string> outputFiles;
|
||||||
|
|
||||||
|
std::vector<std::string> allConfigs;
|
||||||
|
this->Makefile->GetConfigurations(allConfigs);
|
||||||
|
|
||||||
|
if (allConfigs.empty())
|
||||||
|
{
|
||||||
|
this->Generate(0, inputExpression.get(), outputFiles);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for(std::vector<std::string>::const_iterator li = allConfigs.begin();
|
||||||
|
li != allConfigs.end(); ++li)
|
||||||
|
{
|
||||||
|
this->Generate(li->c_str(), inputExpression.get(), outputFiles);
|
||||||
|
if(cmSystemTools::GetFatalErrorOccured())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
/*============================================================================
|
||||||
|
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.
|
||||||
|
============================================================================*/
|
||||||
|
#ifndef cmGeneratorExpressionEvaluationFile_h
|
||||||
|
#define cmGeneratorExpressionEvaluationFile_h
|
||||||
|
|
||||||
|
#include "cmStandardIncludes.h"
|
||||||
|
#include <cmsys/auto_ptr.hxx>
|
||||||
|
|
||||||
|
#include "cmGeneratorExpression.h"
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
class cmGeneratorExpressionEvaluationFile
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
cmGeneratorExpressionEvaluationFile(const std::string &input,
|
||||||
|
cmsys::auto_ptr<cmCompiledGeneratorExpression> outputFileExpr,
|
||||||
|
cmMakefile *makefile,
|
||||||
|
cmsys::auto_ptr<cmCompiledGeneratorExpression> condition,
|
||||||
|
bool inputIsContent);
|
||||||
|
|
||||||
|
void Generate();
|
||||||
|
|
||||||
|
std::vector<std::string> GetFiles() const { return this->Files; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
void Generate(const char *config,
|
||||||
|
cmCompiledGeneratorExpression* inputExpression,
|
||||||
|
std::map<std::string, std::string> &outputFiles);
|
||||||
|
|
||||||
|
private:
|
||||||
|
const std::string Input;
|
||||||
|
const cmsys::auto_ptr<cmCompiledGeneratorExpression> OutputFileExpr;
|
||||||
|
cmMakefile *Makefile;
|
||||||
|
const cmsys::auto_ptr<cmCompiledGeneratorExpression> Condition;
|
||||||
|
std::vector<std::string> Files;
|
||||||
|
const bool InputIsContent;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -26,6 +26,7 @@
|
||||||
#include "cmGeneratedFileStream.h"
|
#include "cmGeneratedFileStream.h"
|
||||||
#include "cmGeneratorTarget.h"
|
#include "cmGeneratorTarget.h"
|
||||||
#include "cmGeneratorExpression.h"
|
#include "cmGeneratorExpression.h"
|
||||||
|
#include "cmGeneratorExpressionEvaluationFile.h"
|
||||||
|
|
||||||
#include <cmsys/Directory.hxx>
|
#include <cmsys/Directory.hxx>
|
||||||
|
|
||||||
|
@ -69,6 +70,13 @@ cmGlobalGenerator::~cmGlobalGenerator()
|
||||||
{
|
{
|
||||||
delete this->LocalGenerators[i];
|
delete this->LocalGenerators[i];
|
||||||
}
|
}
|
||||||
|
for(std::vector<cmGeneratorExpressionEvaluationFile*>::const_iterator
|
||||||
|
li = this->EvaluationFiles.begin();
|
||||||
|
li != this->EvaluationFiles.end();
|
||||||
|
++li)
|
||||||
|
{
|
||||||
|
delete *li;
|
||||||
|
}
|
||||||
this->LocalGenerators.clear();
|
this->LocalGenerators.clear();
|
||||||
|
|
||||||
if (this->ExtraGenerator)
|
if (this->ExtraGenerator)
|
||||||
|
@ -981,6 +989,8 @@ void cmGlobalGenerator::Generate()
|
||||||
// Create per-target generator information.
|
// Create per-target generator information.
|
||||||
this->CreateGeneratorTargets();
|
this->CreateGeneratorTargets();
|
||||||
|
|
||||||
|
this->ProcessEvaluationFiles();
|
||||||
|
|
||||||
// Compute the inter-target dependencies.
|
// Compute the inter-target dependencies.
|
||||||
if(!this->ComputeTargetDepends())
|
if(!this->ComputeTargetDepends())
|
||||||
{
|
{
|
||||||
|
@ -2558,3 +2568,44 @@ std::string cmGlobalGenerator::EscapeJSON(const std::string& s) {
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void cmGlobalGenerator::AddEvaluationFile(const std::string &inputFile,
|
||||||
|
cmsys::auto_ptr<cmCompiledGeneratorExpression> outputExpr,
|
||||||
|
cmMakefile *makefile,
|
||||||
|
cmsys::auto_ptr<cmCompiledGeneratorExpression> condition,
|
||||||
|
bool inputIsContent)
|
||||||
|
{
|
||||||
|
this->EvaluationFiles.push_back(
|
||||||
|
new cmGeneratorExpressionEvaluationFile(inputFile, outputExpr,
|
||||||
|
makefile, condition,
|
||||||
|
inputIsContent));
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void cmGlobalGenerator::ProcessEvaluationFiles()
|
||||||
|
{
|
||||||
|
std::set<std::string> generatedFiles;
|
||||||
|
for(std::vector<cmGeneratorExpressionEvaluationFile*>::const_iterator
|
||||||
|
li = this->EvaluationFiles.begin();
|
||||||
|
li != this->EvaluationFiles.end();
|
||||||
|
++li)
|
||||||
|
{
|
||||||
|
(*li)->Generate();
|
||||||
|
if (cmSystemTools::GetFatalErrorOccured())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
std::vector<std::string> files = (*li)->GetFiles();
|
||||||
|
for(std::vector<std::string>::const_iterator fi = files.begin();
|
||||||
|
fi != files.end(); ++fi)
|
||||||
|
{
|
||||||
|
if (!generatedFiles.insert(*fi).second)
|
||||||
|
{
|
||||||
|
cmSystemTools::Error("File to be generated by multiple different "
|
||||||
|
"commands: ", fi->c_str());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -20,9 +20,11 @@
|
||||||
#include "cmSystemTools.h" // for cmSystemTools::OutputOption
|
#include "cmSystemTools.h" // for cmSystemTools::OutputOption
|
||||||
#include "cmExportSetMap.h" // For cmExportSetMap
|
#include "cmExportSetMap.h" // For cmExportSetMap
|
||||||
#include "cmGeneratorTarget.h"
|
#include "cmGeneratorTarget.h"
|
||||||
|
#include "cmGeneratorExpression.h"
|
||||||
|
|
||||||
class cmake;
|
class cmake;
|
||||||
class cmGeneratorTarget;
|
class cmGeneratorTarget;
|
||||||
|
class cmGeneratorExpressionEvaluationFile;
|
||||||
class cmMakefile;
|
class cmMakefile;
|
||||||
class cmLocalGenerator;
|
class cmLocalGenerator;
|
||||||
class cmExternalMakefileProjectGenerator;
|
class cmExternalMakefileProjectGenerator;
|
||||||
|
@ -278,6 +280,14 @@ public:
|
||||||
|
|
||||||
static std::string EscapeJSON(const std::string& s);
|
static std::string EscapeJSON(const std::string& s);
|
||||||
|
|
||||||
|
void AddEvaluationFile(const std::string &inputFile,
|
||||||
|
cmsys::auto_ptr<cmCompiledGeneratorExpression> outputName,
|
||||||
|
cmMakefile *makefile,
|
||||||
|
cmsys::auto_ptr<cmCompiledGeneratorExpression> condition,
|
||||||
|
bool inputIsContent);
|
||||||
|
|
||||||
|
void ProcessEvaluationFiles();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
typedef std::vector<cmLocalGenerator*> GeneratorVector;
|
typedef std::vector<cmLocalGenerator*> GeneratorVector;
|
||||||
// for a project collect all its targets by following depend
|
// for a project collect all its targets by following depend
|
||||||
|
@ -337,6 +347,7 @@ protected:
|
||||||
// All targets in the entire project.
|
// All targets in the entire project.
|
||||||
std::map<cmStdString,cmTarget *> TotalTargets;
|
std::map<cmStdString,cmTarget *> TotalTargets;
|
||||||
std::map<cmStdString,cmTarget *> ImportedTargets;
|
std::map<cmStdString,cmTarget *> ImportedTargets;
|
||||||
|
std::vector<cmGeneratorExpressionEvaluationFile*> EvaluationFiles;
|
||||||
|
|
||||||
virtual const char* GetPredefinedTargetsFolder();
|
virtual const char* GetPredefinedTargetsFolder();
|
||||||
virtual bool UseFolderProperty();
|
virtual bool UseFolderProperty();
|
||||||
|
|
|
@ -86,3 +86,5 @@ if("${CMAKE_TEST_GENERATOR}" MATCHES "Visual Studio [^6]")
|
||||||
add_RunCMake_test(include_external_msproject)
|
add_RunCMake_test(include_external_msproject)
|
||||||
add_RunCMake_test(SolutionGlobalSections)
|
add_RunCMake_test(SolutionGlobalSections)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
add_RunCMake_test(File_Generate)
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
1
|
|
@ -0,0 +1,3 @@
|
||||||
|
CMake Error in CMakeLists.txt:
|
||||||
|
Evaluation file condition \"\$<1:Bad>\" did not evaluate to valid content.
|
||||||
|
Got \"Bad\".
|
|
@ -0,0 +1,5 @@
|
||||||
|
|
||||||
|
file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/output.txt"
|
||||||
|
INPUT "${CMAKE_CURRENT_SOURCE_DIR}/input.txt"
|
||||||
|
CONDITION $<1:Bad>
|
||||||
|
)
|
|
@ -0,0 +1,3 @@
|
||||||
|
cmake_minimum_required(VERSION 2.8)
|
||||||
|
project(${RunCMake_TEST} NONE)
|
||||||
|
include(${RunCMake_TEST}.cmake)
|
|
@ -0,0 +1 @@
|
||||||
|
1
|
|
@ -0,0 +1 @@
|
||||||
|
CMake Error: File to be generated by multiple different commands: .*CommandConflict-build/output_.*.txt
|
|
@ -0,0 +1,9 @@
|
||||||
|
|
||||||
|
file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/output_$<CONFIGURATION>.txt"
|
||||||
|
INPUT "${CMAKE_CURRENT_SOURCE_DIR}/input.txt"
|
||||||
|
CONDITION $<CONFIG:$<CONFIGURATION>>
|
||||||
|
)
|
||||||
|
file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/output_$<CONFIGURATION>.txt"
|
||||||
|
INPUT "${CMAKE_CURRENT_SOURCE_DIR}/input.txt"
|
||||||
|
CONDITION $<CONFIG:$<CONFIGURATION>>
|
||||||
|
)
|
|
@ -0,0 +1,5 @@
|
||||||
|
|
||||||
|
file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/output.txt"
|
||||||
|
INPUT "${CMAKE_CURRENT_SOURCE_DIR}/input.txt"
|
||||||
|
CONDITION $<CONFIG:Debug>
|
||||||
|
)
|
|
@ -0,0 +1 @@
|
||||||
|
1
|
|
@ -0,0 +1,4 @@
|
||||||
|
CMake Error at EmptyCondition1.cmake:2 \(file\):
|
||||||
|
file Incorrect arguments to GENERATE subcommand.
|
||||||
|
Call Stack \(most recent call first\):
|
||||||
|
CMakeLists.txt:3 \(include\)
|
|
@ -0,0 +1,5 @@
|
||||||
|
|
||||||
|
file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/output.txt"
|
||||||
|
INPUT "${CMAKE_CURRENT_SOURCE_DIR}/input.txt"
|
||||||
|
CONDITION
|
||||||
|
)
|
|
@ -0,0 +1 @@
|
||||||
|
1
|
|
@ -0,0 +1,4 @@
|
||||||
|
CMake Error at EmptyCondition2.cmake:2 \(file\):
|
||||||
|
file CONDITION of sub-command GENERATE must not be empty if specified.
|
||||||
|
Call Stack \(most recent call first\):
|
||||||
|
CMakeLists.txt:3 \(include\)
|
|
@ -0,0 +1,5 @@
|
||||||
|
|
||||||
|
file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/output.txt"
|
||||||
|
INPUT "${CMAKE_CURRENT_SOURCE_DIR}/input.txt"
|
||||||
|
CONDITION ""
|
||||||
|
)
|
|
@ -0,0 +1 @@
|
||||||
|
1
|
|
@ -0,0 +1,5 @@
|
||||||
|
CMake Error in CMakeLists.txt:
|
||||||
|
Evaluation file to be written multiple times for different configurations
|
||||||
|
with different content:
|
||||||
|
|
||||||
|
.*output.txt
|
|
@ -0,0 +1,4 @@
|
||||||
|
|
||||||
|
file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/output.txt"
|
||||||
|
INPUT "${CMAKE_CURRENT_SOURCE_DIR}/input.txt"
|
||||||
|
)
|
|
@ -0,0 +1,10 @@
|
||||||
|
include(RunCMake)
|
||||||
|
|
||||||
|
run_cmake(CommandConflict)
|
||||||
|
if("${RunCMake_GENERATOR}" MATCHES "Visual Studio" OR "${RunCMake_GENERATOR}" MATCHES "XCode" )
|
||||||
|
run_cmake(OutputConflict)
|
||||||
|
endif()
|
||||||
|
run_cmake(EmptyCondition1)
|
||||||
|
run_cmake(EmptyCondition2)
|
||||||
|
run_cmake(BadCondition)
|
||||||
|
run_cmake(DebugEvaluate)
|
|
@ -0,0 +1 @@
|
||||||
|
Some $<$<CONFIG:Debug>:conflicting> $<$<NOT:$<CONFIG:Debug>>:content>
|
Loading…
Reference in New Issue