7

たとえば、c++ プロジェクトfooは cmake によって維持されます。1 つのライブラリlibfoo.a(ソース ツリー全体で作成されたすべてのクラス/メソッド/関数を含む) を作成して、ライブラリにリンクできるプログラムを作成できるようにする必要があります-lfoo

さて、おもちゃの例を考えてみましょう。問題は明らかです。ディレクトリfoo(プロジェクトのルート) にはディレクトリa、およびが含まれますb。次の 2 つCmakeLists.txtが作成されます。

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

そしてCMakeLists.txt、ルートディレクトリ用の 1 つ:

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

それは私にとって驚きでした: libfoo.a をビルドした後、 foo_sources からのメソッドのみが含まれa_sources,b_sourcesは除外されます。実行可能ファイルが同じプロジェクトでビルドされている場合は問題aありbませんfoo。しかし、実行可能ファイルが「外部」プロジェクトで作成され、ライブラリを使用するfoo必要がある場合は、リンクする必要があり-lfoo -la -lbます。多くのサブディレクトリを持つプロジェクトを想像してみてください。質問は、「プロジェクト全体から cmake を使用してメソッドを集約し、1 つのライブラリを作成する方法」です。

グーグルは、比較的最近埋め込まれた(2.8.8に登場した)OBJECT library機会に私を導きました。それを使用する良い例がここに示されています。これで、上記の問題は次のように解決できます。

# 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>)

問題は解決したようですが、残念ながら完全ではありません。

依存チェーンが 2 よりも長い場合、たとえば、 が にfoo依存しA、 が に依存しているB場合、問題は依然として残ります。それは、

オブジェクト ライブラリには、オブジェクト ファイルにコンパイルするソース (およびヘッダー) のみを含めることができます。

オブジェクト ライブラリは、インポート、エクスポート、インストール、またはリンクできません。

(引用は同リンクより)

のいくつかの組み合わせを試しましtarget_link_library()たが、add_library(), add_library(... OBJECT ..)リンクAを試みて成功Bfooませんでした(cmake-process中のエラー)

私は単純なものを失っているに違いありません、助けてください、ありがとう!それが重要かどうかはわかりません。プロジェクトはLinuxで維持されています。

4

2 に答える 2

3

「依存する」という用語に巻き込まれていると思います。という名前のライブラリを構築していて、そのライブラリにとfooの 2 つの部分がある場合、 に依存しているかどうかは問題ではありません。ライブラリには両方が含まれている必要があります。表示された CMake コードは適切にビルドされます。ABABfoo

于 2012-12-01T21:09:10.160 に答える
0

はい、@Pete Becker@ の回答をサポートします。しかし、これらのライブラリは実際にはライブラリではなく、オブジェクトモジュールの内部リストを作成することも言う必要があり$<TARGET_OBJECTS:A>ます$<TARGET_OBJECTS:B>。オブジェクト モジュール (自動生成されたソースを除く) のコンパイル間に依存関係がないため、任意の順序で並行して実行できます。

TARGET_OBJECTSあなたの意図のより正確な用語は、単一のオブジェクトライブラリの下にいくつかを集めていると思います。あなたが書けないのは本当に悪いことです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

于 2013-04-12T04:31:41.573 に答える