手始めに、無視できないディレクトリの従来の名前がいくつかあります。これらは、Unixファイルシステムの長い伝統に基づいています。これらは:
trunk
├── bin : for all executables (applications)
├── lib : for all other binaries (static and shared libraries (.so or .dll))
├── include : for all header files
├── src : for source files
└── doc : for documentation
少なくともトップレベルでは、この基本的なレイアウトに固執することをお勧めします。
ヘッダーファイルとソースファイル(cpp)の分割については、どちらのスキームもかなり一般的です。しかし、私はそれらを一緒に保つことを好む傾向があります。ファイルを一緒にすることは、日常のタスクでより実用的です。また、すべてのコードが1つのトップレベルフォルダー、つまりフォルダーの下にある場合、トップレベルにtrunk/src/
ある他のすべてのフォルダー(bin、lib、include、doc、および場合によってはいくつかのテストフォルダー)に気付くことができます。ソース外ビルドの「ビルド」ディレクトリは、ビルドプロセスで生成されたファイルのみを含むすべてのフォルダです。したがって、srcフォルダーのみをバックアップする必要があります。または、バージョン管理システム/サーバー(GitやSVNなど)の下に保持する必要があります。
そして、宛先システムにヘッダーファイルをインストールする場合(最終的にライブラリを配布したい場合)、CMakeにはファイルをインストールするコマンドがあります(「インストール」ターゲットを暗黙的に作成し、「makeinstall」を実行します)。を使用して、すべてのヘッダーを/usr/include/
ディレクトリに配置できます。この目的のために、次のcmakeマクロを使用します。
# custom macro to register some headers as target for installation:
# setup_headers("/path/to/header/something.h" "/relative/install/path")
macro(setup_headers HEADER_FILES HEADER_PATH)
foreach(CURRENT_HEADER_FILE ${HEADER_FILES})
install(FILES "${SRCROOT}${CURRENT_HEADER_FILE}" DESTINATION "${INCLUDEROOT}${HEADER_PATH}")
endforeach(CURRENT_HEADER_FILE)
endmacro(setup_headers)
SRCROOT
srcフォルダーに設定したcmake変数はどこINCLUDEROOT
にあり、ヘッダーの移動先に設定したcmake変数はどこにありますか。もちろん、これを行うには他にも多くの方法がありますが、私の方法は最善ではないと確信しています。重要なのは、ターゲットシステムにヘッダーのみをインストールする必要があるという理由だけでヘッダーとソースを分割する理由はないということです。これは、特にCMake(またはCPack)を使用すると、ヘッダーを選択して構成するのが非常に簡単だからです。別のディレクトリに配置しなくてもインストールできます。そして、これは私がほとんどの図書館で見たものです。
引用:次に、コードの単体テストにGoogle C ++テストフレームワークを使用したいと思います。これは、かなり使いやすいように思われるためです。これを私のコード、たとえば「inc/gtest」または「contrib/gtest」フォルダーにバンドルすることをお勧めしますか?バンドルされている場合は、fuse_gtest_files.pyスクリプトを使用してファイル数を減らすか、そのままにしておくことをお勧めしますか?バンドルされていない場合、この依存関係はどのように処理されますか?
依存関係をライブラリにバンドルしないでください。これは一般的にかなり恐ろしい考えであり、それを行うライブラリを構築しようとして立ち往生しているときはいつもそれを嫌います。それはあなたの最後の手段であるべきであり、落とし穴に注意してください。多くの場合、ひどい開発環境(Windowsなど)をターゲットにしているため、または問題のライブラリの古い(非推奨)バージョン(依存関係)のみをサポートしているため、依存関係をライブラリにバンドルします。主な落とし穴は、バンドルされた依存関係が、同じライブラリ/アプリケーションのすでにインストールされているバージョンと衝突する可能性があることです(たとえば、gtestをバンドルしているが、ライブラリをビルドしようとしている人は、新しい(または古い)バージョンのgtestをすでにインストールしています。 2つが衝突し、その人に非常に厄介な頭痛を与える可能性があります)。だから、私が言ったように、あなた自身の責任でそれをしてください、そして私は最後の手段としてのみ言うでしょう。ライブラリをコンパイルする前にいくつかの依存関係をインストールするように人々に依頼することは、バンドルされた依存関係と既存のインストールとの間の衝突を解決しようとするよりもはるかに害が少ないです。
引用:テストを書くことになると、これらは一般的にどのように構成されていますか?クラスごとに1つのcppファイル(たとえば、test_vector3.cpp)を作成することを考えていましたが、すべてを1つのバイナリにコンパイルして、すべてを簡単に一緒に実行できるようにしましたか?
私の意見では、クラスごとに1つのcppファイル(またはクラスと関数の小さなまとまりのあるグループ)がより一般的で実用的です。ただし、「すべてを一緒に実行できるようにする」ためだけに、すべてを1つのバイナリにコンパイルしないでください。それは本当に悪い考えです。一般に、コーディングに関しては、合理的な範囲で分割する必要があります。単体テストの場合、1つのバイナリですべてのテストを実行する必要はありません。これは、ライブラリ内の何かに少し変更を加えると、その単体テストプログラムがほぼ完全に再コンパイルされる可能性があるためです。 、そしてそれは再コンパイルを待つのにちょうど数分/時間失われました。単純なスキームに固執するだけです:1ユニット=1ユニットテストプログラム。それで、
引用:gtestライブラリは通常cmakeとmakeを使用してビルドされるので、私のプロジェクトもこのようにビルドするのが理にかなっていると思いましたか?次のプロジェクトレイアウトを使用することにした場合:
私はむしろこのレイアウトを提案したいと思います:
trunk
├── bin
├── lib
│ └── project
│ └── libvector3.so
│ └── libvector3.a products of installation / building
├── docs
│ └── Doxyfile
├── include
│ └── project
│ └── vector3.hpp
│_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
│
├── src
│ └── CMakeLists.txt
│ └── Doxyfile.in
│ └── project part of version-control / source-distribution
│ └── CMakeLists.txt
│ └── vector3.hpp
│ └── vector3.cpp
│ └── test
│ └── test_vector3.cpp
│_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
│
├── build
└── test working directories for building / testing
└── test_vector3
ここで注意すべき点がいくつかあります。まず、srcディレクトリのサブディレクトリはincludeディレクトリのサブディレクトリをミラーリングする必要があります。これは、物事を直感的に保つためです(また、フォルダのネストが深いため、サブディレクトリの構造を適度にフラット(浅い)に保つようにしてください)多くの場合、他の何よりも面倒です)。次に、「include」ディレクトリは単なるインストールディレクトリであり、その内容はsrcディレクトリから選択されたヘッダーにすぎません。
第3に、CMakeシステムは、トップレベルの1つのCMakeLists.txtファイルとしてではなく、ソースサブディレクトリに分散されることを目的としています。これは物事をローカルに保ち、それは良いことです(物事を独立した部分に分割するという精神で)。新しいソース、新しいヘッダー、または新しいテストプログラムを追加する場合、必要なのは、問題のサブディレクトリにある1つの小さくて単純なCMakeLists.txtファイルを、他に影響を与えることなく編集することだけです。これにより、ディレクトリを簡単に再構築することもできます(CMakeListはローカルであり、移動するサブディレクトリに含まれています)。トップレベルのCMakeListには、宛先ディレクトリ、カスタムコマンド(またはマクロ)の設定、システムにインストールされているパッケージの検索など、ほとんどのトップレベルの構成が含まれている必要があります。下位レベルのCMakeListには、ヘッダー、ソース、
引用:CMakeLists.txtは、ライブラリのみ、またはライブラリとテストのいずれかを構築できるように、どのように見える必要がありますか?
基本的な答えは、CMakeを使用すると、「すべて」(「make」と入力したときに作成されるもの)から特定のターゲットを明確に除外でき、特定のターゲットのバンドルを作成することもできます。ここではCMakeチュートリアルを行うことはできませんが、自分で調べるのはかなり簡単です。ただし、この特定のケースでは、もちろん、推奨される解決策はCTestを使用することです。これは、CMakeListsファイルでユニットとしてマークされた多数のターゲット(プログラム)を登録するために使用できるコマンドの追加セットです。テスト。したがって、CMakeはすべてのテストをビルドの特別なカテゴリに配置します。これはまさにあなたが求めていたものであり、問題は解決しました。
引用:また、ビルドとbinディレクトリを持つプロジェクトをかなり多く見ました。ビルドはビルドディレクトリで行われ、バイナリはbinディレクトリに移動されますか?テスト用のバイナリとライブラリは同じ場所にありますか?または、次のように構成する方が理にかなっています。
ソースの外にビルドディレクトリを置くこと(「ソース外」ビルド)は、実際に行うべき唯一の正しいことであり、最近のデファクトスタンダードです。したがって、CMakeの人々が推奨するように、そして私が今まで出会ったすべてのプログラマーがそうであるように、間違いなく、ソースディレクトリの外に別の「ビルド」ディレクトリがあります。binディレクトリに関しては、これは慣例であり、この投稿の冒頭で述べたように、これに固執することをお勧めします。
引用:コードを文書化するためにdoxygenも使用したいと思います。これをcmakeとmakeで自動的に実行することは可能ですか?
はい。それは可能以上です、それは素晴らしいです。あなたがどれだけ空想を得たいかに応じて、いくつかの可能性があります。CMakeにはDoxygen用のモジュール(つまりfind_package(Doxygen)
)があり、一部のファイルでDoxygenを実行するターゲットを登録できます。Doxyfileのバージョン番号を更新したり、ソースファイルの日付/作成者スタンプを自動的に入力したりするなど、もっと凝ったことをしたい場合は、少しのCMakeカンフーですべて可能です。一般に、これを行うには、CMakeの解析コマンドによって検出および置換されるトークンを含むソースDoxyfile(たとえば、上記のフォルダーレイアウトに配置した「Doxyfile.in」)を保持する必要があります。私のトップレベルのCMakeListsファイルには、cmake-doxygenを使用していくつかの凝ったことを行うCMakekung-fuのそのような部分が1つあります。