寻找一个'cmake clean'命令清除cmake输出

就像make clean删除makefile生成的所有文件一样,我也想用CMake做同样的事情。 我经常发现自己手动去除了像cmake_install.cmakeCMakeCache.txt CMakeFiles文件和CMakeFiles文件夹。

有像cmake clean的命令来自动删除所有这些文件? 理想情况下,这应该遵循当前目录的CMakeLists.txt文件中定义的recursion结构。

没有cmake clean

我通常在一个单一的文件夹,如“构build”build立项目。 所以如果我想make clean ,我可以用rm -rf build

与“CMakeLists.txt”根目录相同的目录中的“build”文件夹通常是一个不错的select。 要构build您的项目,只需将CMakeLists.txt的位置作为参数提供给cmake。 例如: cd <location-of-cmakelists>/build && cmake .. (来自@ComicSansMS)

我把它search了半个小时,唯一有用的东西就是调用find实用程序:

 # Find and then delete all files under current directory (.) that: # 1. contains cmake (case-&insensitive) in it's path (wholename) # 2. name is not CMakeLists.txt find . -iwholename '*cmake*' -not -name CMakeLists.txt -delete 

此外,请确保在此之前调用make clean (或者您正在使用的任何cmake生成器)。

🙂

CMake官方常见问题指出:

一些使用GNU自动工具创build的构build树有一个“make distclean”目标,用于清除构build,还删除生成的构build系统的Makefiles和其他部分。 CMake不会生成“make distclean”目标,因为CMakeLists.txt文件可以运行脚本和任意命令; CMake没有办法确切地跟踪哪些文件是运行CMake的一部分。 提供一个干净的目标会给用户一个错误的印象,即它会像预期的那样工作。 (CMake会生成一个“make clean”目标来删除由编译器和链接器生成的文件。)

只有用户执行源内构build才需要“make distclean”目标。 CMake支持源内构build,但是我们强烈鼓励用户采用外源构build的概念。 使用独立于源代码树的构build树将阻止CMake在源代码树中生成任何文件。 因为CMake不改变源码树,所以不需要一个干净的目标。 可以通过删除构build树或创build单独的构build树来开始新的构build。

在这些git的日子里,你可能会忘记CMake,并使用git clean -d -f -x ,这将删除所有不受源代码控制的文件。

你可以使用像这样的东西:

 add_custom_target(clean-cmake-files COMMAND ${CMAKE_COMMAND} -P clean-all.cmake ) // clean-all.cmake set(cmake_generated ${CMAKE_BINARY_DIR}/CMakeCache.txt ${CMAKE_BINARY_DIR}/cmake_install.cmake ${CMAKE_BINARY_DIR}/Makefile ${CMAKE_BINARY_DIR}/CMakeFiles ) foreach(file ${cmake_generated}) if (EXISTS ${file}) file(REMOVE_RECURSE ${file}) endif() endforeach(file) 

我通常创build一个“make clean-all”命令,在前面的例子中添加一个“make clean”命令:

 add_custom_target(clean-all COMMAND ${CMAKE_BUILD_TOOL} clean COMMAND ${CMAKE_COMMAND} -P clean-all.cmake ) 

不要试图添加“干净”的目标作为依赖:

 add_custom_target(clean-all COMMAND ${CMAKE_COMMAND} -P clean-all.cmake DEPENDS clean ) 

因为“干净”不是CMake中的真正目标,这是行不通的。 而且,你不应该使用这个“clean-cmake-files”作为任何东西的依赖:

 add_custom_target(clean-all COMMAND ${CMAKE_BUILD_TOOL} clean DEPENDS clean-cmake-files ) 

因为,如果你这样做,所有的cmake文件将在清除之前被清除 – 一切都完成了,并且make会向你发出一个错误,search“CMakeFiles / clean-all.dir / build.make”。 因此,在任何情况下都不能在“任何事情”之前使用clean-all命令:

 add_custom_target(clean-all COMMAND ${CMAKE_BUILD_TOOL} clean COMMAND ${CMAKE_COMMAND} -P clean-all.cmake ) 

这也不pipe用。

简单地发行rm CMakeCache.txt适用于我。

我同意,源代码构build是最好的答案。 但是对于你只需要进行源代码构build的时候,我已经写了一个Python脚本在这里 :

  1. 运行“打扫干净”
  2. 删除顶层目录中的特定cmake生成的文件,如CMakeCache.txt
  3. 对于包含CMakeFiles目录的每个子目录,它将删除CMakeFiles,Makefile和cmake_install.cmake。
  4. 删除所有空的子目录。

我最近发现的解决scheme是将源代码构build概念与Makefile包装器相结合。

在我的顶级CMakeLists.txt文件中,我包含以下内容以防止源代码构build:

 if ( ${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR} ) message( FATAL_ERROR "In-source builds not allowed. Please make a new directory (called a build directory) and run CMake from there. You may need to remove CMakeCache.txt." ) endif() 

然后,我创build一个顶级Makefile,并包含以下内容:

 # ----------------------------------------------------------------------------- # CMake project wrapper Makefile ---------------------------------------------- # ----------------------------------------------------------------------------- SHELL := /bin/bash RM := rm -rf MKDIR := mkdir -p all: ./build/Makefile @ $(MAKE) -C build ./build/Makefile: @ ($(MKDIR) build > /dev/null) @ (cd build > /dev/null 2>&1 && cmake ..) distclean: @ ($(MKDIR) build > /dev/null) @ (cd build > /dev/null 2>&1 && cmake .. > /dev/null 2>&1) @- $(MAKE) --silent -C build clean || true @- $(RM) ./build/Makefile @- $(RM) ./build/src @- $(RM) ./build/test @- $(RM) ./build/CMake* @- $(RM) ./build/cmake.* @- $(RM) ./build/*.cmake @- $(RM) ./build/*.txt ifeq ($(findstring distclean,$(MAKECMDGOALS)),) $(MAKECMDGOALS): ./build/Makefile @ $(MAKE) -C build $(MAKECMDGOALS) endif 

