Skip to content

Commit

Permalink
FindPkgConfig: export the list of found libraries also as variable
Browse files Browse the repository at this point in the history
  • Loading branch information
DerDakon committed May 11, 2018
1 parent c9e995c commit 92ac721
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 21 deletions.
6 changes: 6 additions & 0 deletions Help/release/dev/FindPkgConfig-LINK_LIBRARIES.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
FindPkgConfig-LINK_LIBRARIES
----------------------------

* The :module:`FindPkgConfig` module has learned to export the found libraries
with full path for direct consumption with the :command:`target_link_libraries`
command.
11 changes: 2 additions & 9 deletions Modules/FindBLAS.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -88,16 +88,9 @@ endif()

if(BLA_PREFER_PKGCONFIG)
find_package(PkgConfig)
pkg_check_modules(PKGC_BLAS IMPORTED_TARGET blas)
pkg_check_modules(PKGC_BLAS blas)
if(PKGC_BLAS_FOUND)
# FIXME: We should not interpret the INTERFACE_LINK_LIBRARIES property
# because it could have generator expressions and such. This is a
# workaround for pkg_check_modules not providing a first-class way to
# get the list of libraries.
get_property(BLAS_LIBRARIES TARGET PkgConfig::PKGC_BLAS PROPERTY INTERFACE_LINK_LIBRARIES)
find_package_handle_standard_args(BLAS
REQUIRED_VARS BLAS_LIBRARIES
VERSION_VAR PKGC_BLAS_VERSION)
set(BLAS_LIBRARIES "${PKGC_BLAS_LINK_LIBRARIES}")
return()
endif()
endif()
Expand Down
39 changes: 27 additions & 12 deletions Modules/FindPkgConfig.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -183,8 +183,8 @@ endfunction()

# scan the LDFLAGS returned by pkg-config for library directories and
# libraries, figure out the absolute paths of that libraries in the
# given directories, and create an imported target from them
function(_pkg_create_imp_target _prefix _no_cmake_path _no_cmake_environment_path)
# given directories
function(_pkg_find_libs _prefix _no_cmake_path _no_cmake_environment_path)
unset(_libs)
unset(_find_opts)

Expand Down Expand Up @@ -221,18 +221,23 @@ function(_pkg_create_imp_target _prefix _no_cmake_path _no_cmake_environment_pat
list(APPEND _libs "${pkgcfg_lib_${_prefix}_${_pkg_search}}")
endforeach()

set(${_prefix}_LINK_LIBRARIES "${_libs}" PARENT_SCOPE)
endfunction()

# create an imported target from all the information returned by pkg-config
function(_pkg_create_imp_target _prefix)
# only create the target if it is linkable, i.e. no executables
if (NOT TARGET PkgConfig::${_prefix}
AND ( ${_prefix}_INCLUDE_DIRS OR _libs OR ${_prefix}_CFLAGS_OTHER ))
AND ( ${_prefix}_INCLUDE_DIRS OR ${_prefix}_LINK_LIBRARIES OR ${_prefix}_CFLAGS_OTHER ))
add_library(PkgConfig::${_prefix} INTERFACE IMPORTED)

