607

Just as make clean deletes all the files that a makefile has produced, I would like to do the same with CMake. All too often I find myself manually going through directories removing files like cmake_install.cmake and CMakeCache.txt, and the CMakeFiles folders.

Is there a command like cmake clean to remove all these files automatically? Ideally this should follow the recursive structure defined within the current directory's CMakeLists.txt file.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Bill Cheatham
  • 11,396
  • 17
  • 69
  • 104

26 Answers26

682

CMake 3.X

CMake 3.X offers a 'clean' target.

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

From the CMake docs for 3.0.2:

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

CMake 2.X

There is no cmake clean in CMake version 2.X

I usually build the project in a single folder like "build". So if I want to make clean, I can just rm -rf build.

The "build" folder in the same directory as the root "CMakeLists.txt" is usually a good choice. To build your project, you simply give cmake the location of the CMakeLists.txt as an argument. For example: cd <location-of-cmakelists>/build && cmake ... (From @ComicSansMS)

zsxwing
  • 20,270
  • 4
  • 37
  • 59
  • 132
    This is called "out of source build" and should be the preferred way to go. It avoids name clashes and the like – arne Mar 13 '12 at 08:48
  • 25
    +1 for out-of-source builds. This becomes vital when building multiple architectures. For example, you cannot build both 64bit and 32bit binaries with an in-source build, as this requires two separate CMake cache hierarchies. – ComicSansMS Mar 13 '12 at 09:22
  • This sounds great. Could you provide some more details on where this folder usually sits relative to your top level CMakeLists, and also how to specify the build location in CMake? – Bill Cheatham Mar 13 '12 at 09:38
  • 9
    You can place the folder anywhere you want, but a build folder in the same directory as the root CMakeLists.txt is usually a good choice. To build you simply give cmake the location of the CMakeLists.txt as an argument. For example: `cd /build && cmake ..` – ComicSansMS Mar 13 '12 at 10:09
  • 86
    There really ought to be a cmake clean. Everyone who has ever used cmake, even if they are in the habit of doing out of source builds, has accidentally run cmake in the wrong directory and it is a huge pain in the ass to clean up manually. – pavon May 19 '15 at 18:29
  • 2
    @pavon: Any files *generated* by CMake should *not* be under version control. Removing any files from the source directory that are not under version control is easy. – DevSolar Jun 12 '15 at 11:10
  • 31
    @DevSolar But the converse is not true; just because a file is not under version control doesn't mean that it is generated by cmake and is safe to blow away. Picking out which unversioned files are work in progress that you need to keep and which are cmake cruft is a pain, especially when much of the cmake files are copies/similarly named to your files. – pavon Aug 25 '15 at 16:05
  • 1
    Another thing with out-of-source builds is that the generated project might not deal well if the src folder is not below the project folder. E.g. if I generate a VS project in the /build, it will compile, but the files are displayed as "external files" and the project cannot generate the structure. Any help for this? – IceFire Jul 10 '16 at 13:55
  • 1
    After becoming really tired for doing the whole "rm -rf build" ... "cmake .." each time I added a solution file, or changed some CMake configuration (e.g. C++17 compilation instead of the default C++11), I started writing the whole thing as a single command line. Use with care ;) ```cd .. && rm -rf build && mkdir build && cd build && CC=`which clang` CXX=`which clang++` cmake ..``` – Olof Bjarnason Apr 12 '17 at 19:56
  • 1
    @OlofBjarnason From within the build directory, just do `rm -r *` and your build directory will be cleaned. Then you don't have to re `mkdir build`, although there is the problem that if you accidentally did it from your source directory, you lost all your files :-/. Maybe your solution is better, but you probably don't need the `-f` for `rm`; `rm -r build` should work for many build directories – Justin May 17 '17 at 17:13
  • 3
    I actually removed my source directory once when I meant to remove the build directly. After that, I wrote a script that double checks what is being erased. But really, cmake should just have a write-only mode for cache, it would solve a lot of issues. – proski Sep 01 '17 at 19:53
  • 2
    Of course, out-of-source builds are the go-to method for Unix Makefiles, but if you're using another generator such as Eclipse CDT, it prefers you to build in-source. What now? `shopt -s globstar && rm -r **/CMakeCache.txt **/*.cmake **/Makefile **/CMakeFiles`? There really ought to be a `cmake clean`. – Chris Watts Nov 09 '17 at 09:33
  • 1
    This command may not be safe. A user may put some third-party libraries in the project. If these libraries don't use cmake but have some matched files, this command will delete them. – zsxwing Nov 09 '17 at 19:56
  • 2
    I accidentally launched cmake in the source directory instead of the build directory and it spammed it full of the generated files and directories. I really, really wish for an "undo". – SF. Nov 28 '17 at 12:02
  • @CJxD , you are awesome and I love your `shopt...` solution which I just aliased to cmake-clean. I would like to suggest adding a `-f` to the `rm` as well to silence any file not found errors printed to STDERR. You really should take all of this and add an answer to the original question, because your solution is by far the best so far. – Michael Goldshteyn Aug 12 '18 at 13:56
  • That is for Linux, etc. What is the command for Windows, say inside a Windows Docker container? – Peter Mortensen Sep 17 '18 at 09:08
  • If 'cmake clean' is such a bad idea, then it should refuse to do a build in the source directory. – Aron Insinga May 14 '19 at 21:21
  • what if after I remove build directory, and then `mkdir build && cd build && cmake .. && make` -- I get missing function error. If I clone git to another folder and do `mkdir build && cd build && cmake .. && make` -- then it works. Where does CMake have other leftovers? – Arkady Nov 15 '19 at 12:50
  • If the `CMakeCache.txt` file is not placed in the `build` directory, then you'll need to delete the `CMakeCache.txt` file as well. Otherwise, values from this cache file may be used during the next CMake attempt. – MikeOnline Jun 04 '20 at 21:57
  • @proski a simple - and fairly reliable - way to avoid accidentally nuking the wrong folder by typing `rm -rf *` is `rm -rf ../build/*` which fails if _build_ isn't the directory being nuked. – John McFarlane Oct 17 '21 at 10:50
  • I don't remember what command it was. Maybe a bash completion followed by Enter before I realized what it was. Anyway, I have no desire to through away my scripts now. My point is that it shouldn't be necessary to remove anything just to have it ignored. – proski Oct 17 '21 at 18:52
  • 2
    CMake 3.24 does not understand `--target clean` or `--clean-first` on MacOS – Matthew Barclay Aug 24 '22 at 02:42
  • Unsure why this is accepted answer. 3.X does not have `--target` or `--clean-first` on MacOS, or Ubuntu, or Windows... – Phill Feb 15 '23 at 11:00
  • cmake's stock clean target fails to remove most of its internal files. The behavior is somehow even worse when using cmake with ninja instead of make. – mcandre Apr 16 '23 at 03:55
