0

CMake プロジェクトで、ライブラリに組み込まれたソースがあるとします。

// a.cpp
void f() { /* some code*/ }

そして、私はヘッダーを持っています

// b.h
void f();
struct X { void g() { f(); } };

別のファイルがあります:

// main.cpp
#include "b.h"
int main() { X x; x.g(); }

CMakeLists.txt には以下が含まれます。

add_library(A a.cpp)
add_executable(main main.cpp)
target_link_libraries(main A)

ここで、CMakeLists.txt の最後の行を見てください。main の依存関係として A を明示的に指定する必要があります。基本的に、bh を含むすべてのソースに対してそのような依存関係を指定する必要があります。たとえば、a.cpp は ch のクラス インライン関数を呼び出し、次に dh の関数を呼び出し、最後にライブラリ A から関数を呼び出します。bh が多数のファイルに含まれている場合、そのようなすべての依存関係を手動で見つけることは現実的ではありません。大規模なプロジェクト。

だから私の質問は、ヘッダーを直接または間接的に含むすべてのソースファイルに対して、特定のライブラリにリンクする必要があることを指定する方法はありますか?

ありがとう。

4

1 に答える 1

2

1つ明確にするために:a.cppはlib "A"にコンパイルされます。つまり、A のすべてのユーザーは、A で指定する必要がありますtarget_link_libraries。それを回避する方法はありません。A を使用する小さなアプリケーションが 10 個ある場合は、target_link_libraries10 回指定する必要があります。

私の答えはあなたの質問の2番目の問題を扱っており、それがより重要なものだと思います:

インクルードのチェーンを取り除く方法は?

ah を bh に含め、そのメソッドを bh で使用すると、「暗黙の」依存関係が追加されます。お気づきのとおり、bh のユーザーには ah も必要です。大まかに言えば、2つのアプローチがあります。

良いアプローチ:

これは CMake とは関係ありませんが、カプセル化に関するものです。ライブラリのユーザー (あなた自身を含む) は、その内部実装について心配する必要はありません。つまり、ah に bh を含めないでください。

代わりに、インクルードを .cpp ファイルに移動します。このようにして、連鎖を断ち切ります。たとえば、次のようなもの

// b.h
void f();
struct X
{ 
    void g();
};

// b.cpp
#include b.h
#include a.h
void X::g( )
{
    f();
}

このように、ah ​​の使用は cpp ファイルに「含まれ」、ライブラリを使用する人は bh をインクルードして b.lib にリンクするだけで済みます。

別の方法:

現在、そのような「依存」を受け入れなければならない状況や、意識的に選択しなければならない状況があります。たとえば、A を制御できない場合、または A 内部のクラス/構造体に関して定義されたライブラリを意識的に作成することにした場合。

その場合、必要なすべてのインクルード ディレクトリをチェーンの下に準備する CMake コードを作成することをお勧めします。たとえば、変数「YOURLIB_INCLUDES」と「YOURLIB_LIBRARIES」を「YourLibConfig.cmake」に定義し、ライブラリのすべてのユーザーが「YourLibConfig.cmake」をインポートする必要があることを文書化します。これは、いくつかの cmake ベースのプロジェクトが採用しているアプローチです。たとえば、OpenCV はファイルをインストールしOpenCVConfig.cmake、VTK はファイルをインストールしVTKConfig.cmakeて準備しUseVTK.cmakeます。

于 2012-10-28T14:20:43.017 に答える