Browse Source

Merge topic 'FindPkgConfig-global-target'

7aa26cf0e9 FindPkgConfig: allow to create global imported targets

Acked-by: Kitware Robot <[email protected]>
Merge-request: !2193
Brad King 7 years ago
parent
commit
949c62175e

+ 5 - 0
Help/release/dev/pkgc-global.rst

@@ -0,0 +1,5 @@
+pkgc-global
+-----------
+
+* Module ``FindPkgConfig`` gains capability to create imported targets in
+  global scope.

+ 31 - 16
Modules/FindPkgConfig.cmake

@@ -114,12 +114,13 @@ macro(_pkgconfig_invoke_dyn _pkglist _prefix _varname cleanup_regexp)
 endmacro()
 
 # Splits given arguments into options and a package list
-macro(_pkgconfig_parse_options _result _is_req _is_silent _no_cmake_path _no_cmake_environment_path _imp_target)
+macro(_pkgconfig_parse_options _result _is_req _is_silent _no_cmake_path _no_cmake_environment_path _imp_target _imp_target_global)
   set(${_is_req} 0)
   set(${_is_silent} 0)
   set(${_no_cmake_path} 0)
   set(${_no_cmake_environment_path} 0)
   set(${_imp_target} 0)
+  set(${_imp_target_global} 0)
   if(DEFINED PKG_CONFIG_USE_CMAKE_PREFIX_PATH)
     if(NOT PKG_CONFIG_USE_CMAKE_PREFIX_PATH)
       set(${_no_cmake_path} 1)
@@ -146,14 +147,22 @@ macro(_pkgconfig_parse_options _result _is_req _is_silent _no_cmake_path _no_cma
     if (_pkg STREQUAL "IMPORTED_TARGET")
       set(${_imp_target} 1)
     endif()
+    if (_pkg STREQUAL "GLOBAL")
+      set(${_imp_target_global} 1)
+    endif()
   endforeach()
 
+  if (${_imp_target_global} AND NOT ${_imp_target})
+    message(SEND_ERROR "the argument GLOBAL may only be used together with IMPORTED_TARGET")
+  endif()
+
   set(${_result} ${ARGN})
   list(REMOVE_ITEM ${_result} "REQUIRED")
   list(REMOVE_ITEM ${_result} "QUIET")
   list(REMOVE_ITEM ${_result} "NO_CMAKE_PATH")
   list(REMOVE_ITEM ${_result} "NO_CMAKE_ENVIRONMENT_PATH")
   list(REMOVE_ITEM ${_result} "IMPORTED_TARGET")
+  list(REMOVE_ITEM ${_result} "GLOBAL")
 endmacro()
 
 # Add the content of a variable or an environment variable to a list of
@@ -225,11 +234,16 @@ function(_pkg_find_libs _prefix _no_cmake_path _no_cmake_environment_path)
 endfunction()
 
 # create an imported target from all the information returned by pkg-config
-function(_pkg_create_imp_target _prefix)
+function(_pkg_create_imp_target _prefix _imp_target_global)
   # only create the target if it is linkable, i.e. no executables
   if (NOT TARGET PkgConfig::${_prefix}
       AND ( ${_prefix}_INCLUDE_DIRS OR ${_prefix}_LINK_LIBRARIES OR ${_prefix}_CFLAGS_OTHER ))
-    add_library(PkgConfig::${_prefix} INTERFACE IMPORTED)
+    if(${_imp_target_global})
+      set(_global_opt "GLOBAL")
+    else()
+      unset(_global_opt)
+    endif()
+    add_library(PkgConfig::${_prefix} INTERFACE IMPORTED ${_global_opt})
 
     if(${_prefix}_INCLUDE_DIRS)
       set_property(TARGET PkgConfig::${_prefix} PROPERTY
@@ -248,15 +262,15 @@ 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)
+macro(_pkg_recalculate _prefix _no_cmake_path _no_cmake_environment_path _imp_target _imp_target_global)
   _pkg_find_libs(${_prefix} ${_no_cmake_path} ${_no_cmake_environment_path})
   if(${_imp_target})
-    _pkg_create_imp_target(${_prefix})
+    _pkg_create_imp_target(${_prefix} ${_imp_target_global})
   endif()
 endmacro()
 
 ###
-macro(_pkg_check_modules_internal _is_required _is_silent _no_cmake_path _no_cmake_environment_path _imp_target _prefix)
+macro(_pkg_check_modules_internal _is_required _is_silent _no_cmake_path _no_cmake_environment_path _imp_target _imp_target_global _prefix)
   _pkgconfig_unset(${_prefix}_FOUND)
   _pkgconfig_unset(${_prefix}_VERSION)
   _pkgconfig_unset(${_prefix}_PREFIX)
@@ -474,7 +488,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 )
 
