program tip

`cmake`에서`pkg-config`를 사용하는 적절한 방법은 무엇입니까?

radiobox 2020. 12. 13. 09:09
반응형

`cmake`에서`pkg-config`를 사용하는 적절한 방법은 무엇입니까?


인터넷을 둘러 보면 다음과 같은 많은 코드를 보았습니다.

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)있습니까?

심판 :


아래에 표시된 다른 방법은 일반적인 설치 위치 (예 : / usr / lib)에서 찾을 수없는 공유 라이브러리에 대한 링커 경로를 구성하지 못합니다. 결과 링커 오류는 /usr/bin/ld: cannot find -llibrary-1.0. 제 경우에는 pkg-config 파일도 설치되지 않았고 프로젝트의 pkg-config 경로는 PKG_CONFIG_PATH 환경 변수를 사용하여 추가되었습니다. 이것은 작동하는 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()호출은 더 유연하며 REQUIRED수동으로해야하는 작업을 자동으로 수행하는 등의 옵션을 허용 include()합니다.

둘째, 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, 예를 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의 자체 답변에 대해 간단히 언급했을 것입니다.


Most of the available answers fail to configure the headers for the pkg-config library. After meditating on the Documentation for FindPkgConfig I came up with a solution that provides those also:

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

(Substitute your target in place of <my-target> and whatever library in place of <some-lib>, accordingly.)

The IMPORTED_TARGET option seems to be key and makes everything then avaiable under the PkgConfig:: namespace. This was all that was required and also all that should be required.


  1. There is no such command as target_use. But I know several projects that have written such a command for their internal use. But every project want to pass additional flags or defines, thus it does not make sense to have it in general CMake. Another reason not to have it are C++ templated libraries like Eigen, there is no library but you only have a bunch of include files.

  2. The described way is often correct. It might differ for some libraries, then you'll have to add _LDFLAGS or _CFLAGS. One more reason for not having target_use. If it does not work for you, ask a new question specific about SDL2 or whatever library you want use.


If you are looking to add definitions from the library as well, the add_definitions instruction is there for that. Documentation can be found here, along with more ways to add compiler flags.

The following code snippet uses this instruction to add GTKGL to the project:

pkg_check_modules(GTKGL REQUIRED gtkglext-1.0)
include_directories(${GTKGL_INCLUDE_DIRS})
link_directories(${GTKGL_LIBRARY_DIRS})
add_definitions(${GTKGL_CFLAGS_OTHER})
set(LIBS ${LIBS} ${GTKGL_LIBRARIES})

target_link_libraries([insert name of program] ${LIBS})

참고URL : https://stackoverflow.com/questions/29191855/what-is-the-proper-way-to-use-pkg-config-from-cmake

반응형