114

In these days of Git everywhere, you may forget CMake and use git clean -d -f -x, that will remove all files not under source control.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Jean Davy
  • 2,062
  • 1
  • 19
  • 24
  • 28
    That `-x` option though. That's an excellent trick of the `git` trade. Though I'd personally still do a dry-run first, `git clean -d -f -x -n`. Every once in awhile I keep a convenience file I use for a project in with the project folder under `git` control, but it's not something I want to share with others so I don't `git add` it to the project. This would blow that kind of file away if I wasn't careful to add a `-e ` option. On that note, it would be nice if `git` had a `.gitcleanignore` file. :) – CivFan Oct 15 '15 at 22:45
  • 3
    @CivFan you can try using `chattr +i $filename` (needs root permissions, doesn't allow to modify the file after this). This way git won't be able to remove that file even if it tries to do it like `rm -f`. – Ruslan Oct 18 '15 at 14:26
  • 4
    That assumes in-source builds, which is to be avoided by itself. – Slava Jul 19 '17 at 09:52
  • this was a simple solution (and I have no recollection of what those flags mean, but it's just a dev machine lol). – matanster Nov 23 '17 at 21:03
  • 4
    Um but what about newly added files which user forgot to `git add`? – yugr May 01 '18 at 16:40
  • 1
    great answer; can you please include the notion of combining flag arguments? i.e. ```git clean -dfx```. This also relies on a good .gitignore btw – Seth Sep 01 '18 at 00:27
  • The reason I want a 'make maintainer-clean' is *exactly* because I want to *avoid* deleting files that I created manually but are not in git yet. Such can be (temporary) work files, like test scripts or sources, or crafted files that I need to debug something, or a README that I'm working on but didn't add yet. – Carlo Wood Dec 10 '19 at 19:04
  • as for `-x`, take extra care. some IDEs save their .files in their "workspace dir", you could lose all your custom settings with that thing >_ – Adam.Er8 Aug 25 '20 at 06:48
  • Downvote, because this is not limited to clearing just the CMake files. – irowe Jan 20 '23 at 21:21
  • That is risky, especially when actively debugging gitignore patterns. – mcandre Apr 16 '23 at 03:56
93

CMake official FAQ states:

Some build trees created with GNU autotools have a "make distclean" target that cleans the build and also removes Makefiles and other parts of the generated build system. CMake does not generate a "make distclean" target because CMakeLists.txt files can run scripts and arbitrary commands; CMake has no way of tracking exactly which files are generated as part of running CMake. Providing a distclean target would give users the false impression that it would work as expected. (CMake does generate a "make clean" target to remove files generated by the compiler and linker.)

A "make distclean" target is only necessary if the user performs an in-source build. CMake supports in-source builds, but we strongly encourage users to adopt the notion of an out-of-source build. Using a build tree that is separate from the source tree will prevent CMake from generating any files in the source tree. Because CMake does not change the source tree, there is no need for a distclean target. One can start a fresh build by deleting the build tree or creating a separate build tree.

Community
  • 1
  • 1
Peter Petrik
  • 9,701
  • 5
  • 41
  • 65
  • 4
    Originally, as introduced and used by GNU autotools, the 'distclean' target is intended to make the source tree ready to tar up and create a tar distribution. Such a tar file users can download and untar and then run 'configure' and 'make' *without* needing the autotools (aclocal, automake, autoconf, etc) If we extrapolate that to cmake then a 'make distclean' would leave us with a clean source that can be built without having cmake installed. However, this doesn't work when the generator was a single-target generator (as the 'make' target is), because configuration with cmake happens while – Carlo Wood Dec 10 '19 at 19:09
  • 1
    ... running cmake. Making a distribution that cannot be configured, does not even do platform tests etc, is useless. Hence there does not exist 'distclean' target for cmake. cmake is *required* to exist on the machine of the end-user. – Carlo Wood Dec 10 '19 at 19:10
  • 9
    `we strongly encourage users to adopt the notion of an out-of-source build` -- shame they made it the default behavior then. (Seriously, having the default behavior be something you discourage users from doing is a silly design decision.) – BrainSlugs83 Sep 24 '20 at 21:23
60

I googled it for like half an hour and the only useful thing I came up with was invoking the find utility:

# 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

Also, be sure to invoke make clean (or whatever CMake generator you're using) before that.

:)

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
  • 39
    I would recommend against using this approach if the directory you are working in is under version control: when I tried this approach with svn it removed some of the repositories working files. – bcumming Feb 06 '13 at 13:17
  • Lovely! I'm going to create an alias for this in bashrc or bash_profile. @Yuri: It'd be nice to add a small explanation of what all those parameters mean. – Nav Mar 10 '13 at 08:59
  • 11
    There might other files matching *cmake* so this really is not a universal approach. This should do: rm -rf CMakeFiles; rm -rf CMakeCache.txt; rm -rf cmake_install.cmake; – honza_p Dec 19 '14 at 17:57
  • 1
    I would remove -exec rm -rf {} \+ and just use -delete. –  May 28 '15 at 17:41
  • 4
    Downvoted, since this command can potentially delete some user files. I do prefer honza_p command, not really longer, simpler and less risky. – Adrien Descamps Feb 07 '17 at 09:10
  • I agree with @AdrienDescamps – bartgol Mar 27 '17 at 14:16
  • 2
    @AdrienDescamps: except it still leaves cmake-related junk in subdirectories. I was doing `rm -rf CMakeFiles ; rm -rf */CMakeFiles ; rm -rf */*/CMakeFiles ; rm -rf */*/*/CMakeFiles` and still wasn't done... – SF. Nov 28 '17 at 12:16
  • 1
    If someone executes this command in my source tree, I will shoot them. – Erki Aring Jan 28 '18 at 20:09
  • This is a bad advise - deleting *randomly* all files with *cmake* in it would (for example) destroy my project (if I didn't have a backup). – Carlo Wood Dec 10 '19 at 18:57
  • `find` is non-portable for COMSPEC Windows users. `-not` is non-portable for non-Linux/non-POSIX users. `rm` is non-portable for COMSPEC Windows users. Also not futureproof. Also ignores make and ninja files. Also, incredible risk of accidentally deleting a file just because it is named similarly to cmake. – mcandre Apr 16 '23 at 03:59
40

You can use something like:

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)

I usually create a "make clean-all" command adding a call to "make clean" to the previous example:

add_custom_target(clean-all
   COMMAND ${CMAKE_BUILD_TOOL} clean
   COMMAND ${CMAKE_COMMAND} -P clean-all.cmake
)

Don't try to add the "clean" target as a dependence:

add_custom_target(clean-all
   COMMAND ${CMAKE_COMMAND} -P clean-all.cmake
   DEPENDS clean
)

Because "clean" isn't a real target in CMake and this doesn't work.

Moreover, you should not use this "clean-cmake-files" as dependence of anything:

add_custom_target(clean-all
   COMMAND ${CMAKE_BUILD_TOOL} clean
   DEPENDS clean-cmake-files
)

Because, if you do that, all CMake files will be erased before clean-all is complete, and make will throw you an error searching "CMakeFiles/clean-all.dir/build.make". In consequence, you can not use the clean-all command before "anything" in any context:

add_custom_target(clean-all
   COMMAND ${CMAKE_BUILD_TOOL} clean
   COMMAND ${CMAKE_COMMAND} -P clean-all.cmake
)

That doesn't work either.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
ABu
  • 10,423
  • 6
  • 52
  • 103
  • Is there a way to fill cmake_generated automatically? Perhaps, combining this with the answer of yuri.makarevich? Currently, this won't remove files in the subdirectories of ${CMAKE_BINARY_DIR}. – foxcub Feb 01 '14 at 00:11
  • Does not work for Ninja or Visual studio. I wouldn't recommend such an approach. – usr1234567 Nov 09 '17 at 08:40
  • Nice idea but this does not remove `CMakeCache.txt` and not help me too, but I found this similar way to update variables in every build, so no need to remove `CMakeCache.txt`: https://stackoverflow.com/questions/53159371/how-to-create-a-cmake-variable-that-takes-a-default-value-unless-explicitly-over/53159688#53159688 – Celuk Feb 08 '22 at 11:38
37

Simply issuing rm CMakeCache.txt works for me too.

user1480788
  • 514
  • 4
  • 8
  • 1
    Only deleting related variables in CMakeCache.txt works for me too. – Yorkwar Jan 19 '16 at 11:55
  • Deleting CMakeCache.txt and then running 'cmake --build /build-path' causes 'Error: could not load cache'. – nenchev Oct 28 '17 at 21:57
  • 2
    @nenchev you need to run `cmake /build-path` again. – Samaursa Oct 29 '17 at 19:56
  • 1
    @Samaursa cmake --build reruns cmake when needed, this method breaks the build directory and cmake complains. My answer further down tells you to delete the CMakeFiles/ directory, which causes a clean rebuild and cmake to automatically rerun. – nenchev Oct 29 '17 at 20:47
  • @nenchev when you manually delete the cache, you have to run `cmake /build-path` again as it expects a cache file to exist when the `CMakeFiles` directory does. Of course, if you delete the `CMakeFiles` directory, then `CMake --build` will know to run `CMake`. One of the reasons this is important to know (and I wish there was a `CMake --cleancache` or similar) is because in large builds, deleting `CMakeFiles` can trigger a time consuming generate (and a search for compilers, which on Windows takes an unusually long time). Deleting the `CMakeCache.txt` and running `CMake` again is faster. – Samaursa Oct 30 '17 at 12:08
  • @Samaursa My point is that deleting the CMakeCache.txt leaves the build directory in a messed up state, requiring you to rerun cmake /build-path. I obviously know that CMakeCache is expected, and the point I'm making is that deleting just that file forces you to explicitly rerun cmake, after which if you run the build, it doesn't actually rebuild everything (clean build). Maybe I misunderstood, but a clean build to me is like any other build system, recreate build files, recompile sources. – nenchev Oct 30 '17 at 17:13
  • 2
    @nenchev I see what you mean and I agree. – Samaursa Oct 30 '17 at 18:33
  • Really the best answer so far. – yugr May 01 '18 at 16:57
  • Not, if you have several caches in different subdirs. – Wör Du Schnaffzig Aug 26 '22 at 12:18
21

Starting with CMake 3.24, there exists the --fresh command line option which rebuilds the entire build tree every time:

--fresh

New in version 3.24.

Perform a fresh configuration of the build tree. This removes any existing CMakeCache.txt file and associated CMakeFiles/ directory, and recreates them from scratch.

https://cmake.org/cmake/help/latest/manual/cmake.1.html#options

SkryptX
  • 813
  • 1
  • 9
  • 24
  • That doesn't begin to delete all the different junk files that a typical cmake project generates. – mcandre Apr 16 '23 at 04:00
  • @mcandre No it doesn't, but it doesn't matter. The build tree gets regenerated including the cache. So the build output should be unaffected regardless of junk files that may or may not be there. – SkryptX Apr 17 '23 at 10:21
19

Maybe it's a little outdated, but since this is the first hit when you google cmake clean, I will add this:

Since you can start a build in the build dir with a specified target with

cmake --build . --target xyz

you can of course run

cmake --build . --target clean

to run the clean target in the generated build files.

redleg
  • 287
  • 3
  • 3
9

I agree that the out-of-source build is the best answer. But for the times when you just must do an in-source build, I have written a Python script available here, which:

  1. Runs "make clean"
  2. Removes specific CMake-generated files in the top-level directory such as CMakeCache.txt
  3. For each subdirectory that contains a CMakeFiles directory, it removes CMakeFiles, Makefile, cmake_install.cmake.
  4. Removes all empty subdirectories.
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
tschutter
  • 107
  • 1
  • 1
  • Thanks for that. I would like to add a line to your script that silences `make` when there is no `Makefile` present due to a prior clean (i.e., makes this script idempotent). Just add the line (properly spaced): `if os.path.isfile(os.path.join(directory,'Makefile')):` right before line 24: `args = [` and of course indent the rest of the function body after the line just added. This will only perform a `make ... clean` if a `Makefile` is present in the current directory being cleaned. Otherwise, the script is perfect! – Michael Goldshteyn Aug 12 '18 at 14:10
  • _"But for the times when you just must do an in-source build"_ When exactly are those times, though? I hope they're few and far between, these days, and that whenever you encounter one, you file a bug with the maintainers asking them to fix their build tooling. Any project that uses CMake, at least, needs to support out-of-source builds, otherwise their code is a chore to use with `ExternalProject` (requires `BUILD_IN_SOURCE`, implied goat sacrifice), and I'm not even sure it's possible with `FetchContent` since it lacks a similar option. – FeRD Sep 27 '21 at 05:17
8

It's funny to see this question gets so many attentions and complicated solutions, which indeed shows a pain to not have a clean method with cmake.

Well, you can definitely cd build_work to do you work, then do a rm -rf * when you need to clean. However, rm -rf * is a dangerous command given that many people are often not aware which dir they are in.

If you cd .., rm -rf build_work and then mkdir build_work and then cd build_work, that's just too much typing.

So a good solution is to just stay out of the build folder and tell cmake the path:
to configure: cmake -B build_work
to build: cmake --build build_work
to install: cmake --install build_work
to clean: rm -rf build_work
to recreate build folder: you don't even need mkdir build_work, just configure it with cmake -B build_work.

frank
  • 178
  • 2
  • 7
7

In the case where you pass -D parameters into CMake when generating the build files and don't want to delete the entire build/ directory:

Simply delete the CMakeFiles/ directory inside your build directory.

rm -rf CMakeFiles
cmake --build .

This causes CMake to rerun, and build system files are regenerated. Your build will also start from scratch.

mcandre
  • 22,868
  • 20
  • 88
  • 147
nenchev
  • 1,998
  • 28
  • 16
  • It is not enough. CMakeCache.txt has to be deleted as well (like for found libs). – Pierre Aug 12 '21 at 12:16
  • `rm` is not portable; it fails in Command Prompt. Yes, PowerShell, WSL, and Cygwin-like environments can provide a workaround. But I like my stuff to work more portably than that. Using rez as a workaround. https://github.com/mcandre/rez – mcandre Apr 15 '23 at 22:01
5

try to use: cmake --clean-first path-of-CMakeLists.txt-file -B output-dir

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

赏心悦目
  • 1,603
  • 1
  • 12
  • 12
  • That screen shot shows **text** only. Yet you take a screen shot of it, breaking the answer for anybody who comes here with a screenreader. Please drop that picture, and do a copy/paste of text, and spend the 1 minute to properly format that input. – GhostCat Jun 21 '19 at 12:52
  • what do you mean by use --target clean. $ cmake --target clean CMake Error: Unknown argument --target CMake Error: Run 'cmake --help' for all supported options. – shirish Jul 12 '22 at 17:35
5

CMake 3.X

CMake 3.0 and above offers a 'clean' target. This removes any artifacts like object files, library files, executables, generated files, etc.

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

You can also clean the build, then run the build. In 1 command.

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

However, this WON'T cleanup things like the CMakeCache.txt or the associated CMakeFiles/ directory. Which you may want to do. You just have to delete the build folder.

# 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

Now in CMake 3.24 you can perform a fresh configuration of the build tree. This removes any existing CMakeCache.txt file and associated CMakeFiles/ directory, and recreates them from scratch.

Generally you want to do this when:

  • You want to clear cached variable in CMakeCache.txt
  • You want to change compilers
  • Any other operations related to CMake caching
cmake -B C:/foo/build --fresh
jpr42
  • 718
  • 3
  • 14
4

Of course, out-of-source builds are the go-to method for Unix Makefiles, but if you're using another generator such as Eclipse CDT, it prefers you to build in-source. In which case, you'll need to purge the CMake files manually. Try this:

find . -name 'CMakeCache.txt' -o -name '*.cmake' -o -name 'Makefile' -o -name 'CMakeFiles' -exec rm -rf {} +

Or if you've enabled globstar with shopt -s globstar, try this less disgusting approach instead:

rm -rf **/CMakeCache.txt **/*.cmake **/Makefile **/CMakeFiles
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Chris Watts
  • 6,197
  • 7
  • 49
  • 98
  • My choice yesterday was cloning repo to a new folder, update CMakeLists.txt to build from subfolder `build`. It took a little longer time than those commands but I had to do it one time only :) – Tien Do Sep 01 '18 at 06:40
3

A solution that I found recently is to combine the out-of-source build concept with a Makefile wrapper.

In my top-level CMakeLists.txt file, I include the following to prevent in-source builds:

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()

Then, I create a top-level Makefile, and include the following:

# -----------------------------------------------------------------------------
# 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

The default target all is called by typing make, and invokes the target ./build/Makefile.

The first thing the target ./build/Makefile does is to create the build directory using $(MKDIR), which is a variable for mkdir -p. The directory build is where we will perform our out-of-source build. We provide the argument -p to ensure that mkdir does not scream at us for trying to create a directory that may already exist.

The second thing the target ./build/Makefile does is to change directories to the build directory and invoke cmake.

Back to the all target, we invoke $(MAKE) -C build, where $(MAKE) is a Makefile variable automatically generated for make. make -C changes the directory before doing anything. Therefore, using $(MAKE) -C build is equivalent to doing cd build; make.

To summarize, calling this Makefile wrapper with make all or make is equivalent to doing:

mkdir build
cd build
cmake ..
make 

The target distclean invokes cmake .., then make -C build clean, and finally, removes all contents from the build directory. I believe this is exactly what you requested in your question.

The last piece of the Makefile evaluates if the user-provided target is or is not distclean. If not, it will change directories to build before invoking it. This is very powerful because the user can type, for example, make clean, and the Makefile will transform that into an equivalent of cd build; make clean.

In conclusion, this Makefile wrapper, in combination with a mandatory out-of-source build CMake configuration, make it so that the user never has to interact with the command cmake. This solution also provides an elegant method to remove all CMake output files from the build directory.

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.

Another thing to note: This Makefile may not work if you use a variable number of CMake variables to build your project, for example, cmake .. -DSOMEBUILDSUSETHIS:STRING="foo" -DSOMEOTHERBUILDSUSETHISTOO:STRING="bar". This Makefile assumes you invoke CMake in a consistent way, either by typing cmake .. or by providing cmake a consistent number of arguments (that you can include in your Makefile).

Finally, credit where credit is due. This Makefile wrapper was adapted from the Makefile provided by the C++ Application Project Template.

  • I suggest to never use a `Makefile` as a meta-builder. It is really disturbing and error prone. If you want to do that, write a script (eg `build.sh`) – Jérôme Pouiller May 13 '22 at 10:00
2

I use the following shell script for such purposes:

#!/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

If you are using Windows then use Cygwin for this script.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
yanpas
  • 2,155
  • 1
  • 17
  • 26
2

Clear the cmake build output:

Command line:

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

Cmake:

cmake --build . --target clean
0

To simplify cleaning when using "out of source" build (i.e. you build in the build directory), I use the following script:

$ 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

Every time you need to clean up, you should source this script from the build directory:

. cmake-clean-build
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Alexander Lobov
  • 386
  • 2
  • 11
  • Nice and safe. As I you may have the build directory opened in file manager, I suggest replacing the `cd .. ; rm ; mkdir ; cd` sequence with `cd .. ; rm -rf build/*`. – Mostafa Farzán Jul 20 '19 at 21:24
0

--fresh (cmake version 3.24 or later)

Can be used to remove the previous cache file and recreate the build tree.

-1

If you run

cmake .

it will regenerate the CMake files. Which is necessary if you add a new file to a source folder that is selected by *.cc, for example.

While this isn't a "clean" per se, it does "clean" up the CMake files by regenerating the caches.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Homer6
  • 15,034
  • 11
  • 61
  • 81
  • 1
    It does not clean wrt. the compilation state: If 500 out of 1200 files have been compiled, after "cmake ." it will just continue with the last 700 files. – Peter Mortensen Sep 17 '18 at 17:04
-1

This is pretty old, but if you completely remove the cmake-build-debug folder, when you compile using cmake it should automatically create a new cmake-build-debug folder with everything you need. Works especially well in CLion.

-2

If you have custom defines and want to save them before cleaning, run the following in your build directory:

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

Then create a new build directory (or remove the old build directory and recreate it) and finally run cmake with the arguments you'll get with the script above.

Zouppen
  • 1,214
  • 11
  • 17
-2

cmake mostly cooks a Makefile, one could add rm to the clean PHONY.

For example,

[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
LinconFive
  • 1,718
  • 1
  • 19
  • 24
-2

Here is what I use. It's wrapped in a function, It's cross platform and it demonstrated how to find matching filenames or folder names, in case you wanted to make any easy adjustments. This function runs every time I build my scripts and has worked flawlessly for my needs.

function(DELETE_CACHE)
    if(CMAKE_HOST_WIN32)
        execute_process(COMMAND cmd /c for /r %%i in (CMakeCache.*) do del "%%i" WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
        execute_process(COMMAND cmd /c for /d /r %%i in (*CMakeFiles*) do rd /s /q "%%i" WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
    else()
        execute_process(COMMAND find . -name "CMakeCache.*" -delete WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
        execute_process(COMMAND "rm -rf `find . -type d -name CMakeFiles`" WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
    endif()
endfunction()
aquawicket
  • 524
  • 1
  • 9
  • 27
-3

I used zsxwing's answer successfully to solve the following problem:

I have source that I build on multiple hosts (on a Raspberry Pi Linux board, on a VMware Linux virtual machine, etc.)

I have a Bash script that creates temporary directories based on the hostname of the machine like this:

# 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
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
-9

Create a temporary build directory, for example, build_cmake. Hence all your build files will be inside this folder.

Then in your main CMake file add the below command.

add_custom_target(clean-all
    rm -rf *
)

Hence while compiling do

cmake ..

And to clean do:

make clean-all
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Natesh
  • 7
  • 1