2012-12-01 5 views
7

C++ - プロジェクト、例えばfooはcmakeによって維持されます。 -lfooでライブラリにリンクできるプログラムを作成するために、1つのライブラリlibfoo.a(すべてのクラス/メソッド/関数をソースツリー全体で作成)を作成したいとします。cmakeでプロジェクト全体から1つの静的ライブラリを作成します

ここで、おもちゃの例を考えてみましょう。ディレクトリfoo(プロジェクトのルート)には、ディレクトリabが含まれています。 、b_sourceslibfoo.aをを構築した後foo_sourcesからメソッドのみが含まれており、a_sources:私にとっては驚きだった

add_subdirectory(a) 
add_subdirectory(b) 
add_library(foo <foo_sources> 
target_link_libraries(foo A B) 

は:ルートディレクトリの

# a/CMakeLists.txt 
add_library(A <a_sources>) 
# b/CMakeLists.txt 
add_library(B <b_sources>) 

そして、もう一つCMakeLists.txtを:二つのCmakeLists.txtが作成されます除外される。 実行ファイルが同じプロジェクトでビルドされている場合は問題ありません。実行ファイルを作成する際ににリンクされている場合、abがリンクされている必要があります。 しかし、実行可能ファイルがライブラリ "foo"を使用する "外部"プロジェクトで作成されている場合は、-lfoo -la -lbとリンクする必要があります。今はサブディレクトリの多いプロジェクトを想像してください。だから質問は "どのように1つのライブラリを作成し、cmakeの手段でプロジェクト全体からメソッドを集約するか"です。

グーグルでは、比較的最近に埋め込まれた(2.8.8に登場)OBJECT library機会につながった。それを使用する良い例はhereです。今、上記の問題はそれで解決することができます:

# a/CMakeLists.txt 
add_library(A OBJECT <a_sources>) 
# b/CMakeLists.txt 
add_library(B OBJECT <b_sources>) 
# foo/CMakeLists.txt 
add_subdirectory(a) 
add_subdirectory(b) 
add_library(foo <foo_sources> $<TARGET_OBJECTS:A> $<TARGET_OBJECTS:B>) 

問題は解決されるようですが、残念なことに、かなり。

fooA(これはBに依存)に依存している場合、依存性チェインが2より長い場合、問題は依然として残ります。

オブジェクトライブラリには、オブジェクトファイルをコンパイルするソース(およびヘッダー)のみが含まれている可能性があります。

オブジェクトライブラリは、インポート、エクスポート、インストール、またはリンクすることはできません。私はadd_library(), add_library(... OBJECT ..)が成功せずfooABをリンクしようと、target_link_library()のいくつかの組み合わせを試した

(引用符は同じlinkから撮影されている)

(cmakeの-処理中にエラーが発生しました。)

私は何かを失うに違いありません、助けてください、ありがとう! 私はそれが重要であるか分かりません。プロジェクトはLinuxで管理されています。

答えて

3

「依存している」という言葉に絡み合っていると思います。fooという名前のライブラリを構築する場合、ABの2つの部分があり、ABに依存するかどうかは関係ありません。ライブラリには両方が含まれている必要があります。あなたが示したCMakeコードは、fooを適切に構築します。

0

はい、私は答え@ペテベッカー@をサポートしています。しかし、それらのライブラリは$<TARGET_OBJECTS:A>$<TARGET_OBJECTS:B>は実際にはライブラリではなくむしろcmakeオブジェクトモジュールの内部リストであると言われるべきです。オブジェクトモジュールのコンパイル(自動生成されたソースを除く)には依存関係がないため、順序と並行して実行できます。

私はあなたの意図のより正確な用語は、単一のオブジェクトライブラリの下にいくつか一緒に集まっていると思います。それは本当にあなたがadd_library(B OBJECT b.cpp $<TARGET_OBJECTS:A>)書くことができない悪いです。しかし、あなたはいつも自分でこれを実装することができます

add_library(A OBJECT a.cpp) 
set(A_OBJECTS $<TARGET_OBJECTS:A>) 

add_library(B OBJECT b.cpp) 
set(B_OBJECTS $<TARGET_OBJECTS:B> ${A_OBJECTS}) 

add_library(foo ${B_OBJECTS}) 

すなわちだけの特別な変数を作成_OBJECTSライブラリでこれらのオブジェクトライブラリを含めたい時はいつでも実行可能ファイルまたはその_OBJECTSの風味を持つ他のオブジェクトライブラリの一部として、それらを使用します。

関連する問題