ネットを見てみると、次のようなコードがたくさん見られました。
_include(FindPkgConfig)
pkg_search_module(SDL2 REQUIRED sdl2)
target_include_directories(app SYSTEM PUBLIC ${SDL2_INCLUDE_DIRS}
target_link_libraries(app ${SDL2_LIBRARIES})
_
ただし、インクルードディレクトリとライブラリのみを使用し、_pkg-config
_によって返される可能性のある定義、ライブラリパス、およびその他のフラグを無視するため、これは間違った方法のようです。
これを実行し、_pkg-config
_によって返されるすべてのコンパイルおよびリンクフラグが、コンパイルされたapp
で使用されるようにする正しい方法は何でしょうか。そして、これを達成するための単一のコマンド、つまりtarget_use(app SDL2)
のようなものはありますか?
ref:
以下に示す他の方法では、一般的なインストール場所(/ usr/libなど)にない共有ライブラリのリンカーパスを構成できません。結果のリンカーエラーは/usr/bin/ld: cannot find -llibrary-1.0
。私の場合、pkg-configファイルもインストールされず、PKG_CONFIG_PATH環境変数を使用してプロジェクトのpkg-configパスが追加されました。これは、機能するCMakeLists.txtの要約版です。
cmake_minimum_required(VERSION 3.14)
project(ya-project C)
find_package(PkgConfig REQUIRED)
pkg_check_modules(MY_PKG REQUIRED IMPORTED_TARGET any-package)
pkg_check_modules(YOUR_PKG REQUIRED IMPORTED_TARGET ya-package)
add_executable(program-name file.c ya.c)
target_link_libraries(program-name
PkgConfig::MY_PKG
PkgConfig::YOUR_PKG)
まず、呼び出し:
_include(FindPkgConfig)
_
次のものに置き換える必要があります。
_find_package(PkgConfig)
_
find_package()
呼び出しはより柔軟で、include()
を使用して手動で行う必要があることを自動的に行うREQUIRED
などのオプションを許可します。
第二に、_pkg-config
_を手動で呼び出すことは可能な限り避けるべきです。 CMakeには、Linuxの_/usr/share/cmake-3.0/Modules/Find*cmake
_にある豊富なパッケージ定義セットが付属しています。これらは、pkg_search_module()
への生の呼び出しよりも多くのオプションと選択肢をユーザーに提供します。
前述の架空のtarget_use()
コマンドについては、CMakeには既にPUBLIC | PRIVATE | INTERFACEで組み込まれています。 target_include_directories(mytarget PUBLIC ...)
のような呼び出しにより、mytarget
を使用するすべてのターゲットでincludeディレクトリが自動的に使用されます。 target_link_libraries(myapp mytarget)
。ただし、このメカニズムは_CMakeLists.txt
_ファイル内で作成されたライブラリのみに適用されるようで、pkg_search_module()
で取得されたライブラリには機能しません。呼び出しadd_library(bar SHARED IMPORTED)
がそのために使用される可能性がありますが、まだ検討していません。
主な質問に関しては、これはほとんどの場合にここで動作します:
_find_package(PkgConfig REQUIRED)
pkg_check_modules(SDL2 REQUIRED sdl2)
...
target_link_libraries(testapp ${SDL2_LIBRARIES})
target_include_directories(testapp PUBLIC ${SDL2_INCLUDE_DIRS})
target_compile_options(testapp PUBLIC ${SDL2_CFLAGS_OTHER})
_
_SDL2_CFLAGS_OTHER
_には、コンパイルの成功に必要な定義とその他のフラグが含まれています。ただし、フラグ_SDL2_LIBRARY_DIRS
_および_SDL2_LDFLAGS_OTHER
_は無視されますが、どれくらいの頻度で問題になるかはわかりません。
その他のドキュメントはこちら http://www.cmake.org/cmake/help/v3.0/module/FindPkgConfig.html
SDL2とリンクするだけで済むことはまれです。現在人気のある答えはpkg_search_module()
を使用します。これは特定のモジュールをチェックし、最初に動作するモジュールを使用します。
SDL2およびSDL2_MixerおよびSDL2_TTFなどとリンクしたい可能性が高くなります... pkg_check_modules()
は、指定されたすべてのモジュールをチェックします。
# sdl2 linking variables
find_package(PkgConfig REQUIRED)
pkg_check_modules(SDL2 REQUIRED sdl2 SDL2_ttf SDL2_mixer SDL2_image)
# your app
file(GLOB SRC "my_app/*.c")
add_executable(my_app ${SRC})
target_link_libraries(my_app ${SDL2_LIBRARIES})
target_include_directories(my_app PUBLIC ${SDL2_INCLUDE_DIRS})
target_compile_options(my_app PUBLIC ${SDL2_CFLAGS_OTHER})
免責事項:stackoverflowで十分なストリートクレデンスがあれば、Grumbelの自己回答についてコメントしただけです。
利用可能な回答のほとんどは、pkg-config
ライブラリのヘッダーの設定に失敗します。 FindPkgConfigのドキュメント について瞑想した後、これらも提供するソリューションを思い付きました。
include(FindPkgConfig)
if(NOT PKG_CONFIG_FOUND)
message(FATAL_ERROR "pkg-config not found!" )
endif()
pkg_check_modules(<some-lib> REQUIRED IMPORTED_TARGET <some-lib>)
target_link_libraries(<my-target> PkgConfig::<some-lib>)
(<my-target>
の代わりにターゲットを、<some-lib>
の代わりに任意のライブラリを置き換えます。)
IMPORTED_TARGET
オプションは重要であると思われ、PkgConfig::
名前空間の下ですべてが利用可能になります。これが必要なすべてであり、すべてshouldも必要でした。
target_use
などのコマンドはありません。しかし、私は、内部で使用するためにそのようなコマンドを作成したいくつかのプロジェクトを知っています。しかし、すべてのプロジェクトは追加のフラグまたは定義を渡したいため、一般的なCMakeでそれを使用することは意味がありません。それを持たないもう1つの理由は、EigenのようなC++テンプレートライブラリです。ライブラリはありませんが、インクルードファイルの束しかありません。
説明されている方法は、多くの場合正しいです。一部のライブラリでは異なる場合があるため、_LDFLAGS
または_CFLAGS
を追加する必要があります。 target_use
がないもう1つの理由。うまくいかない場合は、SDL2または使用したいライブラリについて特定の新しい質問をしてください。