2011-12-13 12 views
9

私はかなり長い間このことに苦労してきました。そして、cmakeの私の冒険は、私が間違っていると確信しているハッキリした解決策をもたらしました。私のC++プロジェクトをcmakeで構造化する正しい方法は?

次のように私は、いくつかのファイルで構成されてライブラリを作成しました:

-libfolder 
    -codepart1folder 
    -CMakeLists.txt 
    -codepart1.cpp 
    -codepart1.hpp 
    -codepart2folder 
    -codepart3folder 
    -lib.cpp 
    -lib.hpp 
    -CMakeLists.txt 

私は(いくつかの実験の後)ライブラリをコンパイルするCMakeListsファイルを書いた、と私はlib.aファイルを生成することができます。今私はこのコードを他のプロジェクトのライブラリとして取り込み、lib.hppのインタフェースからアクセスしたいと思います。ディレクトリ構造の観点から、これを行うための最善の方法は何ですか?また、私のルートプロジェクトでCMakeLists.txtに入れる必要があるものは何ですか?

私の現在の試みは、私の現在のプロジェクトにサブフォルダとして-libfolder追加し、コマンドを追加することであった

include_directories(${PROJECT_SOURCE_DIR}/libfolder) 
link_directories(${PROJECT_BINARY_DIR}/libfolder) 
add_subdirectory(libfolder) 
target_link_libraries(project lib) 

私はmakeを実行すると、ライブラリは罰金コンパイルするが、project.cppをコンパイルするときcodepart1.hpp(project.cppからインクルードされているlib.hppに含まれています)を見つけることができないという不満があります。

これは間違ったやり方だと思うが、私はCMakeのドキュメンテーションを眺めることができず、このようなプロジェクトをセットアップする上での良いチュートリアルを見つけることができない。助けてください、CMake gurus!

+0

おそらくcmake per-seeにはあまり役に立たないかもしれませんが、私はあなたにpremakeを見てもらうことをお勧めします。それは成熟に近づいており、cmakeには多くの利点があります(1つは、あなたがすでにluaを知っている場合には、それを速くするのがずっと速いことです)。 http://industriousone.com/what-premakeで確認することができます。 – Ylisar

+1

それで、あなたの新しいプロジェクトが以前にビルドされたライブラリを使用できるようにしたいのですか?それとも、両方ともsortofメタプロジェクトからビルドしたいですか? – moooeeeep

答えて

2

オクラホマので、CMakeの第一人者である私の同僚に相談した後、3つのオプションで1を残して、私がやろうとしています何のためにサポートしていないCMakeのようだ:

  1. のすべてを追加します。親プロジェクトCMakeLists.txtへの依存性 - それほどきれいではありませんが、動作するようになります。コードを追加するすべてのプロジェクトでこれを行う必要があります。また、ライブラリが変更された場合に戻って修正する必要があります。

  2. ライブラリヘッダーをクリーンアップします。これはいくつかのコンパイラのハッカーによって行われます。このアイデアはすべてのクラスを前方宣言し、ポインタまたはboost :: shared_ptrだけを使用してから、依存関係をcppファイルに含めることです。そうすれば、findpackageのすべてのものを使ってcppファイルを構築することができます。ヘッダーとライブラリにリンクするだけでlibを使用できるという利点があります。

  3. ビルドシステムを調べます。複雑な依存関係を持つポータブルコードと高速コードのコンパイルは、解決された問題ではありません!私の調査から、それはかなり複雑であることが分かった。私は彼がGoogleから拾ったものを使って、自分がcmakeで作成したシステムを構築する同僚を採用することになった。

+0

+1、3 rdparty include-dirsを必要としないようにインタフェースをクリーンアップする方がさらに優れているからです。 –

5

CMakeプロジェクトを別のCMakeプロジェクトにインポートするクリーンな方法は、find_packageコマンドです。パッケージの宣言は、exportコマンドを使用して行います。 find_packageを使用する利点は、パッケージのファイルへのパスをハードコードする必要がなくなることです。

欠落しているhppファイルについては、codepart1folderは含まれていないため、インクルードパスには含まれていません。

+0

Ok ...この回答から、find_packageとexportがこの場合に使用する正しいものかどうか、あるいは私がどのように行うのかは、私には明らかではありません。どうぞあなたは詳しく教えていただけますか? – dlants

+0

include_directories($ {PROJECT_SOURCE_DIR}/libfolder/codepart1folder)を使用します。 – LeDYoM

1

