Podobnie jak make clean
usuwa wszystkie pliki utworzone przez plik makefile, chciałbym zrobić to samo z CMake. Zbyt często ręcznie przeglądam katalogi usuwając pliki takie jak cmake_install.cmake
i CMakeCache.txt
oraz CMakeFiles
foldery.
Czy istnieje polecenie, cmake clean
aby automatycznie usunąć wszystkie te pliki? Najlepiej byłoby, gdyby podążała za strukturą rekurencyjną zdefiniowaną w CMakeLists.txt
pliku bieżącego katalogu .
cd <location-of-cmakelists>/build && cmake ..
Oficjalne FAQ CMake stanowi:
źródło
W dzisiejszych czasach Gita wszędzie możesz zapomnieć o CMake i użyciu
git clean -d -f -x
, który usunie wszystkie pliki nie będące pod kontrolą źródła.źródło
-x
opcja jednak. To doskonała sztuczka wgit
handlu. Chociaż ja osobiście nadal robić sucho pierwszygit clean -d -f -x -n
. Co jakiś czas przechowuję plik wygody, którego używam dla projektu w folderze projektu podgit
kontrolą, ale nie chcę tego udostępniać innym, więc nie przesyłamgit add
go do projektu. Spowodowałoby to zniszczenie tego rodzaju pliku, gdybym nie ostrożnie dodawał-e <pattern>
opcji. Przy tej notatce byłoby miło, gdybygit
miał.gitcleanignore
plik. :)chattr +i $filename
(wymaga uprawnień roota, nie pozwala na modyfikację pliku po tym). W ten sposób git nie będzie w stanie usunąć tego pliku, nawet jeśli spróbuje to zrobić w podobny sposóbrm -f
.git add
?Przeglądałem go przez około pół godziny i jedyną przydatną rzeczą, jaką wymyśliłem, było wywołanie
find
narzędzia:Należy także pamiętać, aby wywołać
make clean
(lub cokolwiek CUpewnij generator używasz) przed tym.:)
źródło
rm -rf CMakeFiles ; rm -rf */CMakeFiles ; rm -rf */*/CMakeFiles ; rm -rf */*/*/CMakeFiles
i wciąż nie skończyłem ...Możesz użyć czegoś takiego jak:
Zwykle tworzę polecenie „make clean-all”, dodając wywołanie „make clean” do poprzedniego przykładu:
Nie próbuj dodawać „czystego” celu jako zależności:
Ponieważ „czyste” nie jest prawdziwym celem w CMake i to nie działa.
Co więcej, nie powinieneś używać tych „czystych cmake-plików” jako zależności czegokolwiek:
Ponieważ jeśli to zrobisz, wszystkie pliki CMake zostaną usunięte przed zakończeniem czyszczenia, a make wyświetli błąd podczas wyszukiwania „CMakeFiles / clean-all.dir / build.make”. W związku z tym nie można użyć polecenia wyczyść wszystko przed „niczym” w dowolnym kontekście:
To też nie działa.
źródło
Po prostu wydawanie
rm CMakeCache.txt
działa również dla mnie.źródło
cmake /build-path
ponownie.Może to trochę przestarzałe, ale ponieważ jest to pierwszy hit, gdy google
cmake clean
, dodam to:Ponieważ możesz rozpocząć kompilację w katalogu kompilacji z określonym celem za pomocą
cmake --build . --target xyz
oczywiście możesz biegać
cmake --build . --target clean
aby uruchomić
clean
cel w wygenerowanych plikach kompilacji.źródło
Zgadzam się, że najlepsza odpowiedź to wersja spoza źródła. Ale w czasach, gdy musisz po prostu zbudować kompilację źródłową, napisałem dostępny tutaj skrypt w języku Python , który:
źródło
make
gdy nie ma go zMakefile
powodu wcześniejszego wyczyszczenia (tzn. Czyni ten skrypt idempotentnym). Wystarczy dodać linię (właściwie rozmieszczoną):if os.path.isfile(os.path.join(directory,'Makefile')):
tuż przed linią 24:args = [
i oczywiście wciąć resztę funkcji po dodanej właśnie linii. Wykona to tylkomake ... clean
wtedy, gdy aMakefile
jest obecny w czyszczonym katalogu bieżącym. W przeciwnym razie skrypt jest idealny!Rozwiązaniem, które ostatnio znalazłem, jest połączenie koncepcji kompilacji poza źródłami z pakietem Makefile.
Do mojego najwyższego poziomu pliku CMakeLists.txt dołączam następujące elementy, aby zapobiec kompilacjom źródłowym:
Następnie tworzę plik Makefile najwyższego poziomu i dołączam następujące elementy:
Domyślny cel
all
jest wywoływany przez wpisaniemake
i wywołuje cel./build/Makefile
.Pierwszą rzeczą, którą
./build/Makefile
robi cel , jest utworzeniebuild
katalogu$(MKDIR)
, który jest zmienną dlamkdir -p
. Katalogbuild
jest miejscem, w którym wykonamy naszą kompilację poza źródłami. Podajemy argument,-p
aby upewnić się, żemkdir
nie krzyczy na nas próba stworzenia katalogu, który może już istnieć.Drugą rzeczą, którą
./build/Makefile
robi cel , jest zmiana katalogów dobuild
katalogu i wywołaniecmake
.Wracamy do
all
celu,$(MAKE) -C build
gdzie wywołujemy$(MAKE)
zmienną Makefile , dla której jest automatycznie generowanamake
.make -C
zmienia katalog przed zrobieniem czegokolwiek. Dlatego używanie$(MAKE) -C build
jest równoważne działaniucd build; make
.Podsumowując, wywołanie tego opakowania Makefile za pomocą
make all
lubmake
jest równoważne z:Cel
distclean
wywołujecmake ..
, a następniemake -C build clean
ostatecznie usuwa całą zawartość zbuild
katalogu. Uważam, że dokładnie o to prosiłeś w swoim pytaniu.Ostatni fragment pliku Makefile ocenia, czy podany przez użytkownika cel jest, czy nie
distclean
. Jeśli nie, zmieni katalogi nabuild
przed wywołaniem. Jest to bardzo potężne, ponieważ użytkownik może na przykład pisaćmake clean
, a Makefile przekształci go w odpowiednikcd build; make clean
.Podsumowując, to opakowanie Makefile w połączeniu z obowiązkową konfiguracją CMake kompilacji poza źródłami sprawia, że użytkownik nigdy nie musi wchodzić w interakcje z poleceniem
cmake
. To rozwiązanie zapewnia również elegancką metodę usuwania wszystkich plików wyjściowych CMake zbuild
katalogu.PS W pliku Makefile używamy prefiksu,
@
aby ukryć dane wyjściowe polecenia powłoki, a prefiksu,@-
aby ignorować błędy polecenia powłoki. Podczas używaniarm
jako elementudistclean
docelowego polecenie zwróci błąd, jeśli pliki nie istnieją (mogły zostać usunięte już przy użyciu wiersza polecenia zrm -rf build
lub nigdy nie zostały wygenerowane). Ten błąd powrotu zmusi nasz Makefile do wyjścia. Używamy przedrostka,@-
aby temu zapobiec. Dopuszczalne jest, jeśli plik został już usunięty; chcemy, aby nasz Makefile kontynuował pracę i usunął resztę.Kolejna rzecz do zapamiętania: ten plik Makefile może nie działać, jeśli na przykład używasz zmiennej liczby zmiennych CMake do zbudowania projektu
cmake .. -DSOMEBUILDSUSETHIS:STRING="foo" -DSOMEOTHERBUILDSUSETHISTOO:STRING="bar"
. Ten Makefile zakłada, że wywołujesz CMake w spójny sposób, wpisująccmake ..
lub podająccmake
stałą liczbę argumentów (które możesz dołączyć do swojego Makefile).Wreszcie kredyt, w którym kredyt jest należny. To opakowanie Makefile zostało zaadaptowane z pliku Makefile dostarczonego przez szablon projektu aplikacji C ++ .
źródło
Oczywiście, kompilacje poza źródłami są metodą przejścia do Uniksowych Makefile, ale jeśli używasz innego generatora, takiego jak Eclipse CDT, preferujesz kompilację w źródle. W takim przypadku musisz ręcznie wyczyścić pliki CMake. Spróbuj tego:
Lub jeśli włączyłeś globstar z
shopt -s globstar
, spróbuj zamiast tego mniej obrzydliwego podejścia:źródło
build
. Trwało to trochę dłużej niż te polecenia, ale musiałem to zrobić tylko raz :)spróbuj użyć: cmake --clean-first path-of-CMakeLists.txt-file -B output-dir
--clean-first: najpierw buduj cel, a potem buduj.
(Tylko do czyszczenia użyj --target clean.)
źródło
W przypadku, gdy przekazujesz
-D
parametry do CMake podczas generowania plików kompilacji i nie chcesz usuwać całego katalogu kompilacji /:Po prostu usuń katalog CMakeFiles / z katalogu kompilacji.
Powoduje to ponowne uruchomienie CMake i generowanie plików systemowych. Twoja kompilacja rozpocznie się również od zera.
źródło
Aby uprościć czyszczenie podczas korzystania z kompilacji „poza źródłem” (tj. Kompilujesz w
build
katalogu), używam następującego skryptu:Za każdym razem, gdy musisz wyczyścić, skrypt powinien pochodzić z
build
katalogu:źródło
cd .. ; rm ; mkdir ; cd
sekwencji nacd .. ; rm -rf build/*
.Jeśli masz niestandardowe definicje i chcesz je zapisać przed czyszczeniem, uruchom następujące polecenie w katalogu kompilacji:
Następnie utwórz nowy katalog kompilacji (lub usuń stary katalog kompilacji i utwórz go ponownie), a na koniec uruchom
cmake
z argumentami, które otrzymasz za pomocą powyższego skryptu.źródło
Jeśli uciekniesz
zregeneruje pliki CMake. Jest to konieczne, jeśli dodasz nowy plik do folderu źródłowego wybranego na przykład przez * .cc.
Chociaż samo w sobie nie jest to „czyste”, „oczyszcza” pliki CMake poprzez regenerację pamięci podręcznej.
źródło
Używam następującego skryptu powłoki do takich celów:
Jeśli używasz systemu Windows, użyj Cygwin dla tego skryptu.
źródło
Zabawnie jest widzieć, że to pytanie zyskuje tak wiele uwagi i skomplikowanych rozwiązań, co w rzeczywistości pokazuje ból z powodu braku czystej metody z cmake.
Cóż, na pewno
cd build
możesz wykonać swoją pracę, a następnie zrobić to,rm -rf *
kiedy musisz wyczyścić. Jednakrm -rf *
jest to niebezpieczne polecenie podano, że wiele osób często nie są świadomi, które są w dir.Jeśli ciebie
cd ..
,rm -rf build
a potemmkdir build
, a potemcd build
, że jest po prostu zbyt dużo typowania.Dobrym rozwiązaniem jest po prostu pozostanie poza folderem kompilacji i poinformowanie cmake o ścieżce:
do skonfigurowania:
cmake -B build
do kompilacji:
cmake --build build
do czyszczenia:
rm -rf build
do odtworzenia folderu kompilacji: nawet nie potrzebujesz
mkdir build
, po prostu skonfiguruj go,cmake -B build
a cmake go utworzyźródło
cmake
głównie gotujeMakefile
, można dodaćrm
do czystego PHONY .Na przykład,
źródło
Mam to w moim pliku rc powłoki (
.bashrc
,.zshrc
):Powinieneś go używać tylko do kompilacji spoza źródła. Załóżmy, że masz katalog nazwany
build/
w tym celu. Musisz po prostu uciect-cmake-clean
z tego.źródło
Kiedyś zsxwing na odpowiedź z powodzeniem rozwiązać następujący problem:
Mam źródło, które buduję na wielu hostach (na płycie Raspberry Pi Linux, na maszynie wirtualnej VMware Linux itp.)
Mam skrypt Bash, który tworzy katalogi tymczasowe na podstawie nazwy hosta komputera w następujący sposób:
źródło
Utwórz tymczasowy katalog kompilacji, na przykład
build_cmake
. Dlatego wszystkie pliki kompilacji będą znajdować się w tym folderze.Następnie w głównym pliku CMake dodaj poniższe polecenie.
Stąd podczas kompilacji
I do czyszczenia wykonaj:
źródło