if(${_prefix}_INCLUDE_DIRS)
set_property(TARGET PkgConfig::${_prefix} PROPERTY
INTERFACE_INCLUDE_DIRECTORIES "${${_prefix}_INCLUDE_DIRS}")
endif()
if(_libs)
if(${_prefix}_LINK_LIBRARIES)
set_property(TARGET PkgConfig::${_prefix} PROPERTY
INTERFACE_LINK_LIBRARIES "${_libs}")
INTERFACE_LINK_LIBRARIES "${${_prefix}_LINK_LIBRARIES}")
endif()
if(${_prefix}_CFLAGS_OTHER)
set_property(TARGET PkgConfig::${_prefix} PROPERTY
Expand All @@ -241,6 +246,15 @@ function(_pkg_create_imp_target _prefix _no_cmake_path _no_cmake_environment_pat
endif()
endfunction()

# recalculate the dynamic output
# this is a macro and not a function so the result of _pkg_find_libs is automatically propagated
macro(_pkg_recalculate _prefix _no_cmake_path _no_cmake_environment_path _imp_target)
_pkg_find_libs(${_prefix} ${_no_cmake_path} ${_no_cmake_environment_path})
if(${_imp_target})
_pkg_create_imp_target(${_prefix})
endif()
endmacro()

###
macro(_pkg_check_modules_internal _is_required _is_silent _no_cmake_path _no_cmake_environment_path _imp_target _prefix)
_pkgconfig_unset(${_prefix}_FOUND)
Expand Down Expand Up @@ -460,9 +474,7 @@ macro(_pkg_check_modules_internal _is_required _is_silent _no_cmake_path _no_cma
_pkgconfig_invoke_dyn("${_pkg_check_modules_packages}" "${_prefix}" CFLAGS "" --cflags )
_pkgconfig_invoke_dyn("${_pkg_check_modules_packages}" "${_prefix}" CFLAGS_OTHER "" --cflags-only-other )

if (_imp_target)
_pkg_create_imp_target("${_prefix}" ${_no_cmake_path} ${_no_cmake_environment_path})
endif()
_pkg_recalculate("${_prefix}" ${_no_cmake_path} ${_no_cmake_environment_path} ${_imp_target})
endif()

if(NOT "${_extra_paths}" STREQUAL "")
Expand Down Expand Up @@ -525,6 +537,7 @@ endmacro()

<XXX>_FOUND ... set to 1 if module(s) exist
<XXX>_LIBRARIES ... only the libraries (without the '-l')
<XXX>_LINK_LIBRARIES ... the libraries and their absolute paths
<XXX>_LIBRARY_DIRS ... the paths of the libraries (without the '-L')
<XXX>_LDFLAGS ... all required linker flags
<XXX>_LDFLAGS_OTHER ... all other linker flags
Expand Down Expand Up @@ -592,8 +605,10 @@ macro(pkg_check_modules _prefix _module0)
if (${_prefix}_FOUND)
_pkgconfig_set(__pkg_config_arguments_${_prefix} "${_module0};${ARGN}")
endif()
elseif (${_prefix}_FOUND AND ${_imp_target})
_pkg_create_imp_target("${_prefix}" ${_no_cmake_path} ${_no_cmake_environment_path})
else()
if (${_prefix}_FOUND)
_pkg_recalculate("${_prefix}" ${_no_cmake_path} ${_no_cmake_environment_path} ${_imp_target})
endif()
endif()
endmacro()

Expand Down Expand Up @@ -646,8 +661,8 @@ macro(pkg_search_module _prefix _module0)
endif()

_pkgconfig_set(__pkg_config_checked_${_prefix} ${PKG_CONFIG_VERSION})
elseif (${_prefix}_FOUND AND ${_imp_target})
_pkg_create_imp_target("${_prefix}" ${_no_cmake_path} ${_no_cmake_environment_path})
elseif (${_prefix}_FOUND)
_pkg_recalculate("${_prefix}" ${_no_cmake_path} ${_no_cmake_environment_path} ${_imp_target})
endif()
endmacro()

Expand Down
12 changes: 12 additions & 0 deletions Tests/RunCMake/FindPkgConfig/FindPkgConfig_IMPORTED_TARGET.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -85,3 +85,15 @@ pkg_check_modules(FakePackage2 REQUIRED QUIET IMPORTED_TARGET cmakeinternalfakep
if (NOT TARGET PkgConfig::FakePackage2)
message(FATAL_ERROR "No import target for fake package 2 with prefix path")
endif()

# check that the full library path is also returned
if (NOT FakePackage2_LINK_LIBRARIES STREQUAL "${fakePkgDir}/lib/libcmakeinternalfakepackage2.a")
message(FATAL_ERROR "FakePackage2_LINK_LIBRARIES has bad content on first run: ${FakePackage2_LINK_LIBRARIES}")
endif()

# the information in *_LINK_LIBRARIES is not cached, so ensure is also is present on second run
unset(FakePackage2_LINK_LIBRARIES)
pkg_check_modules(FakePackage2 REQUIRED QUIET IMPORTED_TARGET cmakeinternalfakepackage2)
if (NOT FakePackage2_LINK_LIBRARIES STREQUAL "${fakePkgDir}/lib/libcmakeinternalfakepackage2.a")
message(FATAL_ERROR "FakePackage2_LINK_LIBRARIES has bad content on second run: ${FakePackage2_LINK_LIBRARIES}")
endif()

0 comments on commit 92ac721

Please sign in to comment.