diff options
author | Yves Frederix <yves.frederix@gmail.com> | 2016-09-16 15:50:06 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2016-11-17 18:53:42 (GMT) |
commit | 427b6da9e5aa2e1a8570259573b1faa15e4169df (patch) | |
tree | c9a2281849dde22f953dbf76ed557f613275d643 | |
parent | ab4a9a98266fb29008cecc9649a91fc844c541f5 (diff) | |
download | CMake-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.cxx | 7 | ||||
-rw-r--r-- | Source/cmGlobalVisualStudio8Generator.h | 3 | ||||
-rw-r--r-- | Source/cmake.cxx | 64 | ||||
-rw-r--r-- | Source/cmakemain.cxx | 2 |
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 } |