it-swarm.com.de

Suchen Sie nach einem Befehl 'cmake clean', um die CMake-Ausgabe zu löschen

So wie make clean alle Dateien löscht, die ein Makefile erstellt hat, möchte ich das auch mit CMake machen. Zu oft gehe ich manuell durch Verzeichnisse und entferne Dateien wie cmake_install.cmake und CMakeCache.txt sowie die CMakeFiles-Ordner.

Gibt es einen Befehl wie cmake clean, um alle diese Dateien automatisch zu entfernen? Im Idealfall sollte dies der rekursiven Struktur folgen, die in der CMakeLists.txt-Datei des aktuellen Verzeichnisses definiert ist.

311
Bill Cheatham

Es gibt keinen cmake clean.

Ich baue das Projekt normalerweise in einem einzigen Ordner wie "build". Wenn ich also make clean möchte, kann ich einfach rm -rf build.

Der Ordner "build" im selben Verzeichnis wie das Stammverzeichnis "CMakeLists.txt" ist normalerweise eine gute Wahl. Um Ihr Projekt zu erstellen, geben Sie einfach den Ort der Datei CMakeLists.txt als Argument an. Zum Beispiel: cd <location-of-cmakelists>/build && cmake ... (Von @ComicSansMS)

378
zsxwing

CMake offiziell FAQ heißt:

Einige Build-Trees, die mit GNU Autotools erstellt wurden, haben ein "make distclean" Ziel, das den Build bereinigt und auch Makefiles und andere .__ entfernt. Teile des generierten Build-Systems. CMake generiert kein "make Distclean" -Ziel, da CMakeLists.txt-Dateien Skripts und .__ ausführen können. beliebige Befehle; CMake kann nicht genau nachverfolgen, welche Dateien werden als Teil des laufenden CMake generiert. Bereitstellen eines distclean-Ziels Benutzer würden den falschen Eindruck erwecken, dass es wie erwartet funktionieren würde. (CMake generiert ein "make clean" -Ziel, um vom Compiler und vom Linker generierte Dateien zu entfernen.) 

Ein "distclean machen" -Ziel ist nur erforderlich, wenn der Benutzer einen In-Source-Build ausführt. CMake unterstützt In-Source-Builds, aber wir empfehlen Benutzern dringend, den Begriff .__ zu übernehmen. eines Out-of-Source-Builds. Verwenden eines Build-Baums, der von .__ getrennt ist. Die Quellstruktur verhindert, dass CMake Dateien in der .__-Datei generiert. Quellbaum. Da CMake die Quellstruktur nicht ändert, gibt es kein distclean ziel erforderlich. Man kann einen neuen Build mit .__ beginnen. Löschen des Build-Baums oder Erstellen eines separaten Build-Baums.

61
Peter

Ich habe es eine halbe Stunde lang gegoogelt und das einzig Nützliche, was ich fand, war das Aufruf des find-Dienstprogramms:

# 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

Stellen Sie außerdem sicher, dass Sie make clean (oder den von Ihnen verwendeten CMake-Generator) vor that aufrufen.

:)

45
user1614309

In diesen Tagen von Git können Sie CMake vergessen und git clean -d -f -x verwenden, um alle Dateien zu entfernen, die nicht der Quellcodeverwaltung unterliegen.

44
Jean Davy

Sie können so etwas verwenden:

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)

Normalerweise erstelle ich den Befehl "make clean-all" und füge dem vorherigen Beispiel einen Aufruf für "make clean" hinzu:

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

Versuchen Sie nicht, das "saubere" Ziel als Abhängigkeit hinzuzufügen:

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

Weil "sauber" in CMake kein echtes Ziel ist und dies nicht funktioniert.

Außerdem sollten Sie diese "clean-cmake-Dateien" nicht als Abhängigkeit von irgendetwas verwenden:

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

Wenn Sie dies tun, werden alle CMake-Dateien gelöscht, bevor clean-all abgeschlossen ist, und make gibt einen Fehler bei der Suche nach "CMakeFiles/clean-all.dir/build.make" aus. Infolgedessen können Sie den Clean-All-Befehl vor "irgendetwas" in keinem Kontext verwenden:

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

