CMake出力を消去するための「cmake clean」コマンドを探しています


419

同じようにmake clean削除メイクファイルが生成されたすべてのファイル、私はCMakeのと同じことをしたいと思います。すべてあまりにも頻繁に私は自分自身が手動のようなファイルを削除するディレクトリを経由見つけるcmake_install.cmakeCMakeCache.txt、およびCMakeFilesフォルダ。

cmake cleanこれらのファイルをすべて自動的に削除するようなコマンドはありますか?理想的には、これは現在のディレクトリのCMakeLists.txtファイル内で定義されている再帰構造に従う必要があります。

回答:


487

ありませんcmake clean

私は通常、「ビルド」のような単一のフォルダーにプロジェクトをビルドします。だから私がしたいならmake clean、私はただすることができますrm -rf build

ルート「CMakeLists.txt」と同じディレクトリにある「build」フォルダは、通常は適切な選択です。プロジェクトをビルドするには、cmakeにCMakeLists.txtの場所を引数として指定するだけです。次に例を示しますcd <location-of-cmakelists>/build && cmake ..。(@ComicSansMSから)


101
これは「ソース外ビルド」と呼ばれ、推奨される方法です。名前の衝突などを回避
arne

17
ソース外ビルドの場合は+1。これは、複数のアーキテクチャを構築する場合に重要になります。たとえば、64ビットと32ビットの両方のバイナリをソースビルドでビルドすることはできません。これには、2つの別々のCMakeキャッシュ階層が必要になるためです。
ComicSansMS 2012年

9
フォルダーはどこにでも配置できますが、ビルドフォルダーは通常、ルートのCMakeLists.txtと同じディレクトリに配置することをお勧めします。ビルドするには、cmakeにCMakeLists.txtの場所を引数として指定します。例:cd <location-of-cmakelists>/build && cmake ..
ComicSansMS 2012年

64
本当にきれいなはずです。cmakeを使用したことがあるすべての人は、たとえソースビルドの外で実行する習慣があったとしても、誤って間違ったディレクトリでcmakeを実行しており、手動でクリーンアップすることはお尻に大きな負担となります。
pavon

24
@DevSolarしかし、その逆は真実ではありません。ファイルがバージョン管理されていないからといって、そのファイルがcmakeによって生成され、安全に吹き飛ばされるとは限りません。特にバージョン管理されていないファイルのうち、保持する必要がある未処理のファイルと、cmakeの残骸を特定するのは、特に、c​​makeファイルの多くがファイルにコピー/類似した名前である場合に大変です。
pavon 2015

84

CMakeの公式FAQには次のように記載されています。

GNU autotoolsで作成された一部のビルドツリーには、ビルドをクリーンアップし、Makefileと生成されたビルドシステムの他の部分を削除する「make distclean」ターゲットがあります。CMakeLists.txtファイルはスクリプトや任意のコマンドを実行できるため、CMakeは「make distclean」ターゲットを生成しません。CMakeには、CMakeの実行中に生成されたファイルを正確に追跡する方法がありません。distcleanターゲットを提供すると、期待どおりに機能するという誤った印象をユーザーに与えます。(CMakeは、コンパイラーとリンカーによって生成されたファイルを削除するために「make clean」ターゲットを生成します。)

「make distclean」ターゲットは、ユーザーがソース内ビルドを実行する場合にのみ必要です。CMakeはソース内ビルドをサポートしていますが、ユーザーにはソース外ビルドの概念を採用することを強くお勧めします。ソースツリーとは別のビルドツリーを使用すると、CMakeがソースツリーでファイルを生成できなくなります。CMakeはソースツリーを変更しないため、distcleanターゲットは必要ありません。ビルドツリーを削除するか、別のビルドツリーを作成することで、新しいビルドを開始できます。


