web-dev-qa-db-ja.com

複数の相互依存するサブディレクトリを持つC ++プロジェクトをビルドするにはどうすればよいですか?

私はディレクトリをより組織的な要素として使用しているC++プロジェクトを持っています-JavaまたはPHPのディレクトリを使用する方法。ディレクトリは自給自足を意図していません要素ではなく、プロジェクト全体を整理し、ソースに圧倒されないようにするための方法です。それらはすべて相互に依存しており、そのように使用することを意図していません。

関連する問題として、私が見たCMakeの複数のサブディレクトリの例のほとんど(およびそれらの多くはありません)は、include_directoriesの設定の問題を無視または無視しました。問題を抱えている。ソースファイルをコーミングして、どのファイルがどのディレクトリに依存するかを判断するのではなく、潜在的なインクルードディレクトリとして/src/の下にあるすべてのディレクトリを設定し、CMakeが実際に依存するディレクトリを決定できるようにしますか?

構造の例を次に示します。

--src
  --top1
    --mid1
      --bot1
        --src1.cpp
        --hdr1.h
      --bot2
        --src2.cpp
        --hdr2.h
    --mid2
      --bot3
        --src3.cpp
        --src4.cpp
        --hdr3.h
  --top2
    --mid3
      --src5.cpp
      --hdr4.h

などなど。このような構造を処理するためにCMakeLists.txtファイルをどのように構造化できますか?

65
Daniel Bingham

プロジェクトのディレクトリ構造はファイルを整理するためにあるため、1つのアプローチはCMakeLists.txtは、srcディレクトリ内のすべてのソースファイルを自動的に検索し、すべてのディレクトリをヘッダーファイルが含まれるインクルードディレクトリとして追加します。次のCMakeファイルは出発点として使用できます。

cmake_minimum_required(VERSION 3.0)

project (Foo)

file(GLOB_RECURSE Foo_SOURCES "src/*.cpp")
file(GLOB_RECURSE Foo_HEADERS "src/*.h")

set (Foo_INCLUDE_DIRS "")
foreach (_headerFile ${Foo_HEADERS})
    get_filename_component(_dir ${_headerFile} PATH)
    list (APPEND Foo_INCLUDE_DIRS ${_dir})
endforeach()
list(REMOVE_DUPLICATES Foo_INCLUDE_DIRS)

add_executable (FooExe ${Foo_SOURCES})
target_include_directories(FooExe PRIVATE ${Foo_INCLUDE_DIRS})

二つ file(GLOB_RECURSE ...コマンドは、ソースファイルとヘッダーファイルのセットを決定します。 foreachループは、すべてのヘッダーファイルのリストからインクルードディレクトリのセットを計算します。

ソースファイルのセットを計算する場合の1つの欠点は、新しいファイルがソースツリーに追加されたときにCMakeが自動的に検出しないことです。その後、手動でビルドファイルを再作成する必要があります。

59
sakra

私はCMakeの専門家ではありませんが、他に答えがないので、ドキュメンテーションを見て試してみます。ソースとインクルードファイルを異なるディレクトリに整理することは、ほぼ標準です。

CMakeを使用すると、インクルードディレクトリのリストを提供できるようです。 http://www.cmake.org/cmake/help/cmake-2-8-docs.html#command:include_directories

のようなもの:

include_directories("src/top1/mid1/bot1" "src/top1/mid1/bot2/" ... )

これらはヘッダーファイルを見つけることができるようにコンパイラに渡され、ソースファイルごとに渡されます。したがって、どのソースファイルにもヘッダーファイルを含めることができるはずです(これはあなたが求めているものだと思います)。

同様に、すべてのソースファイルを add_executable コマンドで一覧表示できるはずです。

add_executable(name "src/top1/mid1/bot1/src1.cpp" "src/top1/id1/bot2/src2.cpp" ...)

したがって、これはすべてを構築するための単純な方法です。各ソースファイルがコンパイルされ、それらすべてのディレクトリでヘッダーが検索され、オブジェクトファイルがリンクされます。多くのインクルードフォルダーを必要としないように、これを単純化する方法があるかどうかを検討してください。すべてのソースファイルで参照する必要のある共通ヘッダーファイルがいくつかあるだけかもしれません。物事がより複雑になる場合は、サブ階層をライブラリなどに組み込むことができます。ソースファイルとヘッダーを分離することも検討してください(たとえば、srcとincludeに)。

2
Guy Sirton