Skip to content
Snippets Groups Projects
FindPackageAddDependency.cmake 4.06 KiB
Newer Older
uindra's avatar
uindra committed
####################################################################################################
#
# This is a wrapper around find_package() which tries to handle consistently the resulting
# dependency of the currently built package on other packages once it is installed.
#
# It populates a global property ${PROJECT_NAME}_PACKAGE_DEPENDENCIES which can be used in your template
# [my_pkg]Config.cmake.in file like so:
#
#    @PACKAGE_INIT@
#
#    include(CMakeFindDependencyMacro)
#    @MYPROJ_PACKAGE_DEPENDENCIES@
#
# MYPROJ_PACKAGE_DEPENDENCIES will contain 1 call to find_dependency() for each package which
# was successfully found by the call to find_package().
#
# Usage:
#
# find_package_add_dependency([PACKAGE] [WITH_VAR [TRUE_IF_FOUND]] [ANY OTHER FIND_PACKAGE ARGUMENTS])
#
# Optional argument WITH_VAR is the name of the variable which find_package([pkg]) sets
# to TRUE if the package is found - if not given, by default we assume this to be pkg_FOUND
#
# Optional argument BEFORE_FIND can be used to add any code that may be required
# before calling find_dependency() for the package, for example modifying the CMAKE_MODULE_PATH
#
# Any other argument values are passed to find_package() (QUIET, REQUIRED, VERSION, etc.)
#
# include(FindPackageAddDependency)
# find_package_add_dependency(SomeGreatPackage 3.10 REQUIRED)
#
#   -> if found, this will set SomeGreatPackage_FOUND to TRUE,
#      and we add a call to find_dependency(SomeGreatPackage 3.10 REQUIRED) to the
#      dependency list
#
# find_package_add_dependency(UnusualPackage WITH_VAR HAVE_UnusualPackage
#                                       6.3 COMPONENTS UnusualComponentA UnusualComponentF)
#
#   -> if UnusualPackage is found with its components UnusualComponentA and UnusualComponentF,
#      HAVE_UnnusualPackage is set to TRUE and we add a call to
#      find_dependency(UnusualPackage 6.3 COMPONENTS UnusualComponentA UnusualComponentF)
#      to the dependency list
#
# find_package_add_dependency(HardToFind
#                               BEFORE_FIND "set(CMAKE_MODULE_PATH \${CMAKE_MODULE_PATH} \${CMAKE_CURRENT_LIST_DIR})"
#                             )
#
#   -> the FindHardToFind.cmake module can only be found in the CMAKE_CURRENT_LIST_DIR of the Config file
#      Note that any '$' in the string needs to be escaped: '\$'
include(CMakeParseArguments)

set_property(GLOBAL PROPERTY ${PROJECT_NAME}_PACKAGE_DEPENDENCIES "")

function(find_package_add_dependency package)

   CMAKE_PARSE_ARGUMENTS(ARG "" "WITH_VAR;BEFORE_FIND" "" ${ARGN})
   
   if(ARG_WITH_VAR)
      set(PKG_FOUND_VAR ${ARG_WITH_VAR})
   else(ARG_WITH_VAR)
      set(PKG_FOUND_VAR "${package}_FOUND")
   endif(ARG_WITH_VAR)

   if(ARG_BEFORE_FIND)
       set(FIND_PREAMBLE "${ARG_BEFORE_FIND}\n")
   else(ARG_BEFORE_FIND)
       set(FIND_PREAMBLE "")
   endif(ARG_BEFORE_FIND)

   find_package(${package} ${ARG_UNPARSED_ARGUMENTS})
   if(${PKG_FOUND_VAR})
      set_property(GLOBAL
                     APPEND_STRING
                     PROPERTY ${PROJECT_NAME}_PACKAGE_DEPENDENCIES
                     "#-- handle ${package} dependency\n${FIND_PREAMBLE}find_dependency(${package}")
      if(ARG_UNPARSED_ARGUMENTS)
      	 foreach(arg ${ARG_UNPARSED_ARGUMENTS})
	 
      	    set_property(GLOBAL
                     APPEND_STRING
                     PROPERTY ${PROJECT_NAME}_PACKAGE_DEPENDENCIES
                     " ${arg}")
	 
	 endforeach()
      endif(ARG_UNPARSED_ARGUMENTS)
 	 
      set_property(GLOBAL
	      APPEND_STRING
	      PROPERTY ${PROJECT_NAME}_PACKAGE_DEPENDENCIES
	      ")\n")

   endif(${PKG_FOUND_VAR})

   #-- set all variables defined by package in parent scope
   get_property(dir_variables DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VARIABLES)
   #-- make sure to escape the special regex character '+' in the package name
   string(REPLACE "+" "\\+" package_regex ${package})
   string(TOUPPER ${package_regex} PACKAGE_REGEX)
   foreach(dir_var ${dir_variables})
      if(dir_var MATCHES ${package_regex} OR dir_var MATCHES ${PACKAGE_REGEX})
      	 set(${dir_var} ${${dir_var}} PARENT_SCOPE)
      endif()
   endforeach()
   
endfunction()