summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYves Frederix <yves.frederix@gmail.com>2016-09-16 15:50:06 (GMT)
committerBrad King <brad.king@kitware.com>2016-11-17 18:53:42 (GMT)
commit427b6da9e5aa2e1a8570259573b1faa15e4169df (patch)
treec9a2281849dde22f953dbf76ed557f613275d643
parentab4a9a98266fb29008cecc9649a91fc844c541f5 (diff)
downloadCMake-427b6da9e5aa2e1a8570259573b1faa15e4169df.zip
CMake-427b6da9e5aa2e1a8570259573b1faa15e4169df.tar.gz
CMake-427b6da9e5aa2e1a8570259573b1faa15e4169df.tar.bz2
VS: Teach `cmake --build` to reconfigure if needed before building
Visual Studio's build system does not cleanly handle itself being re-generated during the build. Teach `cmake --build` to check whether the build system needs to be re-generated before launching the native build tool.
-rw-r--r--Source/cmGlobalVisualStudio8Generator.cxx7
-rw-r--r--Source/cmGlobalVisualStudio8Generator.h3
-rw-r--r--Source/cmake.cxx64
-rw-r--r--Source/cmakemain.cxx2
4 files changed, 65 insertions, 11 deletions
diff --git a/Source/cmGlobalVisualStudio8Generator.cxx b/Source/cmGlobalVisualStudio8Generator.cxx
index 64808c9..cf37c2c 100644
--- a/Source/cmGlobalVisualStudio8Generator.cxx
+++ b/Source/cmGlobalVisualStudio8Generator.cxx
@@ -161,6 +161,11 @@ void cmGlobalVisualStudio8Generator::GetDocumentation(
entry.Brief = "Generates Visual Studio 8 2005 project files.";
}
+std::string cmGlobalVisualStudio8Generator::GetGenerateStampList()
+{
+ return "generate.stamp.list";
+}
+
void cmGlobalVisualStudio8Generator::Configure()
{
this->cmGlobalVisualStudio7Generator::Configure();
@@ -244,7 +249,7 @@ bool cmGlobalVisualStudio8Generator::AddCheckTarget()
// Create a list of all stamp files for this project.
std::vector<std::string> stamps;
std::string stampList = cmake::GetCMakeFilesDirectoryPostSlash();
- stampList += "generate.stamp.list";
+ stampList += cmGlobalVisualStudio8Generator::GetGenerateStampList();
{
std::string stampListFile =
generators[0]->GetMakefile()->GetCurrentBinaryDirectory();
diff --git a/Source/cmGlobalVisualStudio8Generator.h b/Source/cmGlobalVisualStudio8Generator.h
index b149c9d..53feb47 100644
--- a/Source/cmGlobalVisualStudio8Generator.h
+++ b/Source/cmGlobalVisualStudio8Generator.h
@@ -23,6 +23,9 @@ public:
/** Get the documentation entry for this generator. */
static void GetDocumentation(cmDocumentationEntry& entry);
+ /** Get the name of the main stamp list file. */
+ static std::string GetGenerateStampList();
+
virtual void EnableLanguage(std::vector<std::string> const& languages,
cmMakefile*, bool optional);
virtual void AddPlatformDefinitions(cmMakefile* mf);
diff --git a/Source/cmake.cxx b/Source/cmake.cxx
index 6c066c6..59290ff 100644
--- a/Source/cmake.cxx
+++ b/Source/cmake.cxx
@@ -129,8 +129,8 @@ typedef CM_UNORDERED_MAP<std::string, Json::Value> JsonValueMapType;
} // namespace
-static bool cmakeCheckStampFile(const char* stampName);
-static bool cmakeCheckStampList(const char* stampName);
+static bool cmakeCheckStampFile(const char* stampName, bool verbose = true);
+static bool cmakeCheckStampList(const char* stampList, bool verbose = true);
void cmWarnUnusedCliWarning(const std::string& variable, int /*unused*/,
void* ctx, const char* /*unused*/,
@@ -2233,7 +2233,7 @@ int cmake::GetSystemInformation(std::vector<std::string>& args)
return 0;
}
-static bool cmakeCheckStampFile(const char* stampName)
+static bool cmakeCheckStampFile(const char* stampName, bool verbose)
{
// The stamp file does not exist. Use the stamp dependencies to
// determine whether it is really out of date. This works in
@@ -2287,11 +2287,13 @@ static bool cmakeCheckStampFile(const char* stampName)
stamp << "# CMake generation timestamp file for this directory.\n";
}
if (cmSystemTools::RenameFile(stampTemp, stampName)) {
- // Notify the user why CMake is not 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 does not need to re-run because " << stampName
- << " is up-to-date.\n";
+ if (verbose) {
+ // Notify the user why CMake is not 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 does not need to re-run because " << stampName
+ << " is up-to-date.\n";
+ }
return true;
}
cmSystemTools::RemoveFile(stampTemp);
@@ -2299,7 +2301,7 @@ static bool cmakeCheckStampFile(const char* stampName)
return false;
}
-static bool cmakeCheckStampList(const char* stampList)
+static bool cmakeCheckStampList(const char* stampList, bool verbose)
{
// If the stamp list does not exist CMake must rerun to generate it.
if (!cmSystemTools::FileExists(stampList)) {
@@ -2317,7 +2319,7 @@ static bool cmakeCheckStampList(const char* stampList)
// Check each stamp.
std::string stampName;
while (cmSystemTools::GetLineFromStream(fin, stampName)) {
- if (!cmakeCheckStampFile(stampName.c_str())) {
+ if (!cmakeCheckStampFile(stampName.c_str(), verbose)) {
return false;
}
}
@@ -2397,6 +2399,48 @@ int cmake::Build(const std::string& dir, const std::string& target,
if (cachedVerbose) {
verbose = cmSystemTools::IsOn(cachedVerbose);
}
+
+#ifdef CMAKE_HAVE_VS_GENERATORS
+ // For VS generators, explicitly check if regeneration is necessary before
+ // actually starting the build. If not done separately from the build
+ // itself, there is the risk of building an out-of-date solution file due
+ // to limitations of the underlying build system.
+ std::string const stampList = cachePath + "/" +
+ GetCMakeFilesDirectoryPostSlash() +
+ cmGlobalVisualStudio8Generator::GetGenerateStampList();
+
+ // Note that the stampList file only exists for VS generators.
+ if (cmSystemTools::FileExists(stampList.c_str()) &&
+ !cmakeCheckStampList(stampList.c_str(), false)) {
+
+ // Correctly initialize the home (=source) and home output (=binary)
+ // directories, which is required for running the generation step.
+ std::string homeOrig = this->GetHomeDirectory();
+ std::string homeOutputOrig = this->GetHomeOutputDirectory();
+ this->SetDirectoriesFromFile(cachePath.c_str());
+
+ int ret = this->Configure();
+ if (ret) {
+ cmSystemTools::Message("CMake Configure step failed. "
+ "Build files cannot be regenerated correctly.");
+ return ret;
+ }
+ ret = this->Generate();
+ if (ret) {
+ cmSystemTools::Message("CMake Generate step failed. "
+ "Build files cannot be regenerated correctly.");
+ return ret;
+ }
+ std::string message = "Build files have been written to: ";
+ message += this->GetHomeOutputDirectory();
+ this->UpdateProgress(message.c_str(), -1);
+
+ // Restore the previously set directories to their original value.
+ this->SetHomeDirectory(homeOrig);
+ this->SetHomeOutputDirectory(homeOutputOrig);
+ }
+#endif
+
return gen->Build("", dir, projName, target, output, "", config, clean,
false, verbose, 0, cmSystemTools::OUTPUT_PASSTHROUGH,
nativeOptions);
diff --git a/Source/cmakemain.cxx b/Source/cmakemain.cxx
index a974061..dee288c 100644
--- a/Source/cmakemain.cxx
+++ b/Source/cmakemain.cxx
@@ -407,6 +407,8 @@ static int do_build(int ac, char const* const* av)
}
cmake cm;
+ cmSystemTools::SetMessageCallback(cmakemainMessageCallback, (void*)&cm);
+ cm.SetProgressCallback(cmakemainProgressCallback, (void*)&cm);
return cm.Build(dir, target, config, nativeOptions, clean);
#endif
}