CMake出力/ビルドディレクトリ


115

私はCMakeにかなり慣れていないので、その使用方法に関するいくつかのチュートリアルを読み、3つの異なるコンパイラー用のプログラムを作成するために、CMakeスクリプトの複雑な50行を書きました。これで、CMakeに関する私の知識はすべて終わります。

私の問題は、プログラムを作成するときに、そのフォルダーに触れたり、変更したりしたくないソースコードがあることです。すべてのCMakeおよびmake出力ファイルとフォルダーをに入れたい../Compile/ので、CMakeスクリプトのいくつかの変数をそのために変更しました。ラップトップで次のようなことをしたとき、それはしばらくの間機能しました:

Compile$ cmake ../src
Compile$ make

それで、私が今いるフォルダーにきれいな出力がありました。それがまさに私が探しているものです。

今、私は別のコンピューターに移動し、CMake 2.8.11.2を再コンパイルしましたが、ほぼ正方形に戻りました!それは常にsrc私のものCMakeLists.txtが置かれているフォルダーに事をコンパイルします。

CMakeスクリプトでディレクトリを選択する部分は次のとおりです。

set(dir ${CMAKE_CURRENT_SOURCE_DIR}/../Compile/)
set(EXECUTABLE_OUTPUT_PATH ${dir} CACHE PATH "Build directory" FORCE)
set(LIBRARY_OUTPUT_PATH ${dir} CACHE PATH "Build directory" FORCE)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${dir})
set(CMAKE_BUILD_FILES_DIRECTORY ${dir})
set(CMAKE_BUILD_DIRECTORY ${dir})
set(CMAKE_BINARY_DIR  ${dir})
SET(EXECUTABLE_OUTPUT_PATH ${dir})
SET(LIBRARY_OUTPUT_PATH ${dir}lib)
SET(CMAKE_CACHEFILE_DIR ${dir})

そして今、それは常に終わります:

-- Build files have been written to: /.../src

何か不足していますか?


4
設定しているすべての変数を設定する必要はほとんどありません。CMakeはそれらを適切なデフォルトに設定します。またはを絶対に変更しないでください。これらの呼び出しをすべて削除して実行するとどうなりますか?CMAKE_BINARY_DIRCMAKE_CACHEFILE_DIRset()cd Compile; rm -rf *; cmake ../src
Angewは、2013

5
基本的に、CMakeを実行しているときにソースディレクトリの外にいる限り、CMakeListから明示的に指示されない限り、ソースディレクトリは変更されません。
Angewは

@Angew驚くべきヒントをありがとう!私はそれらすべての行を削除してcmake ../srcを使用しただけで、それは魅力のように機能しました!これは、CMakeを最初に学習したときに以前に試してみましたが、機能しなかったので、これは驚くべきことです。正式な返信に回答を入れて、太いチェックマークを付けてください:)
Quantum Physicist

1
私を救ったのは、@ Adam Bowenが「ソース内ビルドでソースディレクトリのソース外ビルドを作成することはできない」という発言でした
Aur Saraf

回答:


60

設定しているすべての変数を設定する必要はほとんどありません。CMakeはそれらを適切なデフォルトに設定します。またはを絶対に変更しないでください。これらを読み取り専用として扱います。CMAKE_BINARY_DIRCMAKE_CACHEFILE_DIR

まず、既存の問題のあるキャッシュファイルをsrcディレクトリから削除します。

cd src
rm CMakeCache.txt
cd ..

次に、すべてのset()コマンドを削除して実行します。

cd Compile
rm -rf *
cmake ../src

CMakeを実行するときにソースディレクトリの外にいる限り、CMakeListから明示的に指示されない限り、ソースディレクトリは変更されません。

これが機能するようになったら、CMakeがデフォルトで配置する場所を確認し、デフォルトの場所(のデフォルト値などEXECUTABLE_OUTPUT_PATH)に満足できない場合にのみ、必要な場所のみを変更します。そして、相対的にそれらを表現しようとCMAKE_BINARY_DIRCMAKE_CURRENT_BINARY_DIRPROJECT_BINARY_DIRなど

CMakeのドキュメントを見ると、変数がセマンティックセクションに分割されていることがわかります。非常に特殊な状況を除いて、「情報を提供する変数」にリストされているものはすべて、CMakeLists内で読み取り専用として扱う必要があります。


2
私はsrcディレクトリのビルドでcmakeを使い始めました...この手法は最初は失敗しました。srcディレクトリ内のすべてのcmakeビルドファイル/キャッシュを削除すると、この手法は機能しました。ありがとう!
Avi Tevet 2014年

18
たぶん、の使用を勧めない方がいいでしょうrm -rf *cd Compile失敗した場合、それはきれいではありません...
ローマ

2
@Roman私はそのようなコマンドラインの例をかなり疑似コードと考えています。「ディレクトリに移動しCompile、そこにあるものをすべて削除してから、ソースディレクトリへのパスを指定してCMakeを実行する」と入力するよりも、簡潔で正確です。私は読者の側で基本的な常識と判断を想定しています。
Angewは

@AviTevet:これが正解だと思います。ソースディレクトリ内の以前のcmake呼び出しからのcmakeキャッシュファイルがある場合、ソースディレクトリから古いファイルをすべて削除しない限り、生成されたファイル用に別のディレクトリを選択するためにcmakeを取得しません。私の意見では、CMakeによるかなり壊れた動作。別の答えを書いてみませんか?
Jo So

112