Das geht auch nicht.

29
Peregring-lk

Die einfache Ausgabe von rm CMakeCache.txt funktioniert auch für mich.

18
user1480788

Ich stimme zu, dass der Out-of-Source-Build die beste Antwort ist. Aber für die Zeiten, in denen Sie nur einen In-Source-Build durchführen müssen, habe ich ein Python-Skript geschrieben, das here verfügbar ist.

  1. Läuft "sauber machen"
  2. Entfernt bestimmte von CMake generierte Dateien im obersten Verzeichnis, z. B. CMakeCache.txt
  3. Für jedes Unterverzeichnis, das ein CMakeFiles-Verzeichnis enthält, werden CMakeFiles, Makefile, cmake_install.cmake entfernt.
  4. Entfernt alle leeren Unterverzeichnisse.
7
tschutter

Eine Lösung, die ich kürzlich gefunden habe, ist die Kombination des Out-of-Source-Build-Konzepts mit einem Makefile-Wrapper.

In meine oberste CMakeLists.txt-Datei füge ich Folgendes hinzu, um In-Source-Builds zu verhindern:

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

Dann erstelle ich ein Makefile der obersten Ebene und füge Folgendes hinzu:

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

Das Standardziel all wird durch Eingabe von make aufgerufen und ruft das Ziel ./build/Makefile auf.

Als Erstes erstellt das Ziel ./build/Makefile das Verzeichnis build mit $(MKDIR), einer Variablen für mkdir -p. In dem Verzeichnis build führen wir unseren Out-of-Source-Build aus. Wir stellen das Argument -p zur Verfügung, um sicherzustellen, dass mkdir uns nicht anschreit, weil Sie versuchen, ein Verzeichnis zu erstellen, das möglicherweise bereits existiert.

Das zweite, was das Ziel ./build/Makefile tut, ist, Verzeichnisse in das Verzeichnis build zu ändern und cmake aufzurufen.

Zurück zum Ziel all rufen wir $(MAKE) -C build auf, wobei $(MAKE) eine Makefile-Variable ist, die automatisch für make generiert wird. make -C wechselt das Verzeichnis, bevor Sie etwas tun. Daher ist die Verwendung von $(MAKE) -C build gleichbedeutend mit cd build; make.

Zusammenfassend ist das Aufrufen dieses Makefile-Wrappers mit make all oder make gleichbedeutend mit:

mkdir build
cd build
cmake ..
make 

Das Ziel distclean ruft cmake .., dann make -C build clean auf und entfernt schließlich den gesamten Inhalt aus dem Verzeichnis build. Ich glaube, genau das haben Sie in Ihrer Frage gefordert.

Der letzte Teil des Makefiles wertet aus, ob das vom Benutzer angegebene Ziel distclean ist oder nicht. Wenn nicht, werden die Verzeichnisse vor dem Aufruf in build geändert. Dies ist sehr leistungsfähig, da der Benutzer beispielsweise make clean eingeben kann und das Makefile dies in ein Äquivalent von cd build; make clean umwandelt.

Zusammenfassend lässt sich sagen, dass dieser Makefile-Wrapper in Kombination mit einer obligatorischen CMake-Konfiguration für Out-of-Source-Builds dafür sorgt, dass der Benutzer niemals mit dem Befehl cmake interagieren muss. Diese Lösung bietet auch eine elegante Methode zum Entfernen aller CMake-Ausgabedateien aus dem Verzeichnis build.

P.S. Im Makefile verwenden wir das Präfix @, um die Ausgabe eines Shell-Befehls zu unterdrücken, und das Präfix @-, um Fehler eines Shell-Befehls zu ignorieren. Wenn Sie rm als Teil des distclean-Ziels verwenden, gibt der Befehl einen Fehler zurück, wenn die Dateien nicht vorhanden sind (sie wurden möglicherweise bereits mit der Befehlszeile mit rm -rf build gelöscht oder gar nicht erst generiert). Dieser Rückgabefehler zwingt unser Makefile zum Beenden. Um dies zu verhindern, verwenden wir das Präfix @-. Es ist akzeptabel, wenn eine Datei bereits entfernt wurde. Wir möchten, dass unser Makefile weiterläuft und den Rest entfernt.