-      _pkg_recalculate("${_prefix}" ${_no_cmake_path} ${_no_cmake_environment_path} ${_imp_target})
+      _pkg_recalculate("${_prefix}" ${_no_cmake_path} ${_no_cmake_environment_path} ${_imp_target} ${_imp_target_global})
     endif()
 
     if(NOT "${_extra_paths}" STREQUAL "")
@@ -502,7 +516,7 @@ endmacro()
                       [REQUIRED] [QUIET]
                       [NO_CMAKE_PATH]
                       [NO_CMAKE_ENVIRONMENT_PATH]
-                      [IMPORTED_TARGET]
+                      [IMPORTED_TARGET [GLOBAL]]
                       <moduleSpec> [<moduleSpec>...])
 
   When the ``REQUIRED`` argument is given, the command will fail with an error
@@ -521,7 +535,8 @@ endmacro()
 
   The ``IMPORTED_TARGET`` argument will create an imported target named
   ``PkgConfig::<prefix>`` that can be passed directly as an argument to
-  :command:`target_link_libraries`.
+  :command:`target_link_libraries`. The ``GLOBAL`` argument will make the
+  imported target available in global scope.
 
   Each ``<moduleSpec>`` must be in one of the following formats::
 
@@ -594,12 +609,12 @@ endmacro()
     XRENDER_STATIC_LIBRARIES=Xrender;X11;pthread;Xau;Xdmcp
 #]========================================]
 macro(pkg_check_modules _prefix _module0)
-  _pkgconfig_parse_options(_pkg_modules _pkg_is_required _pkg_is_silent _no_cmake_path _no_cmake_environment_path _imp_target "${_module0}" ${ARGN})
+  _pkgconfig_parse_options(_pkg_modules _pkg_is_required _pkg_is_silent _no_cmake_path _no_cmake_environment_path _imp_target _imp_target_global "${_module0}" ${ARGN})
   # check cached value
   if (NOT DEFINED __pkg_config_checked_${_prefix} OR __pkg_config_checked_${_prefix} LESS ${PKG_CONFIG_VERSION} OR NOT ${_prefix}_FOUND OR
       (NOT "${ARGN}" STREQUAL "" AND NOT "${__pkg_config_arguments_${_prefix}}" STREQUAL "${_module0};${ARGN}") OR
       (    "${ARGN}" STREQUAL "" AND NOT "${__pkg_config_arguments_${_prefix}}" STREQUAL "${_module0}"))
-    _pkg_check_modules_internal("${_pkg_is_required}" "${_pkg_is_silent}" ${_no_cmake_path} ${_no_cmake_environment_path} ${_imp_target} "${_prefix}" ${_pkg_modules})
+    _pkg_check_modules_internal("${_pkg_is_required}" "${_pkg_is_silent}" ${_no_cmake_path} ${_no_cmake_environment_path} ${_imp_target} ${_imp_target_global} "${_prefix}" ${_pkg_modules})
 
     _pkgconfig_set(__pkg_config_checked_${_prefix} ${PKG_CONFIG_VERSION})
     if (${_prefix}_FOUND)
@@ -607,7 +622,7 @@ macro(pkg_check_modules _prefix _module0)
     endif()
   else()
     if (${_prefix}_FOUND)
-      _pkg_recalculate("${_prefix}" ${_no_cmake_path} ${_no_cmake_environment_path} ${_imp_target})
+      _pkg_recalculate("${_prefix}" ${_no_cmake_path} ${_no_cmake_environment_path} ${_imp_target} ${_imp_target_global})
     endif()
   endif()
 endmacro()
@@ -624,7 +639,7 @@ endmacro()
                       [REQUIRED] [QUIET]
                       [NO_CMAKE_PATH]
                       [NO_CMAKE_ENVIRONMENT_PATH]
-                      [IMPORTED_TARGET]
+                      [IMPORTED_TARGET [GLOBAL]]
                       <moduleSpec> [<moduleSpec>...])
 
   Examples
