From 9f1471739d83c9e61b6700a0c369b7f7bbb19071 Mon Sep 17 00:00:00 2001 From: Brad King Date: Mon, 21 Mar 2022 15:09:23 -0400 Subject: cmake: Add --fresh option to clear the cache and start from scratch Simplify the workflow to re-run CMake from scratch as if a build tree were never before processed, regardless of whether it has been. Fixes: #23119 --- Help/manual/cmake.1.rst | 7 +++++++ Help/release/dev/cmake-fresh.rst | 5 +++++ Source/cmake.cxx | 12 ++++++++++++ Source/cmake.h | 1 + Source/cmakemain.cxx | 2 ++ Tests/RunCMake/CommandLine/Fresh-stdout.txt | 4 ++++ Tests/RunCMake/CommandLine/Fresh.cmake | 18 ++++++++++++++++++ .../RunCMake/CommandLine/P_arbitrary_args-stdout.txt | 5 +++-- Tests/RunCMake/CommandLine/P_arbitrary_args.cmake | 1 + Tests/RunCMake/CommandLine/P_fresh-result.txt | 1 + Tests/RunCMake/CommandLine/P_fresh-stderr.txt | 1 + Tests/RunCMake/CommandLine/P_fresh.cmake | 1 + Tests/RunCMake/CommandLine/RunCMakeTest.cmake | 19 ++++++++++++++++++- 13 files changed, 74 insertions(+), 3 deletions(-) create mode 100644 Help/release/dev/cmake-fresh.rst create mode 100644 Tests/RunCMake/CommandLine/Fresh-stdout.txt create mode 100644 Tests/RunCMake/CommandLine/Fresh.cmake create mode 100644 Tests/RunCMake/CommandLine/P_fresh-result.txt create mode 100644 Tests/RunCMake/CommandLine/P_fresh-stderr.txt create mode 100644 Tests/RunCMake/CommandLine/P_fresh.cmake diff --git a/Help/manual/cmake.1.rst b/Help/manual/cmake.1.rst index e93cbe5..93d2ba4 100644 --- a/Help/manual/cmake.1.rst +++ b/Help/manual/cmake.1.rst @@ -197,6 +197,13 @@ Options .. include:: OPTIONS_BUILD.txt +``--fresh`` + .. versionadded:: 3.24 + + Perform a fresh configuration of the build tree. + This removes any existing ``CMakeCache.txt`` file and associated + ``CMakeFiles/`` directory, and recreates them from scratch. + ``-L[A][H]`` List non-advanced cached variables. diff --git a/Help/release/dev/cmake-fresh.rst b/Help/release/dev/cmake-fresh.rst new file mode 100644 index 0000000..6de5b4e --- /dev/null +++ b/Help/release/dev/cmake-fresh.rst @@ -0,0 +1,5 @@ +cmake-fresh +----------- + +* :manual:`cmake(1)` gained the ``--fresh`` command-line option to remove + any existing ``CMakeCache.txt`` when configuring a build tree. diff --git a/Source/cmake.cxx b/Source/cmake.cxx index a602458..5bfc4c8 100644 --- a/Source/cmake.cxx +++ b/Source/cmake.cxx @@ -868,6 +868,11 @@ void cmake::SetArgs(const std::vector& args) CommandArgument{ "-B", "No build directory specified for -B", CommandArgument::Values::One, CommandArgument::RequiresSeparator::No, BuildArgLambda }, + CommandArgument{ "--fresh", CommandArgument::Values::Zero, + [](std::string const&, cmake* cm) -> bool { + cm->FreshCache = true; + return true; + } }, CommandArgument{ "-P", "-P must be followed by a file name.", CommandArgument::Values::One, CommandArgument::RequiresSeparator::No, @@ -2404,12 +2409,19 @@ int cmake::Run(const std::vector& args, bool noconfigure) } if (this->GetWorkingMode() == NORMAL_MODE) { + if (this->FreshCache) { + this->DeleteCache(this->GetHomeOutputDirectory()); + } // load the cache if (this->LoadCache() < 0) { cmSystemTools::Error("Error executing cmake::LoadCache(). Aborting.\n"); return -1; } } else { + if (this->FreshCache) { + cmSystemTools::Error("--fresh allowed only when configuring a project"); + return -1; + } this->AddCMakePaths(); } diff --git a/Source/cmake.h b/Source/cmake.h index 3c2a36c..c2bbff7 100644 --- a/Source/cmake.h +++ b/Source/cmake.h @@ -703,6 +703,7 @@ private: FileExtensions HipFileExtensions; bool ClearBuildSystem = false; bool DebugTryCompile = false; + bool FreshCache = false; bool RegenerateDuringBuild = false; std::unique_ptr FileTimeCache; std::string GraphVizFile; diff --git a/Source/cmakemain.cxx b/Source/cmakemain.cxx index 0554c3e..96bf845 100644 --- a/Source/cmakemain.cxx +++ b/Source/cmakemain.cxx @@ -73,6 +73,8 @@ const char* cmDocumentationOptions[][2] = { { "--list-presets", "List available presets." }, { "-E", "CMake command mode." }, { "-L[A][H]", "List non-advanced cached variables." }, + { "--fresh", + "Configure a fresh build tree, removing any existing cache file." }, { "--build ", "Build a CMake-generated project binary tree." }, { "--install ", "Install a CMake-generated project binary tree." }, { "--open ", "Open generated project in the associated application." }, diff --git a/Tests/RunCMake/CommandLine/Fresh-stdout.txt b/Tests/RunCMake/CommandLine/Fresh-stdout.txt new file mode 100644 index 0000000..b5cece9 --- /dev/null +++ b/Tests/RunCMake/CommandLine/Fresh-stdout.txt @@ -0,0 +1,4 @@ +-- CMAKE_SOURCE_DIR='[^']*/Tests/RunCMake/CommandLine' +-- CMAKE_BINARY_DIR='[^']*/Tests/RunCMake/CommandLine/Fresh-build' +-- OLD CACHED_VAR_1='' +-- NEW CACHED_VAR_1='CACHED-VALUE-1' diff --git a/Tests/RunCMake/CommandLine/Fresh.cmake b/Tests/RunCMake/CommandLine/Fresh.cmake new file mode 100644 index 0000000..9b1695c --- /dev/null +++ b/Tests/RunCMake/CommandLine/Fresh.cmake @@ -0,0 +1,18 @@ +message(STATUS "CMAKE_SOURCE_DIR='${CMAKE_SOURCE_DIR}'") +message(STATUS "CMAKE_BINARY_DIR='${CMAKE_BINARY_DIR}'") +message(STATUS "OLD CACHED_VAR_1='${CACHED_VAR_1}'") +set(CACHED_VAR_1 "CACHED-VALUE-1" CACHE STRING "") +message(STATUS "NEW CACHED_VAR_1='${CACHED_VAR_1}'") +set(kept "${CMAKE_BINARY_DIR}/kept") +set(removed "${CMAKE_BINARY_DIR}/CMakeFiles/removed") +if(FIRST) + file(WRITE "${kept}" "") + file(WRITE "${removed}" "") +else() + if(NOT EXISTS "${kept}") + message(FATAL_ERROR "File was not kept:\n ${kept}") + endif() + if(EXISTS "${removed}") + message(FATAL_ERROR "File was not removed:\n ${removed}") + endif() +endif() diff --git a/Tests/RunCMake/CommandLine/P_arbitrary_args-stdout.txt b/Tests/RunCMake/CommandLine/P_arbitrary_args-stdout.txt index c0f96f3..c94c19d 100644 --- a/Tests/RunCMake/CommandLine/P_arbitrary_args-stdout.txt +++ b/Tests/RunCMake/CommandLine/P_arbitrary_args-stdout.txt @@ -1,8 +1,9 @@ -^-- CMAKE_ARGC='7' +^-- CMAKE_ARGC='8' -- CMAKE_ARGV1='-P' -- CMAKE_ARGV2='[^']*/Tests/RunCMake/CommandLine/P_arbitrary_args.cmake' -- CMAKE_ARGV3='--' -- CMAKE_ARGV4='-DFOO' -- CMAKE_ARGV5='-S' -- CMAKE_ARGV6='-B' --- CMAKE_ARGV7=''$ +-- CMAKE_ARGV7='--fresh' +-- CMAKE_ARGV8=''$ diff --git a/Tests/RunCMake/CommandLine/P_arbitrary_args.cmake b/Tests/RunCMake/CommandLine/P_arbitrary_args.cmake index d0a4859..8dca990 100644 --- a/Tests/RunCMake/CommandLine/P_arbitrary_args.cmake +++ b/Tests/RunCMake/CommandLine/P_arbitrary_args.cmake @@ -6,3 +6,4 @@ message(STATUS "CMAKE_ARGV4='${CMAKE_ARGV4}'") message(STATUS "CMAKE_ARGV5='${CMAKE_ARGV5}'") message(STATUS "CMAKE_ARGV6='${CMAKE_ARGV6}'") message(STATUS "CMAKE_ARGV7='${CMAKE_ARGV7}'") +message(STATUS "CMAKE_ARGV8='${CMAKE_ARGV8}'") diff --git a/Tests/RunCMake/CommandLine/P_fresh-result.txt b/Tests/RunCMake/CommandLine/P_fresh-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CommandLine/P_fresh-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CommandLine/P_fresh-stderr.txt b/Tests/RunCMake/CommandLine/P_fresh-stderr.txt new file mode 100644 index 0000000..0c5b035 --- /dev/null +++ b/Tests/RunCMake/CommandLine/P_fresh-stderr.txt @@ -0,0 +1 @@ +^CMake Error: --fresh allowed only when configuring a project$ diff --git a/Tests/RunCMake/CommandLine/P_fresh.cmake b/Tests/RunCMake/CommandLine/P_fresh.cmake new file mode 100644 index 0000000..dfedce1 --- /dev/null +++ b/Tests/RunCMake/CommandLine/P_fresh.cmake @@ -0,0 +1 @@ +message(FATAL_ERROR "This code should not be reached.") diff --git a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake index 22a59f2..c8234ec 100644 --- a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake +++ b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake @@ -52,7 +52,8 @@ run_cmake_command(G_no-arg ${CMAKE_COMMAND} -B DummyBuildDir -G) run_cmake_command(G_bad-arg ${CMAKE_COMMAND} -B DummyBuildDir -G NoSuchGenerator) run_cmake_command(P_no-arg ${CMAKE_COMMAND} -P) run_cmake_command(P_no-file ${CMAKE_COMMAND} -P nosuchscriptfile.cmake) -run_cmake_command(P_arbitrary_args ${CMAKE_COMMAND} -P "${RunCMake_SOURCE_DIR}/P_arbitrary_args.cmake" -- -DFOO -S -B) +run_cmake_command(P_arbitrary_args ${CMAKE_COMMAND} -P "${RunCMake_SOURCE_DIR}/P_arbitrary_args.cmake" -- -DFOO -S -B --fresh) +run_cmake_command(P_fresh ${CMAKE_COMMAND} -P "${RunCMake_SOURCE_DIR}/P_fresh.cmake" --fresh) run_cmake_command(build-no-dir ${CMAKE_COMMAND} --build) @@ -212,6 +213,22 @@ message(STATUS "CMAKE_BINARY_DIR='${CMAKE_BINARY_DIR}'") endfunction() run_ExplicitDirs() +function(run_Fresh) + set(RunCMake_TEST_BINARY_DIR "${RunCMake_BINARY_DIR}/Fresh-build") + + set(RunCMake_TEST_VARIANT_DESCRIPTION "-empty") + run_cmake_with_options(Fresh --fresh -DFIRST=ON) + set(RunCMake_TEST_NO_CLEAN 1) + + set(RunCMake_TEST_VARIANT_DESCRIPTION "-reconfig") + run_cmake_with_options(Fresh --fresh) + + set(RunCMake_TEST_VARIANT_DESCRIPTION "-src-from-cache") + set(RunCMake_TEST_NO_SOURCE_DIR 1) + run_cmake_with_options(Fresh --fresh "${RunCMake_TEST_BINARY_DIR}") +endfunction() +run_Fresh() + function(run_Toolchain) set(RunCMake_TEST_NO_SOURCE_DIR 1) set(source_dir ${RunCMake_SOURCE_DIR}/Toolchain) -- cgit v0.12