Ver Fonte

FindPkgConfig: export the list of found libraries also as variable

Rolf Eike Beer há 7 anos atrás
pai
commit
92ac721a44

+ 6 - 0
Help/release/dev/FindPkgConfig-LINK_LIBRARIES.rst

@@ -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.

+ 2 - 9
Modules/FindBLAS.cmake

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

+ 27 - 12
Modules/FindPkgConfig.cmake

@@ -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)
 
@@ -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
@@ -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)
@@ -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 "")
@@ -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
@@ -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()
 
@@ -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()
 

+ 12 - 0
Tests/RunCMake/FindPkgConfig/FindPkgConfig_IMPORTED_TARGET.cmake

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