@@ -634,7 +649,7 @@ endmacro()
     pkg_search_module (BAR libxml-2.0 libxml2 libxml>=2)
 #]========================================]
 macro(pkg_search_module _prefix _module0)
-  _pkgconfig_parse_options(_pkg_modules_alt _pkg_is_required _pkg_is_silent _no_cmake_path _no_cmake_environment_path _imp_target "${_module0}" ${ARGN})
+  _pkgconfig_parse_options(_pkg_modules_alt _pkg_is_required _pkg_is_silent _no_cmake_path _no_cmake_environment_path _imp_target _imp_target_global "${_module0}" ${ARGN})
   # check cached value
   if (NOT DEFINED __pkg_config_checked_${_prefix} OR __pkg_config_checked_${_prefix} LESS ${PKG_CONFIG_VERSION} OR NOT ${_prefix}_FOUND)
     set(_pkg_modules_found 0)
@@ -646,7 +661,7 @@ macro(pkg_search_module _prefix _module0)
     # iterate through all modules and stop at the first working one.
     foreach(_pkg_alt ${_pkg_modules_alt})
       if(NOT _pkg_modules_found)
-        _pkg_check_modules_internal(0 1 ${_no_cmake_path} ${_no_cmake_environment_path} ${_imp_target} "${_prefix}" "${_pkg_alt}")
+        _pkg_check_modules_internal(0 1 ${_no_cmake_path} ${_no_cmake_environment_path} ${_imp_target} ${_imp_target_global} "${_prefix}" "${_pkg_alt}")
       endif()
 
       if (${_prefix}_FOUND)
@@ -662,7 +677,7 @@ macro(pkg_search_module _prefix _module0)
 
     _pkgconfig_set(__pkg_config_checked_${_prefix} ${PKG_CONFIG_VERSION})
   elseif (${_prefix}_FOUND)
-    _pkg_recalculate("${_prefix}" ${_no_cmake_path} ${_no_cmake_environment_path} ${_imp_target})
+    _pkg_recalculate("${_prefix}" ${_no_cmake_path} ${_no_cmake_environment_path} ${_imp_target} ${_imp_target_global})
   endif()
 endmacro()
 

+ 13 - 1
Tests/RunCMake/FindPkgConfig/FindPkgConfig_IMPORTED_TARGET.cmake

@@ -1,10 +1,12 @@
-cmake_minimum_required(VERSION 3.5)
+cmake_minimum_required(VERSION 3.12)
 
 project(FindPkgConfig_IMPORTED_TARGET C)
 
 find_package(PkgConfig REQUIRED)
 pkg_check_modules(NCURSES IMPORTED_TARGET QUIET ncurses)
 
+message(STATUS "source: ${CMAKE_CURRENT_SOURCE_DIR} bin ${CMAKE_CURRENT_BINARY_DIR}")
+
 if (NCURSES_FOUND)
   set(tgt PkgConfig::NCURSES)
   if (NOT TARGET ${tgt})
@@ -66,6 +68,16 @@ if (NOT TARGET PkgConfig::FakePackage1)
   message(FATAL_ERROR "No import target for fake package 1 with prefix path")
 endif()
 
+# find targets in subdir and check their visibility
+add_subdirectory(target_subdir)
+if (TARGET PkgConfig::FakePackage1_dir)
+  message(FATAL_ERROR "imported target PkgConfig::FakePackage1_dir is visible outside it's directory")
+endif()
+
+if (NOT TARGET PkgConfig::FakePackage1_global)
+  message(FATAL_ERROR "imported target PkgConfig::FakePackage1_global is not visible outside it's directory")
+endif()
+
 # And now do the same for the NO_CMAKE_ENVIRONMENT_PATH - ENV{CMAKE_PREFIX_PATH}
 # combination
 unset(CMAKE_PREFIX_PATH)

+ 5 - 0
Tests/RunCMake/FindPkgConfig/target_subdir/CMakeLists.txt

@@ -0,0 +1,5 @@
+# a target with visibility only in this directory
+pkg_check_modules(FakePackage1_dir REQUIRED QUIET IMPORTED_TARGET cmakeinternalfakepackage1)
+
+# the same with global visibility
+pkg_check_modules(FakePackage1_global REQUIRED QUIET IMPORTED_TARGET GLOBAL cmakeinternalfakepackage1)