[CMake] Printing "Found <package>..." message in config mode

Sebastián Mancilla smancill at jlab.org
Tue Aug 14 16:08:36 EDT 2018


Normally, find modules call FIND_PACKAGE_HANDLE_STANDARD_ARGS, which in
turn calls FIND_PACKAGE_MESSAGE, to print a nice message about the location
and version of the dependency.

But I haven't found any way or example to do the same when using the CONFIG
mode of find_package. And I really want to see some output about where the
dependencies are located. So I came up with this:

    # Prints a message with the location and version of a package
    # found in config mode, similar to the message printed by module files.
    # When multiple configurations are installed, this tries to print
    # the location to the same library selected by the CMake generator.
    #
    # TODO: handle configuration mapping (?)
    function(find_package_config_message _package _target _version)
      # The location matching the same build configuration as downstream
      # is selected when linking to the library
      set(_build_type ${CMAKE_BUILD_TYPE})
      if (_build_type)
        string(TOUPPER "IMPORTED_LOCATION_${_build_type}" _location_prop)
        get_target_property(_location_path ${_target} ${_location_prop})
      endif()
      # If downstream has no build configuration set,
      # or the installed package has no matching configuration,
      # the first listed configuration is used to get the location to the
library
      if(NOT _location_path)
        get_target_property(_target_configurations ${_target}
IMPORTED_CONFIGURATIONS)
        if(_target_configurations)
          list(GET _target_configurations 0 _build_type)
          get_target_property(_location_path ${_target}
"IMPORTED_LOCATION_${_build_type}")
        endif()
        if (NOT _location_path)
          message(SEND_ERROR "No imported location for target ${_target}")
        endif()
      endif()

      set(_message "Found ${_package}")
      set(_details "[${_build_type}]")
      if(_location_path)
        set(_message "${_message}: ${_location_path}")
        set(_details "[${_location_path}]${_details}")
      endif()
      if(_version)
        set(_message "${_message} (found version \"${_version}\")")
        set(_details "[${_version}]${_details}")
      endif()
      find_package_message(${_package} ${_message} ${_details})
    endfunction()

I think I got it right, based on the observed behavior while experimenting
with different values for CMAKE_BUILD_TYPE on both upstream and downstream,
and it works fine for most common cases.

I would use in the FooConfig.cmake like this (the function would be in
FooHelpers.cmake):

    if(NOT TARGET Foo::Foo)
      include("${CMAKE_CURRENT_LIST_DIR}/FooTargets.cmake")
      include("${CMAKE_CURRENT_LIST_DIR}/FooHelpers.cmake")
      find_package_config_message(Foo Foo::Foo "@PROJECT_VERSION@")
    endif()

Any thoughts/comments?

-- 
Sebastian Mancilla
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://cmake.org/pipermail/cmake/attachments/20180814/fad8c490/attachment.html>


More information about the CMake mailing list