Answers:
没有cmake clean
。
我通常在“ build”之类的单个文件夹中构建项目。所以,如果我想make clean
,我可以rm -rf build
。
通常,与根目录“ CMakeLists.txt”位于同一目录中的“ build”文件夹是一个不错的选择。要构建项目,只需将cmake的CMakeLists.txt位置作为参数即可。例如:cd <location-of-cmakelists>/build && cmake ..
。(来自@ComicSansMS)
cd <location-of-cmakelists>/build && cmake ..
一些使用GNU自动工具创建的构建树具有“ make distclean”目标,该目标可以清除构建并删除生成的构建系统的Makefile和其他部分。CMake不会生成“ make distclean”目标,因为CMakeLists.txt文件可以运行脚本和任意命令。CMake无法准确跟踪运行CMake时生成的文件。提供distclean目标会给用户一种错误的印象,即它可以按预期工作。(CMake确实会生成“ make clean”目标,以删除由编译器和链接器生成的文件。)
仅当用户执行源内构建时,才需要“ make distclean”目标。CMake支持源代码内部版本,但是我们强烈建议用户采用源代码外部版本的概念。使用与源树分开的构建树将阻止CMake在源树中生成任何文件。因为CMake不会更改源树,所以不需要distclean目标。可以通过删除构建树或创建单独的构建树来开始新的构建。
在当今Git到处都是,您可能会忘记CMake并使用git clean -d -f -x
,这将删除所有不在源代码控制下的文件。
-x
虽然那个选择。那是git
交易的绝招。虽然我个人还是做干先运行,git clean -d -f -x -n
。我偶尔会在项目文件夹处于git
受控状态的情况下保存用于项目的便捷文件,但这不是我想与其他人共享的内容,因此我不会git add
在项目中共享它。如果我不小心添加一个-e <pattern>
选项,这会把这种文件吹走。关于这一点,如果git
有一个.gitcleanignore
文件会很好。:)
chattr +i $filename
(需要root权限,此后不允许修改文件)。这样,即使git尝试这样做,git也将无法删除该文件rm -f
。
git add
呢?
我在Google上搜索了大约半小时,而我想到的唯一有用的方法是调用该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的生成您正在使用什么)之前这一点。
:)
rm -rf CMakeFiles ; rm -rf */CMakeFiles ; rm -rf */*/CMakeFiles ; rm -rf */*/*/CMakeFiles
,但仍然没有做……
您可以使用类似:
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文件将在清除所有文件之前被擦除,并且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
)
那也不行。
只是rm CMakeCache.txt
为我发行作品。
cmake /build-path
再次运行。
我同意外包的构建是最好的答案。但是对于有时候您只需要进行源代码构建的时候,我在这里编写了一个Python脚本,该脚本:
make
没有任何内容Makefile
的情况下(例如,使该脚本成为幂等)而静音。只需if os.path.isfile(os.path.join(directory,'Makefile')):
在第24行之前添加以下行(适当间隔):就在刚添加的行之后args = [
缩进函数主体的其余部分。make ... clean
如果Makefile
要清除的当前目录中存在a,则仅执行a 。否则,脚本是完美的!
我最近发现的一个解决方案是将源代码外生成概念与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)
是自动为生成的Makefile变量make
。make -C
在执行任何操作之前更改目录。因此,使用$(MAKE) -C build
等效于做cd build; make
。
总而言之,使用make all
或调用此Makefile包装器make
等效于:
mkdir build
cd build
cmake ..
make
目标先distclean
调用cmake ..
,然后再调用,make -C build clean
最后从build
目录中删除所有内容。我相信这正是您在问题中所要求的。
Makefile的最后一部分评估用户提供的目标是否为distclean
。如果没有,它将build
在调用之前将目录更改为。这非常强大,因为用户可以键入,例如,make clean
Makefile会将其转换为cd build; make clean
。
总而言之,此Makefile包装器与强制性的源外构建CMake配置相结合,可以使用户永远不必与命令进行交互cmake
。该解决方案还提供了一种优雅的方法,可以从build
目录中删除所有CMake输出文件。
PS在Makefile中,我们使用前缀@
来抑制shell命令的输出,并使用前缀@-
来忽略shell命令的错误。当rm
用作distclean
目标的一部分时,如果文件不存在(该文件可能已经使用带有的命令行删除了rm -rf build
,或者它们从未被生成过),该命令将返回错误。此返回错误将迫使我们的Makefile退出。我们使用前缀@-
来防止这种情况。如果文件已被删除,这是可以接受的。我们希望我们的Makefile继续运行并删除其余部分。
需要注意的另一件事:如果使用可变数量的CMake变量来构建项目,则该Makefile可能无法工作cmake .. -DSOMEBUILDSUSETHIS:STRING="foo" -DSOMEOTHERBUILDSUSETHISTOO:STRING="bar"
。此Makefile假定您通过输入cmake ..
或提供cmake
一致数量的参数(可以包含在Makefile中)以一致的方式调用CMake 。
最后,在应收信贷的地方信贷。这个Makefile包装器是从C ++ Application Project Template提供的Makefile改编而来的。
当然,对于Unix Makefile,源代码外构建是首选方法,但是如果您正在使用其他生成器(例如Eclipse CDT),则它更倾向于您进行源代码内构建。在这种情况下,您将需要手动清除CMake文件。尝试这个:
find . -name 'CMakeCache.txt' -o -name '*.cmake' -o -name 'Makefile' -o -name 'CMakeFiles' -exec rm -rf {} +
或者,如果您使用启用了globstar shopt -s globstar
,请改用这种不太令人讨厌的方法:
rm -rf **/CMakeCache.txt **/*.cmake **/Makefile **/CMakeFiles
build
。比这些命令花了更长的时间,但我只需要做一次:)
为了简化使用“无源”构建(即,您在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
cd .. ; rm ; mkdir ; cd
序列替换为cd .. ; rm -rf build/*
。
有趣的是,看到这个问题得到了如此多的关注和复杂的解决方案,这确实显示了使用cmake缺乏干净方法的痛苦。
好吧,您可以肯定cd build
要做的工作,然后rm -rf *
在需要清洁时进行处理。但是,rm -rf *
鉴于许多人通常不知道他们所在的目录,这是一个危险的命令。
如果您是cd ..
,rm -rf build
然后是mkdir build
,那么cd build
就是太多的输入。
因此,一个好的解决方案是不使用build文件夹,并告诉cmake路径:
配置:cmake -B build
build:cmake --build build
清理:rm -rf build
重新创建build文件夹:您甚至不需要mkdir build
,只需配置它,cmake -B build
然后cmake即可创建
cmake
主要是一个厨师Makefile
,一个可以添加rm
到清洁假。
例如,
[root@localhost hello]# ls
CMakeCache.txt CMakeFiles cmake_install.cmake CMakeLists.txt hello Makefile test
[root@localhost hello]# vi Makefile
clean:
$(MAKE) -f CMakeFiles/Makefile2 clean
rm -rf *.o *~ .depend .*.cmd *.mod *.ko *.mod.c .tmp_versions *.symvers *.d *.markers *.order CMakeFiles cmake_install.cmake CMakeCache.txt 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
创建一个临时构建目录,例如, build_cmake
。因此,所有构建文件都将位于此文件夹中。
然后在您的主要CMake文件中添加以下命令。
add_custom_target(clean-all
rm -rf *
)
因此在编译时
cmake ..
并进行清洁:
make clean-all