手始めに、無視できないディレクトリの従来の名前がいくつかあります。これらは、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、およびおそらくいくつかのテストフォルダー)に加えて、ソース外ビルドの「ビルド」ディレクトリは、ビルドプロセスで生成されたファイルのみを含むすべてのフォルダーです。したがって、バージョン管理システム/サーバー(GitやSVNなど)の下に保管する必要があるのは、srcフォルダーのみ、またはそれよりもはるかに良い方法です。
そして、宛先システムにヘッダーファイルをインストールすることになると(最終的にライブラリを配布したい場合)、CMakeにはファイルをインストールするためのコマンドがあります(暗黙的に「インストール」ターゲットを作成し、「make install」を実行します)。すべてのヘッダーを/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ディレクトリのサブディレクトリはインクルードディレクトリのサブディレクトリをミラーリングする必要があります。これは、物事を直感的に保つためです(また、サブディレクトリ構造を適度にフラット(浅い)に保つようにしてください。多くの場合、何よりも面倒です。第2に、「include」ディレクトリは単なるインストールディレクトリであり、その内容はsrcディレクトリから選択されたヘッダーだけです。
第3に、CMakeシステムは、トップレベルの1つのCMakeLists.txtファイルとしてではなく、ソースサブディレクトリに配布されることを目的としています。これは物事をローカルに保ち、それは良いことです(物事を独立した部分に分割する精神で)。新しいソース、新しいヘッダー、または新しいテストプログラムを追加する場合、必要なのは、問題のサブディレクトリにある1つの小さくてシンプルなCMakeLists.txtファイルを編集することだけです。これにより、ディレクトリを簡単に再構築することもできます(CMakeListはローカルであり、移動するサブディレクトリに含まれています)。最上位のCMakeListsには、宛先ディレクトリ、カスタムコマンド(またはマクロ)のセットアップ、システムにインストールされているパッケージの検索など、ほとんどの最上位の構成が含まれている必要があります。下位レベルのCMakeListsには、ヘッダー、ソース、
引用:CMakeLists.txtは、ライブラリだけ、またはライブラリとテストのいずれかを構築できるようにどのように見える必要がありますか?
基本的な答えは、CMakeを使用すると、特定のターゲットを「すべて」(「make」と入力すると作成される)から明確に除外でき、特定のターゲットのバンドルを作成することもできます。ここではCMakeチュートリアルを行うことはできませんが、自分で調べるのはかなり簡単です。ただし、この特定のケースでは、もちろん、CTestを使用することをお勧めします。これは、CMakeListsファイルで使用できる追加のコマンドセットであり、ユニットとしてマークされている多数のターゲット(プログラム)を登録します。テスト。したがって、CMakeはすべてのテストをビルドの特別なカテゴリに配置し、それがまさにあなたが求めていたものなので、問題は解決されました。
引用:また、ビルド広告とbinディレクトリを持つかなりの数のプロジェクトを見てきました。ビルドはビルドディレクトリで行われ、その後バイナリがbinディレクトリに移動されますか?テストのバイナリとライブラリは同じ場所にありますか?または、次のように構成する方が理にかなっていますか。
ソースの外にビルドディレクトリを作成すること( "out-of-source"ビルド)は実際に唯一の正気なことであり、最近では事実上の標準となっています。したがって、CMakeの人々が推奨するように、またこれまでに出会ったすべてのプログラマーがそうであるように、ソースディレクトリの外に、別の「ビルド」ディレクトリを用意してください。binディレクトリに関しては、まあ、それは慣例であり、この投稿の冒頭で述べたように、これに固執することはおそらく良い考えです。
引用:私のコードを文書化するためにdoxygenも使用したいと思います。これをcmakeおよびmakeで自動的に実行することは可能ですか?
はい。それは不可能ではありません、それは素晴らしいです。どれだけ豪華にしたいかに応じて、いくつかの可能性があります。CMakeにはDoxygen用のモジュール(つまりfind_package(Doxygen)
)があり、一部のファイルでDoxygenを実行するターゲットを登録できます。Doxyfileのバージョン番号を更新したり、ソースファイルの日付/作成者のスタンプを自動的に入力したりするなど、もっと手の込んだことをしたい場合は、CMake kung-fuを使用すればすべて可能です。一般的に、これを行うには、トークンを見つけてCMakeの解析コマンドで置き換えるソースDoxyfile(たとえば、上記のフォルダーレイアウトに配置した「Doxyfile.in」)を保持する必要があります。で、私のトップレベルのCMakeListsファイル、あなたはcmakeの-たDoxygen一緒にいくつかの空想のことを行いますCMakeのカンフーのそのような作品を見つけるでしょう。