1. ホーム
  2. cmake

[解決済み] cmake` から `pkg-config` を使用する正しい方法は何ですか?

2023-01-10 17:35:12

質問

ネットで調べると、このようなコードをたくさん見かけます。

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:

どのように解決するのですか?

cmake と pkg-config をごく普通に使っているのであれば、この解決方法は有効です。

しかし、ある開発ディレクトリ (たとえば /home/me/hack/lib) に存在するライブラリを持っている場合、ここで見られる他の方法を使用してもリンカーパスの構成に失敗します。典型的なインストール場所の下で見つからないライブラリは、次のようなリンカー エラーが発生します。 /usr/bin/ld: cannot find -lmy-hacking-library-1.0 . この解決策は、そのような場合のリンカーエラーを修正します。

もう一つの問題は、pkg-config ファイルが通常の場所にインストールされておらず、プロジェクトの pkg-config パスを PKG_CONFIG_PATH 環境変数を使用して追加する必要があります (これについては、他の Stack Overflow の質問を参照してください)。この解決策は、正しい pkg-config パスを使用する場合にもうまく機能します。

使用方法 IMPORTED_TARGET を使うことが、上記の問題を解決する鍵になります。この解決策は この以前の回答 を改善したもので、最終的にはこの動作するCMakeLists.txtに集約されます。

cmake_minimum_required(VERSION 3.14)
project(ya-project C)

# the `pkg_check_modules` function is created with this call
find_package(PkgConfig REQUIRED) 

# these calls create special `PkgConfig::<MODULE>` variables
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 PUBLIC
        PkgConfig::MY_PKG
        PkgConfig::YOUR_PKG)

なお target_link_libraries はリンカーコマンドを変更するだけではありません。コンパイラー フラグ、コンパイラー定義、インクルード パスなど、指定されたターゲットの他の PUBLIC プロパティも伝搬するため、PUBLIC キーワードは慎重に使用する必要があります。