通过键入make调用默认目标all ,并调用目标./build/Makefile

目标./build/Makefile所做的第一件事是使用$(MKDIR)创buildbuild目录,这是mkdir -p一个variables。 目录build是我们将执行我们的源代码构build的地方。 我们提供参数-p来确保mkdir不会尖叫我们试图创build一个可能已经存在的目录。

目标./build/Makefile所做的第二件事是将目录切换到build目录并调用cmake

回到all目标,我们调用$(MAKE) -C build ,其中$(MAKE)是一个为make自动生成的Makefilevariables。 make -C在做任何事之前改变目录。 因此,使用$(MAKE) -C build等价于cd build; make cd build; make

总而言之,调用这个makefile包装器make allmake就相当于:

 mkdir build cd build cmake .. make 

目标distclean调用cmake .. ,然后make -C build clean ,最后,从build目录中删除所有内容。 我相信这正是你在你的问题中所要求的。

Makefile的最后一部分评估用户提供的目标是否是distclean 。 如果不是的话,它会在调用目录之前改变目录。 这是非常强大的,因为用户可以键入,例如, make clean ,并且Makefile会将其转换成cd build; make clean的等效物cd build; make clean cd build; make clean

总之,这个Makefile包装器与一个强制性的源代码构buildCMakeconfiguration相结合,使得用户从不需要与命令cmake进行交互。 此解决scheme还提供了一个优雅的方法来从build目录中删除所有CMake输出文件。

PS在Makefile中,我们使用前缀@来抑制shell命令的输出,前缀@-忽略来自shell命令的错误。 当使用rm作为distclean目标的一部分时,如果这些文件不存在(它们可能已经使用rm -rf build的命令行已经被删除了,或者它们从来没有生成过),那么这个命令会返回一个错误。 这个返回错误将迫使我们的Makefile退出。 我们使用前缀@-来防止这一点。 如果文件已经被删除,这是可以接受的。 我们希望我们的Makefile继续前进,并删除其余的。

另外要注意的是:如果使用可变数量的CMakevariables来构build项目,例如cmake .. -DSOMEBUILDSUSETHIS:STRING="foo" -DSOMEOTHERBUILDSUSETHISTOO:STRING="bar" ,则此Makefile可能不起作用cmake .. -DSOMEBUILDSUSETHIS:STRING="foo" -DSOMEOTHERBUILDSUSETHISTOO:STRING="bar" 。 这个Makefile假定你以一致的方式调用CMake,或者通过inputcmake ..或者通过提供cmake一致的参数(可以包含在你的Makefile中)来调用CMake。

最后,信贷在哪里到期。 这个Makefile包装器是从C ++应用程序项目模板提供的Makefile中进行调整的。

在生成构build文件时将-Dparameter passing到cmake的情况下,并且不想删除整个构build/目录。 只需删除build目录中的CMakeFiles /目录即可。

rm -rf CMakeFiles/

cmake --build .

这导致cmake重新运行,并且生成系统文件被重新生成。 你的构build也将从头开始。

如果你运行这个:

 cmake . 

它将重新生成cmake文件。 例如,如果将新文件添加到由* .ccselect的源文件夹,则这是必需的。

虽然这本身不是一个“干净的”,但它通过重新生成caching来“清理”cmake文件。

希望有所帮助。

在很多情况下, make rebuild_cache是有用的。 它触发一个完整的configuration运行,这将重build所有依赖于variables的目标。

我使用这个shell脚本来达到这个目的:

 #!/bin/bash for fld in $(find -name "CMakeLists.txt" -printf '%h ') do for cmakefile in CMakeCache.txt cmake_install.cmake CTestTestfile.cmake CMakeFiles Makefile do rm -rfv $fld/$cmakefile done done 

如果你使用的是Windows,那么使用Cygwin作为这个脚本。

我在我的shell rc文件( .bashrc.zshrc )中有这个:

 t-cmake-clean() { local BUILD=$(basename $(pwd)) cd .. rm -rf $BUILD mkdir $BUILD && cd $BUILD } 

你应该用于源外构build。 假设您有一个名为build/的目录。 那么你只需要从里面运行t-cmake-clean

我使用了上面的zsxwing的响应来解决以下问题:

我有源代码构build在多个主机上(在Raspberry PI Linux板上,在VMware Linux虚拟机上等)

我有一个bash脚本来创build基于机器的主机名tmp目录是这样的:

 # get hostname to use as part of directory names HOST_NAME=`uname -n` # create a temporary directory for cmake files so they don't # end up all mixed up with the source. TMP_DIR="cmake.tmp.$HOSTNAME" if [ ! -e $TMP_DIR ] ; then echo "Creating directory for cmake tmp files : $TMP_DIR" mkdir $TMP_DIR else echo "Reusing cmake tmp dir : $TMP_DIR" fi # create makefiles with CMake # # Note: switch to tmp dir and build parent which # is a way of making cmake tmp files stay # out of the way. # # Note2: to clean up cmake files, it is OK to # "rm -rf" the tmp dirs echo echo Creating Makefiles with cmake ... cd $TMP_DIR cmake .. # run makefile (in tmp dir) echo echo Starting build ... make 

希望这有助于某人…

创build一个临时构build目录。 比如build_cmake。 因此所有你build立的文件将在这个文件夹中。

然后在你的主cmake文件中添加下面的命令。

 add_custom_target(clean-all rm -rf * ) 

因此在编译的时候呢

 cmake .. 

并干净做

 make clean-all