もともと、GNU autotoolsで導入および使用されていた「distclean」ターゲットは、ソースツリーをtarで圧縮してtarディストリビューションを作成できるようにすることを目的としています。このようなtarファイルのユーザーは、autotools(aclocal、automake、autoconfなど)必要とせずに、ダウンロードして解凍し、「configure」と「make」実行できます。cmakeに外挿すると、「make distclean」を実行するとクリーンになりますcmakeをインストールしなくてもビルドできるソース。ただし、これは(「make」ターゲットがそうであるように)ジェネレーターが単一ターゲットジェネレーターであった場合は機能しません
Carlo Wood

... cmakeを実行しています。設定できない、プラットフォームのテストさえしないディストリビューションを作るのは無意味です。したがって、cmakeの「distclean」ターゲットは存在しません。cmakeはエンドユーザーのマシンに存在する必要あります。
Carlo Wood

63

Gitの至る所で、CMakeを忘れてを使用するとgit clean -d -f -x、ソース管理下にないすべてのファイルが削除されます。


14
その-xオプションも。それはgit取引の優れたトリックです。けれども私は個人的にはまだ、ドライ実行最初にしてくださいgit clean -d -f -x -ngitたまに、プロジェクトで使用する便利なファイルをプロジェクトフォルダーで管理していますが、他の人と共有したくないgit addので、プロジェクトでは使用しません。私が-e <pattern>オプションを追加するように注意しなかった場合、これはその種のファイルを吹き飛ばしてしまいます。その点でgitは、.gitcleanignoreファイルがあればいいでしょう。:)
CivFan 2015年

1
@CivFanを使用して試すことができますchattr +i $filename(ルート権限が必要です。この後、ファイルを変更することはできません)。このようにgitは、のように実行しようとしても、そのファイルを削除できませんrm -f
ルスラン

3
これは、ソース自体のビルドを前提としています。これは、それ自体で回避する必要があります。
スラバ

これは単純な解決策でした(そして、これらのフラグが何を意味するかについての思い出はありませんが、それは単なる開発マシンの笑いです)。
matanster 2017年

1
ええと、ユーザーが忘れた新しく追加されたファイルはgit addどうですか?
18年

50

私はそれを30分ほどグーグルで操作し、思いついた唯一の有用なことは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ジェネレーター)を必ず呼び出してください。

:)


36
作業しているディレクトリがバージョン管理されている場合は、このアプローチを使用しないことをお勧めします。svnでこのアプローチを試したところ、リポジトリの作業ファイルの一部が削除されました。
2013

8
cmakeに一致する他のファイルがあるかもしれないので、これは本当に普遍的なアプローチではありません。これは行う必要があります:rm -rf CMakeFiles; rm -rf CMakeCache.txt; rm -rf cmake_install.cmake;
honza_p

1
-exec rm -rf {} \ +を削除し、-deleteを使用します。
Edgar Aroutiounian、2015年

3
このコマンドは一部のユーザーファイルを削除する可能性があるため、反対票を投じました。私はhonza_pコマンドを好んでいますが、実際にはより長く、より単純で、リスクは少ないです。
Adrien Descamps 2017

