C ++プロジェクト:アーティファクト - CMake(ビルドタイム)を使用したディレクトリ名の "include"

私は現在、うまく使用している新しいプロジェクトのための良い構造を考案しました。

NOTE: This structure is beneficial for the project which is developed by multiple programmers.


    + include
        + Haroogan
            + Utility
                - util.h
            + More
                - more.h
                + Whatever
                    - whatever.h

    + src
        + Haroogan.More             <--- Artifact
            - more.h
            - more.cpp
            - CMakeLists.txt
        + Haroogan.More.Whatever    <--- Artifact
            - whatever.h
            - whatever.cpp
            - CMakeLists.txt
        + Haroogan.Utility          <--- Artifact
            - util.h
            - util.cpp
            - CMakeLists.txt
        + Haroogan.Application      <--- Artifact
            - app.h
            - app.cpp
            - CMakeLists.txt
        - CMakeLists.txt            <--- "Root" CMakeLists.txt

Artifact - is library, executable, etc. - you got the point.

Artifact-Name (as in the subject) - is simply the name of the artifact which is deduced by CMake from the name of the directory dedicated to the artifact. Actually terms Artifact and Artifact-Name are essentially the same. For example: artifact residing in directory "Haroogan.More.Whatever" has name "Haroogan.More.Whatever".

これにはいくつかの結果があります。

  • ビルド後に生成されるライブラリ、実行可能ファイルなどはArtifact-Nameで名前が付けられます;
  • 特定のアーティファクトに関するすべてのソースコードは、アーティファクト名に対応する名前空間に囲まれています。たとえば、アーティファクト "Haroogan.More.Whatever"は、すべてのソースの "Haroogan :: More :: Whatever"ネームスペースを強制します。
  • 1つのアーティファクトが別のアーティファクトを使用したい場合、別のアーティファクトが含まれていなければなりません。しかしながら、私たちは皆、 #include "../ Haroogan.More/more.h" を書くことは厄介なだけでなく、実際には成果物ファイルシステムに関してさえもデカップリングされています。さらに、プライベートヘッダーのコンセプトも壊れています。この方法で他のアーティファクト内のヘッダーにアクセスできます。

私たちが必要とするのは、単にパブリックヘッダリポジトリです - 「include」ディレクトリです。したがって、最後の問題に取り組むために、私は以下を行うことに決めました:

  • 各アーティファクトは、(CMakeLists.txtの中で)外界にどのヘッダをエクスポートするかを独自に決定します;
  • 次に、これらのヘッダファイルを "include"内の対応するディレクトリにコピーします(すべてのビルドで必要ですが、必要なときのみ)。たとえば、Artifact-Nameが "Haroogan.More.Whatever"の場合、ヘッダは "include/Haroogan/More/Whatever /"ディレクトリにコピーされます(上記のように)。

他のコンポーネントの "Haroogan.More.Whatever"や "Haroogan.More"アーティファクトの "何か"と "より多くの"クラスを使用したい場合は、今から素晴らしく堅牢なアプローチだと思います。

#include 
#include 

using Haroogan::More::Whatever::whatever;
using Haroogan::More::more;

システムは魅力的に機能します(誰かが望むなら私はCMakeスクリプトを提供できます)。しかし、私はヘッダーがコピーされるという事実に満足していません。たとえば、 "whatever.h"をコピーする代わりに、CMakeが "Haroogan/More/Whatever /"に新しいファイル "whatever.h"を作成し、注入 #を作成すると、 "../../../../ src/Haroogan.More.Whatever/whatever.h" が含まれています。

私のシステムは完全に自動化されました。言い換えれば、パス "Haroogan/More/Whatever"はArtifact-Name "Haroogan.More.Whatever"から自動的に推論されます。したがって、 #include "のインジェクション ../../../../ src/Haroogan.More.Whatever/whatever.h" ../../ も自動化されています。

残念ながら、私はCMakeの新機能であり、この機能をどのように実現するのか分かりませんが、それは可能であり、誰かによって既に行われている可能性があります。ありがとうございました。

編集:

この問題の一時的な解決方法は次のとおりです。

../../ の扱いに直面する「Haroogan/More/Whatever /」の中に「whatever.h」を作成するのではなく、単に「Haroogan.More.Whatever.whatever .h "(" whatever.h "の接頭辞を" Haroogan.More.Whatever "とする)を" include "ディレクトリに置いて、それを以下のように使用します:

#include 

using Haroogan::More::Whatever::whatever;

この解決策は受け入れられるものですが、私が興味を持っているものほどそれを好きではありません。

1
代わりの方法は、構造内の各CMakeプロジェクトがCMakeレベルで管理できるCMake-Project_INCLUDE_DIRSのセットを定義する場合です
追加された 著者 André,

1 答え

これはどう:

macro(add_public_headers)
  foreach(header ${ARGN})
    get_filename_component(abspath ${header} ABSOLUTE)
    file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/${header} "#include ${abspath}"
  endforeach()
endmacro()

このマロは、今のところこのように使うことができます:

src/Haroogan.More.Whatever/CMakeLists.txt にあります

add_public_headers(whatever.h)

これはあなたのビルドディレクトリに#include行のヘッダを生成します。

唯一のことは、その道は絶対的なものですが、あなたにとっては問題ではないはずです。

1
追加された
つまり、このプロジェクトを自分のマシンに引き込む他の開発者がいるにもかかわらず、パスを相対的に作成することについてはあまり気にしないでください。言い換えれば、彼らはプロジェクトを構築するときに彼ら自身の絶対的な道を得るでしょう。さて、私は今、この解決策に慣れています。しかし、ここで相対的な経路を導入する方法が見つかった場合は、それを共有すると感謝しています。ありがとうarrowdodger。
追加された 著者 Alexander Shukaev,
そうですね、彼らは自分の絶対的な道を得るでしょう。また、これらのヘッダーはビルドごとに再生成されます。
追加された 著者 arrowd,