寻找一个'cmake clean'命令清除cmake输出
就像make clean
删除makefile生成的所有文件一样,我也想用CMake做同样的事情。 我经常发现自己手动去除了像cmake_install.cmake
和CMakeCache.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脚本在这里 :
- 运行“打扫干净”
- 删除顶层目录中的特定cmake生成的文件,如CMakeCache.txt
- 对于包含CMakeFiles目录的每个子目录,它将删除CMakeFiles,Makefile和cmake_install.cmake。
- 删除所有空的子目录。
我最近发现的解决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 all
或make
就相当于:
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