BUG: Fixes to VS8/VS9 project regeneration rules
- ZERO_CHECK should check all stamps in case of parallel build (fixes complex test failure) - ZERO_CHECK should not appear when CMAKE_SUPPRESS_REGENERATION is on (fixes bug 6490)
This commit is contained in:
parent
b5cebc00f7
commit
fdf169be3a
|
@ -19,6 +19,7 @@
|
||||||
#include "cmLocalVisualStudio7Generator.h"
|
#include "cmLocalVisualStudio7Generator.h"
|
||||||
#include "cmMakefile.h"
|
#include "cmMakefile.h"
|
||||||
#include "cmake.h"
|
#include "cmake.h"
|
||||||
|
#include "cmGeneratedFileStream.h"
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
cmGlobalVisualStudio8Generator::cmGlobalVisualStudio8Generator()
|
cmGlobalVisualStudio8Generator::cmGlobalVisualStudio8Generator()
|
||||||
|
@ -131,6 +132,13 @@ void cmGlobalVisualStudio8Generator::Generate()
|
||||||
cmLocalVisualStudio7Generator* lg =
|
cmLocalVisualStudio7Generator* lg =
|
||||||
static_cast<cmLocalVisualStudio7Generator*>(generators[0]);
|
static_cast<cmLocalVisualStudio7Generator*>(generators[0]);
|
||||||
cmMakefile* mf = lg->GetMakefile();
|
cmMakefile* mf = lg->GetMakefile();
|
||||||
|
|
||||||
|
// Skip the target if no regeneration is to be done.
|
||||||
|
if(mf->IsOn("CMAKE_SUPPRESS_REGENERATION"))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
std::string cmake_command = mf->GetRequiredDefinition("CMAKE_COMMAND");
|
std::string cmake_command = mf->GetRequiredDefinition("CMAKE_COMMAND");
|
||||||
cmCustomCommandLines noCommandLines;
|
cmCustomCommandLines noCommandLines;
|
||||||
mf->AddUtilityCommand(CMAKE_CHECK_BUILD_SYSTEM_TARGET, false,
|
mf->AddUtilityCommand(CMAKE_CHECK_BUILD_SYSTEM_TARGET, false,
|
||||||
|
@ -144,72 +152,94 @@ void cmGlobalVisualStudio8Generator::Generate()
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add a custom rule to re-run CMake if any input files changed.
|
// Create a list of all stamp files for this project.
|
||||||
const char* suppRegenRule =
|
std::vector<std::string> stamps;
|
||||||
mf->GetDefinition("CMAKE_SUPPRESS_REGENERATION");
|
std::string stampList = cmake::GetCMakeFilesDirectoryPostSlash();
|
||||||
if(!cmSystemTools::IsOn(suppRegenRule))
|
stampList += "generate.stamp.list";
|
||||||
|
{
|
||||||
|
std::string stampListFile =
|
||||||
|
generators[0]->GetMakefile()->GetCurrentOutputDirectory();
|
||||||
|
stampListFile += "/";
|
||||||
|
stampListFile += stampList;
|
||||||
|
std::string stampFile;
|
||||||
|
cmGeneratedFileStream fout(stampList.c_str());
|
||||||
|
for(std::vector<cmLocalGenerator*>::const_iterator
|
||||||
|
gi = generators.begin(); gi != generators.end(); ++gi)
|
||||||
{
|
{
|
||||||
// Collect the input files used to generate all targets in this
|
stampFile = (*gi)->GetMakefile()->GetCurrentOutputDirectory();
|
||||||
// project.
|
stampFile += "/";
|
||||||
std::vector<std::string> listFiles;
|
stampFile += cmake::GetCMakeFilesDirectoryPostSlash();
|
||||||
for(unsigned int j = 0; j < generators.size(); ++j)
|
stampFile += "generate.stamp";
|
||||||
{
|
stampFile = generators[0]->Convert(stampFile.c_str(),
|
||||||
cmMakefile* lmf = generators[j]->GetMakefile();
|
cmLocalGenerator::START_OUTPUT);
|
||||||
listFiles.insert(listFiles.end(), lmf->GetListFiles().begin(),
|
fout << stampFile << "\n";
|
||||||
lmf->GetListFiles().end());
|
stamps.push_back(stampFile);
|
||||||
}
|
|
||||||
// Sort the list of input files and remove duplicates.
|
|
||||||
std::sort(listFiles.begin(), listFiles.end(),
|
|
||||||
std::less<std::string>());
|
|
||||||
std::vector<std::string>::iterator new_end =
|
|
||||||
std::unique(listFiles.begin(), listFiles.end());
|
|
||||||
listFiles.erase(new_end, listFiles.end());
|
|
||||||
|
|
||||||
// Create a rule to re-run CMake.
|
|
||||||
std::string stampName = cmake::GetCMakeFilesDirectoryPostSlash();
|
|
||||||
stampName += "generate.stamp";
|
|
||||||
const char* dsprule = mf->GetRequiredDefinition("CMAKE_COMMAND");
|
|
||||||
cmCustomCommandLine commandLine;
|
|
||||||
commandLine.push_back(dsprule);
|
|
||||||
std::string argH = "-H";
|
|
||||||
argH += lg->Convert(mf->GetHomeDirectory(),
|
|
||||||
cmLocalGenerator::START_OUTPUT,
|
|
||||||
cmLocalGenerator::UNCHANGED, true);
|
|
||||||
commandLine.push_back(argH);
|
|
||||||
std::string argB = "-B";
|
|
||||||
argB += lg->Convert(mf->GetHomeOutputDirectory(),
|
|
||||||
cmLocalGenerator::START_OUTPUT,
|
|
||||||
cmLocalGenerator::UNCHANGED, true);
|
|
||||||
commandLine.push_back(argB);
|
|
||||||
commandLine.push_back("--check-stamp-file");
|
|
||||||
commandLine.push_back(stampName.c_str());
|
|
||||||
commandLine.push_back("--vs-solution-file");
|
|
||||||
commandLine.push_back("\"$(SolutionPath)\"");
|
|
||||||
cmCustomCommandLines commandLines;
|
|
||||||
commandLines.push_back(commandLine);
|
|
||||||
|
|
||||||
// Add the rule. Note that we cannot use the CMakeLists.txt
|
|
||||||
// file as the main dependency because it would get
|
|
||||||
// overwritten by the CreateVCProjBuildRule.
|
|
||||||
// (this could be avoided with per-target source files)
|
|
||||||
const char* no_main_dependency = 0;
|
|
||||||
const char* no_working_directory = 0;
|
|
||||||
mf->AddCustomCommandToOutput(
|
|
||||||
stampName.c_str(), listFiles,
|
|
||||||
no_main_dependency, commandLines, "Checking Build System",
|
|
||||||
no_working_directory, true);
|
|
||||||
std::string ruleName = stampName;
|
|
||||||
ruleName += ".rule";
|
|
||||||
if(cmSourceFile* file = mf->GetSource(ruleName.c_str()))
|
|
||||||
{
|
|
||||||
tgt->AddSourceFile(file);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
cmSystemTools::Error("Error adding rule for ", stampName.c_str());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add a custom rule to re-run CMake if any input files changed.
|
||||||
|
{
|
||||||
|
// Collect the input files used to generate all targets in this
|
||||||
|
// project.
|
||||||
|
std::vector<std::string> listFiles;
|
||||||
|
for(unsigned int j = 0; j < generators.size(); ++j)
|
||||||
|
{
|
||||||
|
cmMakefile* lmf = generators[j]->GetMakefile();
|
||||||
|
listFiles.insert(listFiles.end(), lmf->GetListFiles().begin(),
|
||||||
|
lmf->GetListFiles().end());
|
||||||
|
}
|
||||||
|
// Sort the list of input files and remove duplicates.
|
||||||
|
std::sort(listFiles.begin(), listFiles.end(),
|
||||||
|
std::less<std::string>());
|
||||||
|
std::vector<std::string>::iterator new_end =
|
||||||
|
std::unique(listFiles.begin(), listFiles.end());
|
||||||
|
listFiles.erase(new_end, listFiles.end());
|
||||||
|
|
||||||
|
// Create a rule to re-run CMake.
|
||||||
|
std::string stampName = cmake::GetCMakeFilesDirectoryPostSlash();
|
||||||
|
stampName += "generate.stamp";
|
||||||
|
const char* dsprule = mf->GetRequiredDefinition("CMAKE_COMMAND");
|
||||||
|
cmCustomCommandLine commandLine;
|
||||||
|
commandLine.push_back(dsprule);
|
||||||
|
std::string argH = "-H";
|
||||||
|
argH += lg->Convert(mf->GetHomeDirectory(),
|
||||||
|
cmLocalGenerator::START_OUTPUT,
|
||||||
|
cmLocalGenerator::UNCHANGED, true);
|
||||||
|
commandLine.push_back(argH);
|
||||||
|
std::string argB = "-B";
|
||||||
|
argB += lg->Convert(mf->GetHomeOutputDirectory(),
|
||||||
|
cmLocalGenerator::START_OUTPUT,
|
||||||
|
cmLocalGenerator::UNCHANGED, true);
|
||||||
|
commandLine.push_back(argB);
|
||||||
|
commandLine.push_back("--check-stamp-list");
|
||||||
|
commandLine.push_back(stampList.c_str());
|
||||||
|
commandLine.push_back("--vs-solution-file");
|
||||||
|
commandLine.push_back("\"$(SolutionPath)\"");
|
||||||
|
cmCustomCommandLines commandLines;
|
||||||
|
commandLines.push_back(commandLine);
|
||||||
|
|
||||||
|
// Add the rule. Note that we cannot use the CMakeLists.txt
|
||||||
|
// file as the main dependency because it would get
|
||||||
|
// overwritten by the CreateVCProjBuildRule.
|
||||||
|
// (this could be avoided with per-target source files)
|
||||||
|
const char* no_main_dependency = 0;
|
||||||
|
const char* no_working_directory = 0;
|
||||||
|
mf->AddCustomCommandToOutput(
|
||||||
|
stamps, listFiles,
|
||||||
|
no_main_dependency, commandLines, "Checking Build System",
|
||||||
|
no_working_directory, true);
|
||||||
|
std::string ruleName = stamps[0];
|
||||||
|
ruleName += ".rule";
|
||||||
|
if(cmSourceFile* file = mf->GetSource(ruleName.c_str()))
|
||||||
|
{
|
||||||
|
tgt->AddSourceFile(file);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cmSystemTools::Error("Error adding rule for ", stamps[0].c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now perform the main generation.
|
// Now perform the main generation.
|
||||||
|
|
|
@ -111,6 +111,7 @@
|
||||||
#include <memory> // auto_ptr
|
#include <memory> // auto_ptr
|
||||||
|
|
||||||
static bool cmakeCheckStampFile(const char* stampName);
|
static bool cmakeCheckStampFile(const char* stampName);
|
||||||
|
static bool cmakeCheckStampList(const char* stampName);
|
||||||
|
|
||||||
void cmNeedBackwardsCompatibility(const std::string& variable,
|
void cmNeedBackwardsCompatibility(const std::string& variable,
|
||||||
int access_type, void*, const char*, const cmMakefile*)
|
int access_type, void*, const char*, const cmMakefile*)
|
||||||
|
@ -553,6 +554,10 @@ void cmake::SetArgs(const std::vector<std::string>& args)
|
||||||
{
|
{
|
||||||
this->CheckStampFile = args[++i];
|
this->CheckStampFile = args[++i];
|
||||||
}
|
}
|
||||||
|
else if((i < args.size()-1) && (arg.find("--check-stamp-list",0) == 0))
|
||||||
|
{
|
||||||
|
this->CheckStampList = args[++i];
|
||||||
|
}
|
||||||
#if defined(CMAKE_HAVE_VS_GENERATORS)
|
#if defined(CMAKE_HAVE_VS_GENERATORS)
|
||||||
else if((i < args.size()-1) && (arg.find("--vs-solution-file",0) == 0))
|
else if((i < args.size()-1) && (arg.find("--vs-solution-file",0) == 0))
|
||||||
{
|
{
|
||||||
|
@ -2150,6 +2155,13 @@ int cmake::Run(const std::vector<std::string>& args, bool noconfigure)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If we are given a stamp list file check if it is really out of date.
|
||||||
|
if(!this->CheckStampList.empty() &&
|
||||||
|
cmakeCheckStampList(this->CheckStampList.c_str()))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// If we are given a stamp file check if it is really out of date.
|
// If we are given a stamp file check if it is really out of date.
|
||||||
if(!this->CheckStampFile.empty() &&
|
if(!this->CheckStampFile.empty() &&
|
||||||
cmakeCheckStampFile(this->CheckStampFile.c_str()))
|
cmakeCheckStampFile(this->CheckStampFile.c_str()))
|
||||||
|
@ -3697,6 +3709,10 @@ static bool cmakeCheckStampFile(const char* stampName)
|
||||||
// date.
|
// date.
|
||||||
if(cmSystemTools::FileExists(stampName))
|
if(cmSystemTools::FileExists(stampName))
|
||||||
{
|
{
|
||||||
|
// Notify the user why CMake is re-running. It is safe to
|
||||||
|
// just print to stdout here because this code is only reachable
|
||||||
|
// through an undocumented flag used by the VS generator.
|
||||||
|
std::cout << "CMake is re-running due to explicit user request.\n";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3744,8 +3760,8 @@ static bool cmakeCheckStampFile(const char* stampName)
|
||||||
// Notify the user why CMake is not re-running. It is safe to
|
// Notify the user why CMake is not re-running. It is safe to
|
||||||
// just print to stdout here because this code is only reachable
|
// just print to stdout here because this code is only reachable
|
||||||
// through an undocumented flag used by the VS generator.
|
// through an undocumented flag used by the VS generator.
|
||||||
std::cout << "CMake does not need to re-run because the "
|
std::cout << "CMake does not need to re-run because "
|
||||||
<< "generation timestamp is up-to-date.\n";
|
<< stampName << " is up-to-date.\n";
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -3755,6 +3771,36 @@ static bool cmakeCheckStampFile(const char* stampName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
static bool cmakeCheckStampList(const char* stampList)
|
||||||
|
{
|
||||||
|
// If the stamp list does not exist CMake must rerun to generate it.
|
||||||
|
if(!cmSystemTools::FileExists(stampList))
|
||||||
|
{
|
||||||
|
std::cout << "CMake is re-running because generate.stamp.list "
|
||||||
|
<< "is missing.\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
std::ifstream fin(stampList);
|
||||||
|
if(!fin)
|
||||||
|
{
|
||||||
|
std::cout << "CMake is re-running because generate.stamp.list "
|
||||||
|
<< "could not be read.\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check each stamp.
|
||||||
|
std::string stampName;
|
||||||
|
while(cmSystemTools::GetLineFromStream(fin, stampName))
|
||||||
|
{
|
||||||
|
if(!cmakeCheckStampFile(stampName.c_str()))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// For visual studio 2005 and newer manifest files need to be embeded into
|
// For visual studio 2005 and newer manifest files need to be embeded into
|
||||||
// exe and dll's. This code does that in such a way that incremental linking
|
// exe and dll's. This code does that in such a way that incremental linking
|
||||||
// still works.
|
// still works.
|
||||||
|
|
|
@ -435,6 +435,7 @@ private:
|
||||||
std::string CCEnvironment;
|
std::string CCEnvironment;
|
||||||
std::string CheckBuildSystemArgument;
|
std::string CheckBuildSystemArgument;
|
||||||
std::string CheckStampFile;
|
std::string CheckStampFile;
|
||||||
|
std::string CheckStampList;
|
||||||
std::string VSSolutionFile;
|
std::string VSSolutionFile;
|
||||||
std::string CTestCommand;
|
std::string CTestCommand;
|
||||||
std::string CPackCommand;
|
std::string CPackCommand;
|
||||||
|
|
Loading…
Reference in New Issue