1
@AdrienDescamps:サブディレクトリにcmake関連のジャンクが残っていることを除いて。私はやっていましたがrm -rf CMakeFiles ; rm -rf */CMakeFiles ; rm -rf */*/CMakeFiles ; rm -rf */*/*/CMakeFiles、まだやっていませんでした...
SF。

35

あなたは次のようなものを使うことができます:

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」の呼び出しを追加する「make clean-all」コマンドを作成します。

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
)

それも機能しません。


cmake_generatedを自動的に埋める方法はありますか?おそらく、これをyuri.makarevichの回答と組み合わせますか?現在、これは$ {CMAKE_BINARY_DIR}のサブディレクトリにあるファイルを削除しません。
foxcub

忍者やVisual Studioでは機能しません。このようなアプローチはお勧めしません。
usr1234567

23

単にrm CMakeCache.txt私のためにも作品を発行しています。


1
CMakeCache.txtで関連する変数を削除するだけでも機能します。
ヨークウォー

CMakeCache.txtを削除してから「cmake --build / build-path」を実行すると、「エラー:キャッシュをロードできませんでした」が発生します。
nenchev 2017年

1
@nenchev cmake /build-pathもう一度実行する必要があります。
サマウサ2017年

@Samaursa cmake --buildは必要に応じてcmakeを再実行します。このメソッドはビルドディレクトリを壊し、cmakeは不平を言います。さらに下の私の答えは、CMakeFiles /ディレクトリを削除するように指示します。これにより、クリーンな再構築とcmakeが自動的に再実行されます。
nenchev

2
@nenchev私はあなたの意味を理解し、同意します。
サマウサ2017年

9

少し古いかもしれませんが、これはあなたがグーグルするときの最初のヒットなので、これcmake cleanを追加します:

指定したターゲットでビルドディレクトリでビルドを開始できるので

cmake --build . --target xyz

もちろん実行できます

cmake --build . --target clean

clean生成されたビルドファイルでターゲットを実行します。


8

ソース外のビルドが最良の答えであることには同意します。しかし、あなたがインソースビルドをしなければならないときのために、私はここで利用可能なPythonスクリプトを書きました:

  1. 「make clean」を実行します
  2. CMakeCache.txtなどの最上位ディレクトリにある特定のCMake生成ファイルを削除します
  3. CMakeFilesディレクトリを含むサブディレクトリごとに、CMakeFiles、Makefile、cmake_install.cmakeを削除します。
  4. 空のサブディレクトリをすべて削除します。

それをありがとう。以前のクリーンアップのために存在しmakeないときに沈黙するMakefile(つまり、このスクリプトをべき等にする)行をスクリプトに追加したいと思います。行を(適切な間隔で)追加します:if os.path.isfile(os.path.join(directory,'Makefile')):24 args = [行目の直前:もちろん、追加した行の後に関数本体の残りをインデントします。これは、クリーンアップされている現在のディレクトリにmake ... cleana Makefileが存在する場合にのみ実行されます。それ以外の場合、スクリプトは完璧です。
Michael Goldshteyn

4

私が最近見つけた解決策は、アウトオブソースのビルドの概念を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が行う2番目のことは、buildディレクトリをディレクトリに変更してを呼び出すことcmakeです。

allターゲットに戻り、を呼び出します$(MAKE) -C build$(MAKE)は、に対して自動的に生成されるMakefile変数ですmakemake -C何かする前にディレクトリを変更します。したがって、使用すること$(MAKE) -C buildは実行することと同じcd build; makeです。

要約すると、このMakefileラッパーをmake allまたはで呼び出すことは、次のこと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では@、シェルコマンドからの出力を抑制するためにプレフィックスを使用@-し、シェルコマンドからのエラーを無視するためにプレフィックスを使用します。ターゲットのrm一部として使用distcleanする場合、ファイルが存在しないとコマンドはエラーを返します(ファイルは、でコマンドラインを使用してすでに削除されているrm -rf buildか、最初から生成されていない可能性があります)。この戻りエラーにより、Makefileが強制的に終了します。これを@-防ぐためにプレフィックスを使用します。ファイルがすでに削除されていても問題ありません。Makefileが残り、残りを削除することを望みます。

注意すべきもう1つのこと:このMakefileは、プロジェクトのビルドに可変数のCMake変数を使用すると機能しない場合がありますcmake .. -DSOMEBUILDSUSETHIS:STRING="foo" -DSOMEOTHERBUILDSUSETHISTOO:STRING="bar"。このMakefileは、入力するcmake ..cmake、一貫した数の引数(Makefileに含めることができる)を指定することにより、一貫した方法でCMakeを呼び出すことを前提としています。

最後に、クレジットが支払われるべきクレジット。このMakefileラッパーは、C ++アプリケーションプロジェクトテンプレートによって提供されるMakefileから適応されました。


4

もちろん、アウトオブソースビルドは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。サブフォルダーからビルドするためにCMakeLists.txtを更新しました。これらのコマンドより少し時間がかかりましたが、私は1回だけ実行する必要がありました:)
Tien Do

4

使用しようとします:cmake --clean-first-of-CMakeLists.txt-file -B output-dir

--clean-first:最初にクリーンなターゲットをビルドしてからビルドします。
(クリーンアップのみを行うには、-target cleanを使用します。)


このスクリーンショットはテキストのみを示しています。それでも、スクリーンショットを撮って、スクリーンリーダーを持ってここに来た人の答えを壊します。その画像をドロップし、テキストのコピー/貼り付けを行い、1分間かけてその入力を適切にフォーマットしてください。
GhostCat

3

-Dビルドファイルの生成時にパラメーターをCMakeに渡し、build /ディレクトリ全体を削除したくない場合:

ビルドディレクトリ内のCMakeFiles /ディレクトリを削除するだけです。

rm -rf CMakeFiles/
cmake --build .

これにより、CMakeが再実行され、ビルドシステムファイルが再生成されます。ビルドも最初から始まります。


1

「ソース外」ビルド(つまり、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/*ます。
モスタファファルザン

0

カスタム定義があり、クリーニングする前に保存したい場合は、ビルドディレクトリで次のコマンドを実行します。

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

次に、新しいビルドディレクトリを作成し(または古いビルドディレクトリを削除して再作成し)、最後にcmake上記のスクリプトで取得する引数を使用して実行します。


0

走れば

cmake .

CMakeファイルを再生成します。たとえば、*。ccで選択されたソースフォルダーに新しいファイルを追加する場合に必要です。

これ自体は「クリーン」ではありませんが、キャッシュを再生成することでCMakeファイルを「クリーンアップ」します。


WRTはクリーニングしません。コンパイル状態:1200個のファイルのうち500個がコンパイルされている場合は、「cmake」の後。最後の700個のファイルから続行されます。
Peter Mortensen、

0

私はそのような目的で次のシェルスクリプトを使用します。

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

Windowsを使用している場合は、このスクリプトにCygwinを使用します。


0

この質問が非常に多くの注意と複雑な解決策を得るのを見るのはおかしいですが、実際には、cmakeを使用したクリーンなメソッドがないことには苦痛が伴います。

まあ、あなたは間違いなくcd buildあなたが仕事をすること、そしてrm -rf *あなたが掃除する必要があるときにそれをすることができます。ただし、rm -rf *多くの人は自分がどこにいるのかわからないことが多いため、危険なコマンドです。

もしあなたがcd ..rm -rf buildそしてそれmkdir buildから、それがcd buildタイプしすぎるということです。

したがって、良い解決策は、ビルドフォルダーの外にとどまり、cmakeにパスを伝える ことです:
構成する:cmake -B build
ビルドする:cmake --build build
クリーンする:rm -rf build
ビルドフォルダーを再作成する:必要もありません。mkdir build構成するだけでcmake -B build、cmakeが作成します


0

cmake主に料理Makefilermしますが、クリーンなPHONYに追加できます。

例えば、

[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

-1

私のシェルrcファイル(.bashrc.zshrc)にこれがあります:

t-cmake-clean() {
    local BUILD=$(basename $(pwd))
    cd ..
    rm -rf $BUILD
    mkdir $BUILD && cd $BUILD
}

ソース外のビルドにのみ使用することになっています。build/この目的のために名前が付けられたディレクトリがあるとします。次に、その中から実行する必要がありますt-cmake-clean


-3

私は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

-8

たとえば、一時ビルドディレクトリを作成しますbuild_cmake。したがって、すべてのビルドファイルはこのフォルダー内にあります。

次に、メインのCMakeファイルに以下のコマンドを追加します。

add_custom_target(clean-all
    rm -rf *
)

したがって、コンパイル中に

cmake ..

そしてきれいにするために:

make clean-all

11
誰かが誤ってソース外ではなくソース内でビルドした場合にすべてのプロジェクトを削除する素晴らしい方法

3
はい。この方法は、「ソース外ビルド」でのみ使用する必要があります
Natesh

6
ひどい勧告。答えとして存在すべきではありません。
アンヴァンロッサム2017

@AnnevanRossumが同意
zevarito 2017
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.