From 25b6e7b710d7739cca44ed19bf45a190e72a6b82 Mon Sep 17 00:00:00 2001 From: Brad King Date: Thu, 17 Nov 2016 10:29:55 -0500 Subject: Tolerate removed/replaced CMakeCache.txt with old CMakeFiles/ Users or scripts commonly remove or replace `CMakeCache.txt` without also removing `CMakeFiles/`. In this case the information saved in the cache from platform information initialization is missing, so we need to re-initialize it. In such a case, remove the platform information directory so that re-initialization will occur and restore needed information to the cache. Closes: #14820 --- Source/cmGlobalGenerator.cxx | 20 ++++++++++++++++++++ Tests/RunCMake/Configure/RemoveCache-stdout.txt | 1 + Tests/RunCMake/Configure/RemoveCache.cmake | 17 +++++++++++++++++ Tests/RunCMake/Configure/RunCMakeTest.cmake | 9 +++++++++ 4 files changed, 47 insertions(+) create mode 100644 Tests/RunCMake/Configure/RemoveCache-stdout.txt create mode 100644 Tests/RunCMake/Configure/RemoveCache.cmake diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index fa447ff..2808051 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -50,6 +50,9 @@ #include #endif +const std::string kCMAKE_PLATFORM_INFO_INITIALIZED = + "CMAKE_PLATFORM_INFO_INITIALIZED"; + class cmInstalledFile; bool cmTarget::StrictTargetComparison::operator()(cmTarget const* t1, @@ -428,6 +431,23 @@ void cmGlobalGenerator::EnableLanguage( // set the dir for parent files so they can be used by modules mf->AddDefinition("CMAKE_PLATFORM_INFO_DIR", rootBin.c_str()); + if (!this->CMakeInstance->GetIsInTryCompile()) { + // Keep a mark in the cache to indicate that we've initialized the + // platform information directory. If the platform information + // directory exists but the mark is missing then CMakeCache.txt + // has been removed or replaced without also removing the CMakeFiles/ + // directory. In this case remove the platform information directory + // so that it will be re-initialized and the relevant information + // restored in the cache. + if (cmSystemTools::FileIsDirectory(rootBin) && + !mf->IsOn(kCMAKE_PLATFORM_INFO_INITIALIZED)) { + cmSystemTools::RemoveADirectory(rootBin); + } + this->GetCMakeInstance()->AddCacheEntry( + kCMAKE_PLATFORM_INFO_INITIALIZED, "1", + "Platform information initialized", cmStateEnums::INTERNAL); + } + // find and make sure CMAKE_MAKE_PROGRAM is defined if (!this->FindMakeProgram(mf)) { return; diff --git a/Tests/RunCMake/Configure/RemoveCache-stdout.txt b/Tests/RunCMake/Configure/RemoveCache-stdout.txt new file mode 100644 index 0000000..73e7e5d --- /dev/null +++ b/Tests/RunCMake/Configure/RemoveCache-stdout.txt @@ -0,0 +1 @@ +-- The C compiler identification is diff --git a/Tests/RunCMake/Configure/RemoveCache.cmake b/Tests/RunCMake/Configure/RemoveCache.cmake new file mode 100644 index 0000000..304918f --- /dev/null +++ b/Tests/RunCMake/Configure/RemoveCache.cmake @@ -0,0 +1,17 @@ +enable_language(C) + +set(vars + CMAKE_EXECUTABLE_FORMAT + ) + +if(CMAKE_HOST_UNIX) + list(APPEND vars + CMAKE_UNAME + ) +endif() + +foreach(v IN LISTS vars) + if(NOT DEFINED ${v}) + message(SEND_ERROR "Variable '${v}' is not set!") + endif() +endforeach() diff --git a/Tests/RunCMake/Configure/RunCMakeTest.cmake b/Tests/RunCMake/Configure/RunCMakeTest.cmake index 91adb4e..4a135be 100644 --- a/Tests/RunCMake/Configure/RunCMakeTest.cmake +++ b/Tests/RunCMake/Configure/RunCMakeTest.cmake @@ -24,3 +24,12 @@ file(WRITE "${depend}" "2") run_cmake_command(RerunCMake-build2 ${CMAKE_COMMAND} --build .) unset(RunCMake_TEST_BINARY_DIR) unset(RunCMake_TEST_NO_CLEAN) + +# Use a single build tree for a few tests without cleaning. +set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/RemoveCache-build) +set(RunCMake_TEST_NO_CLEAN 1) +file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}") +file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}") +run_cmake(RemoveCache) +file(REMOVE "${RunCMake_TEST_BINARY_DIR}/CMakeCache.txt") +run_cmake(RemoveCache) -- cgit v0.12