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

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


当前回答

如果您有自定义定义,并希望在清理之前保存它们,请在构建目录中运行以下命令:

sed -ne '/variable specified on the command line/{n;s/.*/-D \0 \\/;p}' CMakeCache.txt

然后创建一个新的构建目录(或删除旧的构建目录并重新创建它),最后使用上面脚本获得的参数运行cmake。

其他回答

CMake 3。X

CMake 3。X提供了一个“干净”的目标。

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

来自3.0.2版本的CMake文档:

--clean-first  = Build target 'clean' first, then build.
                 (To clean only, use --target 'clean'.)

CMake 2。X

在cmake版本2中没有cmake clean。X

我通常在一个类似“build”的文件夹中构建项目。如果我想弄清楚,我可以rm -rf构建。

在与根目录“CMakeLists.txt”相同的目录中的“build”文件夹通常是一个不错的选择。要构建你的项目,你只需要把CMakeLists.txt文件的位置作为参数给cmake。例如:cd <location-of-cmakelists>/build && cmake…(从@ComicSansMS)

在Git无处不在的今天,你可能会忘记CMake,而使用Git clean -d -f -x,这将删除所有不在源代码控制下的文件。

清除cmake构建输出:

命令行:

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

Cmake:

cmake --build . --target clean

我用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

我最近发现的一个解决方案是将外部构建概念与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。