正如make clean删除makefile生成的所有文件一样,我想对CMake做同样的事情。我经常发现自己手动地在目录中删除像cmake_install这样的文件。cmake和CMakeCache.txt,以及CMakeFiles文件夹。

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


当前回答

清除cmake构建输出:

命令行:

$ rm -rf [folder that you builded the project]/
$ cmake --build .

Cmake:

cmake --build . --target clean

其他回答

创建一个临时构建目录,例如build_cmake。因此所有的构建文件都在这个文件夹中。

然后在主CMake文件中添加以下命令。

add_custom_target(clean-all
    rm -rf *
)

因此,在编译时

cmake ..

和清洁做:

make clean-all

我最近发现的一个解决方案是将外部构建概念与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所做的第一件事是使用$(MKDIR)创建构建目录,这是MKDIR -p的变量。目录构建是我们执行源外构建的地方。我们提供参数-p,以确保mkdir不会因为试图创建一个可能已经存在的目录而对我们大喊大叫。

目标./build/Makefile所做的第二件事是将目录更改为build目录并调用cmake。

回到all目标,我们调用$(MAKE) -C构建,其中$(MAKE)是为MAKE自动生成的Makefile变量。make -C在执行任何操作之前更改目录。因此,使用$(MAKE) -C build相当于执行cd build;制作。

总而言之,使用make all或make调用这个Makefile包装器相当于这样做:

mkdir build
cd build
cmake ..
make 

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

Makefile的最后一部分评估用户提供的目标是否是distclean。如果不是,它将在调用之前更改要构建的目录。这是非常强大的,因为用户可以输入,例如,make clean, Makefile会将其转换为cd build;做清洁。

总之,这个Makefile包装器与强制的外部构建CMake配置相结合,使得用户永远不必与CMake命令交互。这个解决方案还提供了一个优雅的方法来从构建目录中删除所有CMake输出文件。

P.S. In the Makefile, we use the prefix @ to suppress the output from a shell command, and the prefix @- to ignore errors from a shell command. When using rm as part of the distclean target, the command will return an error if the files do not exist (they may have been deleted already using the command line with rm -rf build, or they were never generated in the first place). This return error will force our Makefile to exit. We use the prefix @- to prevent that. It is acceptable if a file was removed already; we want our Makefile to keep going and remove the rest.

另一件需要注意的事情:如果你使用可变数量的CMake变量来构建项目,这个Makefile可能无法工作,例如,CMake ..-DSOMEBUILDSUSETHIS:字符串= " foo " -DSOMEOTHERBUILDSUSETHISTOO:字符串=“酒吧”。这个Makefile假设你以一致的方式调用CMake,或者输入CMake ..或者通过为cmake提供一致数量的参数(可以包含在Makefile中)。

最后,在该表扬的地方表扬。这个Makefile包装器改编自c++应用程序项目模板提供的Makefile。

我用zsxwing的答案成功解决了以下问题:

我有在多个主机上构建的源代码(在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

为了简化使用“源外”构建时的清理(即在构建目录中构建),我使用以下脚本:

$ 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

CMake 3。X

CMake 3.0及以上版本提供了一个“干净”的目标。这将删除任何工件,如目标文件、库文件、可执行文件、生成文件等。

cmake --build C:/foo/build/ --target clean

您还可以清理构建,然后运行构建。在1命令。

cmake --build C:/foo/build --clean-first

但是,这不会清理CMakeCache.txt或相关的CMakeFiles/目录。你可能想这么做。你只需要删除构建文件夹。

# Just delete the build folder
rm C:/foo/build -rf

# You can also just let git delete the build folder as well
git clean -d -f -x

CMake 3.24

现在在CMake 3.24中,你可以执行一个新的构建树配置。这将删除任何现有的CMakeCache.txt文件和相关的CMakeFiles/目录,并从头开始重新创建它们。

一般情况下,你需要这样做:

你想清除CMakeCache.txt中的缓存变量 您希望更改编译器 任何与CMake缓存相关的其他操作

cmake -B C:/foo/build --fresh