就像make clean
删除了makefile生成的所有文件一样,我想对CMake做同样的事情。我经常发现自己手动浏览目录,删除cmake_install.cmake
和CMakeCache.txt
以及CMakeFiles
文件夹等文件。
是否有像cmake clean
这样的命令可以自动删除所有这些文件?理想情况下,这应该遵循当前目录的CMakeLists.txt
文件中定义的递归结构。
答案 0 :(得分:402)
没有cmake clean
。
我通常在像“build”这样的单个文件夹中构建项目。因此,如果我想make clean
,我可以rm -rf build
。
与根目录“CMakeLists.txt”位于同一目录中的“build”文件夹通常是一个不错的选择。要构建项目,只需将cakeke作为参数提供给CMakeLists.txt的位置即可。例如:cd <location-of-cmakelists>/build && cmake ..
。 (来自@ComicSansMS)
答案 1 :(得分:70)
使用GNU autotools创建的一些构建树具有“make distclean” 清除构建的目标,也删除Makefile和其他 生成的构建系统的一部分。 CMake不生成“make distclean“target,因为CMakeLists.txt文件可以运行脚本和 任意命令; CMake无法准确跟踪哪些文件 是作为运行CMake的一部分生成的。提供一个干净的目标 会给用户一个错误的印象,即它会按预期工作。 (CMake会生成一个“make clean”目标来删除生成的文件 由编译器和链接器。)
“make distclean”目标只是 如果用户执行源内构建,则必需。 CMake支持 源内构建,但我们强烈建议用户采用这一概念 源外构建。使用与之分离的构建树 源树将阻止CMake生成任何文件 源树。因为CMake不会更改源树,所以有 不需要一个干净的目标。一个人可以开始新的建设 删除构建树或创建单独的构建树。
答案 2 :(得分:51)
我用谷歌搜索了半个小时,我想出的唯一有用的东西是调用find
实用程序:
# Find and then delete all files under current directory (.) that:
# 1. contains "cmake" (case-&insensitive) in its path (wholename)
# 2. name is not CMakeLists.txt
find . -iwholename '*cmake*' -not -name CMakeLists.txt -delete
此外,请务必在之前调用make clean
(或您正在使用的任何CMake生成器)。
:)
答案 3 :(得分:47)
在Git的这些日子里,你可能会忘记CMake并使用git clean -d -f -x
,这将删除所有不受源代码控制的文件。
答案 4 :(得分:29)
您可以使用以下内容:
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)
我通常创建一个“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文件将在clean-all完成之前被删除,make会在搜索“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
)
这也不起作用。
答案 5 :(得分:18)
简单地发布rm CMakeCache.txt
也适用于我。
答案 6 :(得分:7)
我同意源外构建是最好的答案。但是,在您必须进行源内构建的时候,我编写了一个可用的here Python脚本,其中:
答案 7 :(得分:4)
我最近发现的解决方案是将源外构建概念与Makefile包装器结合起来。
在我的顶级CMakeLists.txt文件中,我包含以下内容以防止源内构建:
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()
然后,我创建一个顶级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
通过键入all
来调用默认目标make
,并调用目标./build/Makefile
。
目标./build/Makefile
做的第一件事是使用build
创建$(MKDIR)
目录,mkdir -p
是build
的变量。目录-p
是我们执行源外构建的地方。我们提供参数mkdir
以确保./build/Makefile
不会因为尝试创建可能已存在的目录而尖叫。
目标build
做的第二件事是将目录更改为cmake
目录并调用all
。
回到$(MAKE) -C build
目标,我们调用$(MAKE)
,其中make
是为make -C
自动生成的Makefile变量。 $(MAKE) -C build
在执行任何操作之前更改目录。因此,使用cd build; make
相当于执行make all
。
总而言之,使用make
或mkdir build
cd build
cmake ..
make
调用此Makefile包装器等同于:
distclean
目标cmake ..
调用make -C build clean
,然后调用build
,最后删除distclean
目录中的所有内容。我相信这正是您在问题中提出的要求。
Makefile的最后一段评估用户提供的目标是否为build
。如果没有,它会在调用之前将目录更改为make clean
。这非常强大,因为用户可以键入,例如cd build; make clean
,Makefile会将其转换为等效的cmake
。
总之,这个Makefile包装器与强制的源外构建CMake配置相结合,使得用户永远不必与命令build
进行交互。此解决方案还提供了一种从@
目录中删除所有CMake输出文件的优雅方法。
P.S。在Makefile中,我们使用前缀@-
来抑制shell命令的输出,使用前缀rm
来忽略shell命令中的错误。当distclean
作为rm -rf build
目标的一部分使用时,如果文件不存在(可能已使用@-
的命令行删除了它们,则该命令将返回错误,或者它们从来没有产生过。)此返回错误将强制我们的Makefile退出。我们使用前缀cmake .. -DSOMEBUILDSUSETHIS:STRING="foo" -DSOMEOTHERBUILDSUSETHISTOO:STRING="bar"
来防止这种情况发生。如果已经删除了文件,则可以接受;我们希望Makefile继续运行并删除其余部分。
需要注意的另一点是:如果使用可变数量的CMake变量来构建项目,则此Makefile可能无效,例如cmake ..
。此Makefile假定您以一致的方式调用CMake,方法是键入cmake
或提供{{1}}一致数量的参数(可以包含在Makefile中)。
最后,信用到期的信用。这个Makefile包装器是从C++ Application Project Template提供的Makefile改编而来的。
答案 8 :(得分:3)
如果在生成构建文件时将-D
参数传递给CMake并且不想删除整个构建/目录:
只需删除构建目录中的CMakeFiles /目录即可。
rm -rf CMakeFiles/
cmake --build .
这会导致CMake重新运行,并重新生成构建系统文件。您的构建也将从头开始。
答案 9 :(得分:3)
也许它有点过时了,但是因为这是谷歌cmake clean
的第一次点击,我会添加:
由于您可以使用
在指定目标的构建目录中开始构建 cmake --build . --target xyz
你当然可以运行
cmake --build . --target clean
在生成的构建文件中运行clean
目标。
答案 10 :(得分:2)
很高兴看到这个问题获得了如此多的关注和复杂的解决方案,这确实显示了使用cmake缺乏干净方法的痛苦。
好吧,您绝对可以cd build
进行工作,然后在需要清洁时进行rm -rf *
。但是,鉴于许多人通常不知道他们所在的目录,rm -rf *
是一个危险的命令。
如果您依次cd ..
,rm -rf build
,然后依次mkdir build
和cd build
,那么输入的内容太多了。
因此,一个好的解决方案是不使用build文件夹并告诉cmake路径:
配置:cmake -B build
构建:cmake --build build
清洁:rm -rf build
重新创建构建文件夹:您甚至不需要mkdir build
,只需使用cmake -B build
配置它,然后cmake就会创建它
答案 11 :(得分:2)
当然,对于Unix Makefile,源代码外构建是首选方法,但是如果您使用的是Eclipse CDT之类的其他生成器,则它更希望您进行源代码内构建。在这种情况下,您将需要手动清除CMake文件。试试这个:
find . -name 'CMakeCache.txt' -o -name '*.cmake' -o -name 'Makefile' -o -name 'CMakeFiles' -exec rm -rf {} +
或者,如果您已经为shopt -s globstar
启用了globstar,请尝试使用这种不太令人讨厌的方法:
rm -rf **/CMakeCache.txt **/*.cmake **/Makefile **/CMakeFiles
答案 12 :(得分:0)
这很老了,但是如果您完全删除了cmake-build-debug文件夹,则在使用cmake进行编译时,它会自动创建一个新的cmake-build-debug文件夹,其中包含您需要的所有内容。在CLion中效果特别好。
答案 13 :(得分:0)
B b;
b.A::doSomething(); // calls A::doSomething()
通常会烹饪cmake
,可以将Makefile
添加到干净的电话中。
例如,
rm
答案 14 :(得分:0)
尝试使用: cmake --clean-first-CMakeLists.txt文件-B output-dir
-clean-first:先构建目标,然后再构建。
(仅清洁,请使用--target clean。)
答案 15 :(得分:0)
如果您具有自定义定义,并且想要在清理之前保存它们,请在构建目录中运行以下命令:
sed -ne '/variable specified on the command line/{n;s/.*/-D \0 \\/;p}' CMakeCache.txt
然后创建一个新的构建目录(或删除旧的构建目录并重新创建它),最后使用上面脚本中提供的参数运行cmake
。
答案 16 :(得分:0)
使用&#34;来源&#34;以简化清洁工作。构建(即你在build
目录中构建),我使用以下脚本:
$ cat ~/bin/cmake-clean-build
#!/bin/bash
if [ -d ../build ]; then
cd ..
rm -rf build
mkdir build
cd build
else
echo "build directory DOES NOT exist"
fi
每次需要清理时,都应该从build
目录中获取此脚本:
. cmake-clean-build
答案 17 :(得分:0)
我将以下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作为此脚本。
答案 18 :(得分:0)
如果你跑
cmake .
它将重新生成CMake文件。如果您将新文件添加到* .cc选择的源文件夹,则必须使用该文件。
虽然这本身并不“干净”,但它会通过重新生成缓存来“清理”CMake文件。
答案 19 :(得分:-1)
我在我的shell rc文件(.bashrc
,.zshrc
)中有这个:
t-cmake-clean() {
local BUILD=$(basename $(pwd))
cd ..
rm -rf $BUILD
mkdir $BUILD && cd $BUILD
}
您应该将仅用于源外构建。让我们假设您有一个名为build/
的目录。然后你只需要在其中运行t-cmake-clean
。
答案 20 :(得分:-3)
我成功使用zsxwing's answer来解决以下问题:
我有源自多个主机(在Raspberry Pi Linux板上,在VMware Linux虚拟机上等)。
我有一个Bash脚本,可以根据机器的主机名创建临时目录,如下所示:
# 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 the temporary dir and build parent
# which is a way of making cmake tmp files stay
# out of the way.
#
# Note 2: to clean up cmake files, it is OK to
# "rm -rf" the temporary directories
echo
echo Creating Makefiles with cmake ...
cd $TMP_DIR
cmake ..
# Run makefile (in temporary directory)
echo
echo Starting build ...
make
答案 21 :(得分:-6)
创建临时构建目录,例如build_cmake
。因此,您的所有构建文件都将位于此文件夹中。
然后在主CMake文件中添加以下命令。
add_custom_target(clean-all
rm -rf *
)
因此在编译时
cmake ..
要清理干净:
make clean-all