web-dev-qa-db-ja.com

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

make cleanがmakefileが生成したすべてのファイルを削除するように、私はCMakeでも同じことをしたいと思います。多くの場合、私は手動でディレクトリをcmake_install.cmakeCMakeCache.txtのようなファイルを削除したり、CMakeFilesフォルダを手動で調べたりします。

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

330
Bill Cheatham

cmake cleanはありません。

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

ルートの "CMakeLists.txt"と同じディレクトリにある "build"フォルダは、通常は良い選択です。あなたのプロジェクトを構築するためには、単に引数としてCMakeLists.txtの場所をcmakeに渡します。例えば、cd <location-of-cmakelists>/build && cmake ..です。 (@ComicSansMSから)

398
zsxwing

CMakeの公式FAQ /:

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

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

69
Peter

私はそれを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ジェネレータ)を の前に - 呼び出してください。

:)

51
user1614309

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

46
Jean Davy

次のようなものを使うことができます。

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
)

依存関係として "clean"ターゲットを追加しようとしないでください。

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
)

これを行うと、clean-allが完了する前にすべてのCMakeファイルが消去され、makeは "CMakeFiles/clean-all.dir/build.make"の検索中にエラーをスローします。そのため、どのようなコンテキストでも、 "everything"の前にclean-allコマンドを使用することはできません。

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

それもうまくいきません。

29
Peregring-lk

単にrm CMakeCache.txtを発行するだけでも私にはうまくいきます。

18
user1480788

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

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

私が最近見つけた解決策は、ソース外ビルドの概念と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が最初に行うことは、$(MKDIR)を使用してbuildディレクトリを作成することです。これはmkdir -pの変数です。ディレクトリbuildは、ソース外ビルドを実行する場所です。 mkdirがすでに存在している可能性があるディレクトリを作成しようとしていることに対して私たちに叫んでいないことを保証するために、引数-pを提供します。

ターゲット./build/Makefileが行う2番目のことは、ディレクトリをbuildディレクトリに変更してcmakeを呼び出すことです。

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

まとめると、このMakefileラッパーをmake allまたはmakeで呼び出すことは、以下のようにすることと同じです。

mkdir build
cd build
cmake ..
make 

ターゲットdistcleancmake ..を呼び出し、次にmake -C build cleanを呼び出し、最後にbuildディレクトリからすべての内容を削除します。私はこれがまさにあなたの質問であなたが要求したものであると信じます。

Makefileの最後の部分は、ユーザー提供のターゲットがdistcleanであるかどうかを評価します。そうでなければ、起動する前にディレクトリをbuildに変更します。これは非常に強力です。たとえば、ユーザーがmake cleanと入力できるので、Makefileはそれをcd build; make cleanと同等のものに変換します。

結論として、このMakefileラッパーは必須のOut-of-SourceビルドCMake設定と組み合わせて、ユーザーがコマンドcmakeと対話する必要がないようにします。このソリューションはまた、buildディレクトリからすべてのCMake出力ファイルを削除するための洗練された方法を提供します。

P.S Makefileでは、シェルコマンドからの出力を抑制するために接頭辞@を使用し、シェルコマンドからのエラーを無視するために接頭辞@-を使用します。 rmdistcleanターゲットの一部として使用するとき、ファイルが存在しない場合、コマンドはエラーを返します(rm -rf buildのコマンドラインを使用して既に削除されているか、最初から生成されたことはありません)。このリターンエラーはMakefileを強制的に終了させます。これを防ぐために接頭辞@-を使用します。ファイルが既に削除されている場合は問題ありません。私たちは自分のMakefileに続けて残りを削除してもらいたいのです。

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

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

4

多分それは少し時代遅れです、しかし、あなたがcmake cleanをグーグルするとき、これが最初のヒットであるので、私はこれを加えます:

次のように指定したターゲットを使用してbuild dirでビルドを開始できます。

cmake --build . --target xyz

もちろん走れます

cmake --build . --target clean

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

3
redleg

ビルドファイルを生成するときに-DパラメータをCMakeに渡し、build /ディレクトリ全体を削除したくない場合は、次のようにします。

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

rm -rf CMakeFiles/
cmake --build .

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

3
nenchev

もちろん、ソース外ビルドは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
2
CJxD

走れば

cmake .

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

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

0
Homer6

"out of source"ビルド(つまり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
0
Alexander

使用してみてください:cmake --clean-firstのCMakeLists.txt-fileのパス-B output-dir

--clean-first:最初にターゲットをビルドし、次にビルドします。
(クリーニングのみを行うには、-target cleanを使用します。)

0
赏心悦目

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

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

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

0
Zouppen

私はそのような目的のために次のシェルスクリプトを使います。

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