[cmake-developers] Making Config.cmake files easier to write

Alexander Neundorf neundorf at kde.org
Tue Feb 14 15:57:52 EST 2012


On Tuesday 14 February 2012, Yury G. Kudryashov wrote:
> Alexander Neundorf wrote:
> > On Tuesday 14 February 2012, Yury G. Kudryashov wrote:
> >> will substitute @PACKAGE_INCLUDE_INSTALL_DIR@ by "../../../include" and
> >> @PACKAGE_MYPKGDATA_INSTALL_DIR@ by "../../../share/mypkg" (both
> >> transformed to be relative to DESTINATION).
> > 
> > A problem I see here (and which we discussed already before on kde-
> > buildsystem) is the handling of the install() command.
> > 
> > I thought a bit about a syntax like this, which I would like:
> > 
> > configure_config_file(BarConfig.cmake.in BarConfig.cmake
> > 
> >               INSTALL_DESTINATION ${CMAKECONFIG_INSTALL_DIR}
> >               PATH_VARS INCLUDE_INSTALL_DIR DATA_INSTALL_DIR
> >               EXPORT_FILE BarExport.cmake)
> 
> Why do you need EXPORT_FILE parameter? How can you use it? Include
> automatically? Then you need VERSION_FILE parameter as well.
> 
> > but this can't work, can it ?
> > 
> > In the BarConfig.cmake file there would still be either a
> > 
> > set(BAR_INCLUDE_DIR "@INCLUDE_INSTALL_DIR@")
> > which would work for absolute paths, or a
> > 
> > set(BAR_INCLUDE_DIR "${SomePrefix}/@INCLUDE_INSTALL_DIR@")
> > which would work only for relative paths, but a simple set() cannot work
> > for both cases. Am I missing something ?
> 
> You'll have in BarConfig.cmake.in
> set(BAR_INCLUDE_DIR "@PACKAGE_HELPER_INCLUDE_INSTALL_DIR@)
> 
> After configure_config_file() you'll have
> # At top
> get_filename_component(_PKG_CURRENT_DIR "${CURRENT_LIST_FILE}" PATH)

Just a tip: since 2.8.3 or so there is ${CMAKE_CURRENT_LIST_DIR}

> get_filename_component(_PKG_PREFIX_PATH "${_PKG_CURRENT_DIR}/../../.."
> ABSOLUTE)

The ../../../ will be also calculated by the macro, using RELATIVE_PATH and 
the DESTINATION parameter, right ?
 
> #in place of your set()
> set(BAR_INCLUDE_DIR "${_PKG_PREFIX_PATH}/include")
> 
> > Do you have a working example ?
> 
> Not yet. I think about something like this (not tested).
> 
>   foreach(var ${PACAKGE_HELPER_PATH_VARS})
>     if(NOT DEFINED ${var})
>       message(FATAL_ERROR ...)
>     else if(IS_ABSOLUTE ${${var}})
>       file(RELATIVE_PATH PACKAGE_HELPER_${var} ${CMAKE_INSTALL_PREFIX}
> ${${var}})
>     else()
>       set(PACKAGE_HELPER_${var} ${${var}})
>     endif()
>   endforeach()
> 
> It would be nice to make those PACKAGE_HELPER_* vars local to
> configure_config_file() function.

If it's a function(), they are local automatically.

Also still not tested, but now it should have the right prefix:

foreach(var ${PACAKGE_HELPER_PATH_VARS})
  if(NOT DEFINED ${var})
    message(FATAL_ERROR ...)
  else if(IS_ABSOLUTE ${${var}})
    string(REPLACE "${CMAKE_INSTALL_PREFIX}" "\${_PKG_PREFIX_PATH}"
                    PACKAGE_HELPER_${var} "${${var}}"
    else()
      set(PACKAGE_HELPER_${var} ${${var}})
    endif()
  else()
    set(PACKAGE_HELPER_${var} "\${_PKG_PREFIX_PATH}/${${var}}")
  endif()
endforeach()


A nice feature of my proposed macro was that it additionally checked that the 
file/directory actually exists. That's a nice thing, because it makes sure 
that you don't get information out of the Config.cmake file which is wrong 
(due to bad packaging or whatever).

Alex



More information about the cmake-developers mailing list