あなたの投稿を見ると、どこにでも「codepart1folder」を追加していないようです。どのようにしてcodepart1.hppを含めている:

#include <codepart1.hpp> 
#include "codepart1folder/codepart1.hpp" 

私はcmakeのプロジェクトを構築するための標準的な受け入れられた方法があるとは思いません。私はcmake reposの束を見てきました。彼らは違いがある傾向があります。個人的に、私は次のようにします。

-project 
    CMakeLists.txt 
    -build 
    -cmake 
     OptionalCmakeModule.cmake 
    -src 
     -Main 
      Main.cpp 
      Main.hpp 
     -DataStructs 
      SomeTree.hpp 
      SomeObject.hpp 
     -Debug 
      Debug.hpp 
     -UI 
      Window.hpp 
      Window.cpp 

基本的には1つのディレクトリにすべてのソースコードをダンプし、その後は元のアウトを実行してビルドする:「ます。mkdir & & cmakeのを構築& & CDを構築.. & &メイク 'をプロジェクトのルートフォルダに追加します。

プロジェクトの一部として別のライブラリがある場合、別のlibsディレクトリと特定のlibの別のサブフォルダが必要な場合があります。

CMakeLists.txtファイルを見たい場合はhttps://github.com/dcbishop/に私のレポをいくつか持っています。私のプロジェクト構造と

主な問題は、私は、彼らがピックアップされることはありません、あなたが実行した後にファイルを追加した場合、その後「cmakeの..を」(物事を行うための「間違った」方法が明らかにされFILE_GLOBを使用することですあなたは 'make'と呼んでいます)。私はそれを行うための「正しい」方法が分かっていません(ファイルの別のリストを保持することから見ることができますから)1つのCMakeLists.txtファイルしか使用しません。

プロジェクトによっては、cppファイルとhppファイルを別々のディレクトリに分割することもあります。だからあなたはincludeとsrcフォルダを持っているでしょう(少なくとも外部的に使われることになっているhppファイルのために)。主に大規模な図書館であるプロジェクトのために主になると思います。また、ヘッダファイルをインストールするのがずっと簡単になります。

+0

codepart1folderは、libfolder内のCMakeLists.txtファイルに含まれています。プロジェクトフォルダ内のCmakeLists.txtにすべてのサブフォルダ、インクルードとリンクを追加する必要があるのは間違いです。なぜなら、project.cppはそれらのどれにも依存しないからです。lib.hppだけです。 ツリーには、ライブラリを定義するproject2があり、project2をプロジェクトのサブパートとして使用したいと考えています。 – dlants

+0

@ JohnSavageしかしそれは正しい方法です... lib-projectにLIB_INCLUDE_DIRS変数を作成します。この変数は、必要なすべての依存インクルードディレクトリを含むCMakeCacheに「エクスポート」されます。次に、プロジェクトを作成するときに変数が存在すると仮定します。 –

+0

ギターリンクの+1 – hAcKnRoCk

0

あなたはおそらくあなたには、ディレクトリ・パス変数にすべてのフォルダを追加するset(CMAKE_INCLUDE_CURRENT_DIR on)する場合がありますこのような場合には

include_directories(${PROJECT_SOURCE_DIR}/libfolder/codepart1folder) 

が欠落しています。

正しいインクルードフォルダが設定されているかどうかをコマンドラインで確認してください。さらに、cmake変数には常に "print debugging"としてmessage()を使用することができます。 インクルードディレクトリの場合、実際にインクルードディレクトリにあるものを見るためにディレクトリプロパティを読む必要があります。

get_property(inc_dirs DIRECTORY PROPERTY INCLUDE_DIRECTORIES) 
message("inc_dirs = ${inc_dirs}") 

これは、欠落しているものを把握するのに役立ちます。

編集

私はちょうどlibfolderで追加codepart1folderについてコメントを見ました。これはlibfolderのinclude_directoryパスでのみ利用可能で、ルートフォルダには伝播されません。 include codepart1.hppはlib.hppにありますが、プロジェクトパスでも使用できるようにする必要があります。そうしないと、プロジェクトをビルドするときに宣言エラーが見つからなくなります。

+0

これは私の問題です。親プロジェクトにすべてのサブフォルダを組み込む必要はありません。 libは独自のCMakeLists.txtを持つ自己完結型のコードであり、lib.aにコンパイルされています。私はそれをすべてのプロジェクトに入れたいと思っていません。 – dlants

+1

あなたはlibを適切にインターフェースする必要があります。 – Bort

関連する問題