ソース外でビルドしたいようです。ソース外ビルドを作成するには、いくつかの方法があります。

  1. あなたがやっていたことをやって、走って

    cd /path/to/my/build/folder
    cmake /path/to/my/source/folder
    

    これはcmakeのが発生する原因となりますビルドツリーの中に/path/to/my/build/folderためのソースツリーの中で/path/to/my/source/folder

    作成すると、cmakeはソースフォルダーの場所を記憶します。そのため、ビルドツリーでcmakeを再実行できます。

    cmake /path/to/my/build/folder

    あるいは

    cmake .

    現在のディレクトリが既にビルドフォルダである場合。

  2. CMake 3.13以降の場合、これらのオプションを使用してソースとビルドフォルダーを設定します

    cmake -B/path/to/my/build/folder -S/path/to/my/source/folder
  3. 古いCMakeの場合、ドキュメント化されていないオプションを使用して、ソースとビルドフォルダーを設定します

    cmake -B/path/to/my/build/folder -H/path/to/my/source/folder

    これは(1)とまったく同じことを行いますが、現在の作業ディレクトリに依存しません。

CMakeのはで、その出力のすべてを置くビルドツリーデフォルトでは、あなたが自由に使用しているので、しない限り、${CMAKE_SOURCE_DIR}または${CMAKE_CURRENT_SOURCE_DIR}あなたのcmakeのファイルで、それはあなたの触れてはならないソースツリーを

失敗する可能性のある最大の問題は、以前にソースツリーでビルドツリーを生成したことがある(つまり、ソース内ビルドがある)ことです。これを完了すると、上記の(1)の2番目の部分が開始され、cmakeはソースまたはビルドの場所に変更を加えません。したがって、ソース内ビルドでソースディレクトリのソース外ビルドを作成することはできませんCMakeCache.txtソースディレクトリから(少なくとも)削除することで、これをかなり簡単に修正できます。CMakeFilesCMakeが生成する他のいくつかのファイル(主にディレクトリ内)もあり、これらも削除する必要がありますが、これらによってcmakeがソースツリーをビルドツリーとして処理することはありません。

ソース外ビルドはソース内ビルドよりも望ましい場合が多いため、ソース外ビルドが必要になるようにcmakeを変更することができます。

# Ensures that we do an out of source build

MACRO(MACRO_ENSURE_OUT_OF_SOURCE_BUILD MSG)
     STRING(COMPARE EQUAL "${CMAKE_SOURCE_DIR}"
     "${CMAKE_BINARY_DIR}" insource)
     GET_FILENAME_COMPONENT(PARENTDIR ${CMAKE_SOURCE_DIR} PATH)
     STRING(COMPARE EQUAL "${CMAKE_SOURCE_DIR}"
     "${PARENTDIR}" insourcesubdir)
    IF(insource OR insourcesubdir)
        MESSAGE(FATAL_ERROR "${MSG}")
    ENDIF(insource OR insourcesubdir)
ENDMACRO(MACRO_ENSURE_OUT_OF_SOURCE_BUILD)

MACRO_ENSURE_OUT_OF_SOURCE_BUILD(
    "${CMAKE_PROJECT_NAME} requires an out of source build."
)

上記のマクロは、と呼ばれる一般的に使用されるモジュールからのものMacroOutOfSourceBuildです。MacroOutOfSourceBuild.cmakeon googleには多数のソースがありますが、オリジナルを見つけることができず、ここに完全に含めるには十分に短いです。

残念ながら、cmakeは通常、マクロが呼び出されるまでにいくつかのファイルを書き込んでいるため、実際にビルドを実行することはできませんが、削除CMakeCache.txtとが必要CMakeFilesです。

バイナリ、共有ライブラリ、静的ライブラリが書き込まれるパスを設定すると便利な場合があります。その場合、cmake出力を「bin」ディレクトリに作成する方法を参照してください(免責事項、私はその質問に対してトップ投票の回答を持っています...しかしそれが私がそれについて知っている方法です)。


実際には、ソースフォルダーを設定するオプションは-S、ではなくです-H
smac89

@ smac89ありがとう!3.13で文書化されているようです。最新のCMakeを反映するように回答を更新しました。
Adam Bowen、

8

私のコメントを答えに変える:

誰かが私がしたことをした場合、それはすべてのビルドファイルをソースディレクトリに置くことから始まりました:

cd src
cmake .

cmakeのビルドファイルとキャッシュファイル(の束入れますCMakeCache.txtCMakeFilescmake_install.cmakeで、など)をsrcDIR。

ソース外のビルドに変更するには、これらのファイルをすべて削除する必要がありました。次に、@ Angewが彼の回答で推奨したことを実行できます。

mkdir -p src/build
cd src/build
cmake ..

7

CMake Wikiの時点で:

ソースでビルドする場合はCMAKE_BINARY_DIR、これはCMAKE_SOURCE_DIRと同じです。それ以外の場合は、ビルドツリーの最上位ディレクトリです。

これら2つの変数を比較して、アウトオブソースビルドが開始されたかどうかを判断します


6

スクリプトでハードコーディングされたビルドディレクトリ名に依存しないでください。そのため、の行を../Compile変更する必要があります。

それはコンパイルする場所はユーザー次第であるべきだからです。

:その代わりに使用する定義済みの変数のいずれかの http://www.cmake.org/Wiki/CMake_Useful_Variables (のための外観CMAKE_BINARY_DIRCMAKE_CURRENT_BINARY_DIR


2
これは私が探していたものです- CMAKE_CURRENT_BINARY_DIR、通常は現在のバイナリビルドパスについて教えてくれます。おそらく、依存するlibs / binビルドの設定に使用できます。
Parasrish
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.