web-dev-qa-db-ja.com

複数のプロジェクト用に1つのビルドディレクトリを作成する

私はCMakeの初心者ユーザーです。私の環境には、次のようなプロジェクトがいくつかあります。

project
  |------ CMakeLists.txt (The main Cmake)
  |------ ProjectA
  |          |----- .cpp files
  |          |----- .hpp files
  |          |----- CMakeList.txt
  |------ ProjectB
  |          |----- .cpp files
  |          |----- .hpp files
  |          |----- CMakeList.txt
  | 
  |------ build
  |         |-----  CMakeStuff
  |------ bin
  |        |---- executables
  |------ lib
  |        |---- libwhatever.a
  |------ db 
           |---- Database stuff

上記のように、プロジェクトごとに1つのビルドディレクトリを使用したいと思います。 build/projectAbuild/ProjectBのように複数のサブプロジェクトに分割できるため、単一のプロジェクトを再構築する必要がある場合は、build/Projectファイル全体を削除でき、すべてがなくなって新しいCmakeは再びビルドします。

CMAKEの構成に問題があります。

プロジェクトフォルダーの元のCMakeList.txt:

cmake_minimum_required(VERSION 3.2.2.)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/../lib)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/../lib)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/../bin)

project(projectA)
set(CMAKE_BUILD_TYPE Debug)

file(GLOB SOURCES "*.cpp")

add_library(commonmessage SHARED ${SOURCES})

install(TARGETS commonmessage DESTINATION ../lib)

私の質問は:

A)cmakeを単一のビルドディレクトリで実行するとどうなりますか?それは可能ですか?また、正しいCMAKE構成は何ですか?

B)ProjectAのコンパイルには、ProjectBのファイルを含める必要があります。個々のプロジェクトのCMakeLists.txtに設定するにはどうすればよいですか?

C)最後に、すべてをビルドするための単一のメイクファイルと、各プロジェクトを個別にビルドするオプションが必要です。それは単一のビルドディレクトリで可能ですか?

手伝ってくれてありがとう。

21
Mendes

まず、投稿したCMakeコードは、.cppファイルと「projectA」を直接参照するため、最上位のCMakeList.txtファイルに属しているようには見えません。イディオムではないものもいくつかあります。

_cmake_minimum_required(VERSION 3.2.2.)
_

なぜ末尾のドットがここにあるのですか? cmakeが文句を言うかどうかはわかりませんが、どちらの場合も役に立ちません。

_set(CMAKE_BUILD_TYPE Debug)
_

しないでください。代わりに、_-DCMAKE_BUILD_TYPE=Debug_コマンドラインフラグを使用してcmakeを呼び出すか、ccmakeまたはGUIを使用するか、CMakeCache.txtファイルを編集します。

_file(GLOB SOURCES "*.cpp")
_

それもしないでください。 globbingではcmakeが新しく追加または削除されたファイルを自動的に検出しないため、CMakeでソースファイルを明示的にリストすることをお勧めします。しかし、一部の人々は同意しないかもしれません。

ここで、トピックの核心として、物事が通常どのように行われるかを示します。

トップCMakeLists.txtファイル:

_cmake_minimum_required(VERSION 3.2.2)
project(globalProject)

add_subdirectory(projectA)
add_subdirectory(projectB)
_

ProjectA CMakeLists.txtファイル(projectAが実行可能ファイルであると仮定):

_add_executable(projectA file1.cpp file2.cpp ... )
include_directories(${CMAKE_SOURCE_DIR}/projectB) # include files from ProjectB
target_link_libraries(projectA projectB)

install(TARGETS projectA RUNTIME DESTINATION bin)
_

ProjectB CMakeLists.txtファイル(projectBがライブラリであると仮定):

_add_library(projectB file1.cpp file2.cpp ... )

install(TARGETS projectB
    LIBRARY DESTINATION lib
    ARCHIVE DESTINATION lib)
_

このセットアップでは、cmake _make install_のコマンドライン呼び出しで指定されたように、選択した場所にbinとlibを作成する_-DCMAKE_INSTALL_PREFIX=.._ステップが必要であることに注意してください(makeはbuild dirから実行されると仮定)。

また、このセットアップでは、_-DBUILD_SHARED_LIBS=ON_を使用して、静的ライブラリと共有ライブラリのどちらを構築するかを選択できます。両方を構築するには、2つの異なる名前(1つはSTATIC、もう1つはSHARED)の2つの_add_library_呼び出しが必要です。

この作業を行うために必要な手順を要約するには:

_$ mkdir build && cd build
$ cmake .. -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=.. -DBUILD_SHARED_LIBS=ON
$ make
$ make install
_

これらのコマンドをスクリプトに入れて再利用することができます。

これで、質問に答えることができます。

A)可能であり、推奨されています。上記のコードを参照してください。必要なビルドディレクトリは1つだけです。

B)projectA/CMakeLists.txtのコードを参照し、include_directories()を呼び出す必要があります

C)はい、可能です。プロジェクトの各ターゲットは、makeおよびターゲット名を使用して、ビルドディレクトリから個別にビルドできます:_make projectB_および_make projectA_

35
SirDarius

A)N個のプロジェクトに対して1つのCMakeLists.txtを実行できます。ライブラリを定義すると、cmakeで定義された実行可能ファイル(add_executableおよびtarget_link_librariesを参照)で使用できます。

B)target_include_directoriesを参照

C)cmake --target targetは、cmakelists.txtファイルのターゲットの1つのみのMakefileを生成します。