Zu beachten ist noch Folgendes: Dieses Makefile funktioniert möglicherweise nicht, wenn Sie eine variable Anzahl von CMake-Variablen zum Erstellen Ihres Projekts verwenden, z. B. cmake .. -DSOMEBUILDSUSETHIS:STRING="foo" -DSOMEOTHERBUILDSUSETHISTOO:STRING="bar". Dieses Makefile setzt voraus, dass Sie CMake auf konsistente Weise aufrufen, indem Sie entweder cmake .. eingeben oder cmake eine konsistente Anzahl von Argumenten angeben (die Sie in Ihr Makefile aufnehmen können).

Schließlich Guthaben, bei dem Guthaben fällig ist. Dieser Makefile-Wrapper wurde vom Makefile der C++ Application Project Template angepasst.

4

Vielleicht ist es etwas veraltet, aber da dies der erste Treffer ist, wenn Sie auf cmake clean gehen, werde ich Folgendes hinzufügen:

Da kann man einen Build im Build-Verzeichnis mit einem angegebenen Ziel mit starten

cmake --build . --target xyz

du kannst natürlich laufen

cmake --build . --target clean

um das clean-Ziel in den generierten Build-Dateien auszuführen.

3
redleg

Out-of-Source-Builds sind natürlich die gängige Methode für Unix-Makefiles. Wenn Sie jedoch einen anderen Generator wie Eclipse CDT verwenden, wird der In-Source-Build bevorzugt. In diesem Fall müssen Sie die CMake-Dateien manuell bereinigen. Versuche dies:

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

Wenn Sie globstar mit shopt -s globstar aktiviert haben, versuchen Sie stattdessen diesen weniger ekelhaften Ansatz:

rm -rf **/CMakeCache.txt **/*.cmake **/Makefile **/CMakeFiles
2
CJxD

Wenn Sie beim Generieren der Builddateien -D-Parameter an CMake übergeben und nicht das gesamte build/-Verzeichnis löschen möchten:

Löschen Sie einfach das CMakeFiles/-Verzeichnis in Ihrem Build-Verzeichnis.

rm -rf CMakeFiles/
cmake --build .

Dies führt dazu, dass CMake erneut ausgeführt wird und Build-Systemdateien neu erstellt werden. Ihr Build wird auch bei Null beginnen.

2
nenchev

Wenn du läufst

cmake .

die CMake-Dateien werden neu erstellt. Dies ist erforderlich, wenn Sie einem Quellordner, der beispielsweise von * .cc ausgewählt wird, eine neue Datei hinzufügen.

Dies ist zwar an sich nicht "sauber", aber "Bereinigen" Sie die CMake-Dateien, indem Sie die Caches regenerieren.

0
Homer6

Um die Reinigung zu vereinfachen, wenn "out of source" verwendet wird (d. H. Sie erstellen im Verzeichnis build), verwende ich das folgende Skript:

$ 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

Jedes Mal, wenn Sie bereinigen müssen, sollten Sie dieses Skript aus dem Verzeichnis build beziehen:

. cmake-clean-build
0
Alexander

versuchen Sie Folgendes zu verwenden: cmake --clean-first Pfad-von-CMakeLists.txt-Datei -B Ausgabeverzeichnis

--clean-first: Ziel erst bereinigen, dann erstellen.
(Verwenden Sie --target clean, um nur zu reinigen.)

0
赏心悦目

Wenn Sie benutzerdefinierte Definitionen haben und diese vor dem Bereinigen speichern möchten, führen Sie Folgendes in Ihrem Build-Verzeichnis aus:

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

Erstellen Sie dann ein neues Build-Verzeichnis (oder entfernen Sie das alte Build-Verzeichnis und erstellen Sie es erneut), und führen Sie schließlich cmake mit den Argumenten aus, die Sie mit dem obigen Skript erhalten.

0
Zouppen

Ich benutze das folgende Shell-Skript für solche Zwecke:

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

Wenn Sie Windows verwenden, verwenden Sie Cygwin für dieses Skript.

0
yanpas