web-dev-qa-db-ja.com

CMakeおよび順序に依存する共有ライブラリのリンク

メインアプリケーションの共有ライブラリとして構築しているいくつかの小さなコンポーネントがあります。 libalibbの例を使用してみましょう。次のように、それぞれが独自のサブディレクトリ内に構築されます。

add_library(liba SHARED a.cpp)

次に、ルートプロジェクトフォルダーで、メインアプリケーションを両方にリンクする必要があります。

include_directories(a)
include_directories(b)
add_executable(dummy dummy.cpp)
target_link_libraries(dummy a b)

CMakeはこれで問題なく動作し、アプリケーションはコンパイルされますが、リンクに失敗します。問題は、bがaを参照することです。リンク中にライブラリの順序を指定すると

target_link_libraries(dummy b a)

プログラムは正常にコンパイルおよびリンクされます

この種のシステムがライブラリーのより複雑な相互依存関係に関与し始めると、依存関係が非循環であっても不可能になり始めます。ここでリンク手順を管理するにはどうすればよいですか? CMakeでリンクするライブラリを注文するコツはありますか?

34
dusktreader

abの関係を指定するには、次を追加します。

target_link_libraries(b a)


docs から:

ライブラリの依存関係はデフォルトで推移的です。このターゲットが別のターゲットにリンクされている場合、このターゲットにリンクされているライブラリは、他のターゲットのリンク行にも表示されます。

したがって、このようにabの依存関係として指定すると、aに依存するターゲットでbを明示的にリストする必要もありません。 ] _、つまり、他のコマンドは次のようになります。

target_link_libraries(dummy b)

ただし、aをリストしても害はありません。

33
Fraser

簡単な解決策(特に循環依存関係の場合)は、次のように、すべてのライブラリをリスト変数に入れ、そのリストを2回(または必要に応じてさらに)追加することです。

set(LINK_LIBS "liba libb libc")
target_link_libraries(app ${LINK_LIBS} ${LINK_LIBS})

(またはtarget_link_libraries関数でリストを2回続けて入力してください)

これは私にとってかなりうまくいきましたが、気づいていない可能性のあるいくつかの欠点があることを認めます(少しハックのように見えることを除いて)。

14
sonicwave