Yury G.  Kudryashov wrote:

> 15 January 2012 20:06:51 Alexander Neundorf written:
>> Hi,
> Hi,
> 
> Try #1 awaits moderator approval and can be safely deleted.
>> 
>> I create a new branch ImprovedConfigDotCMakeFile in the kdeexamples
>> repository, used by the buildsystem/HowToInstallALibrary/ example:
>> 
> 
http://quickgit.kde.org/?p=kdeexamples.git&a=tree&h=9c8e84b16079b35f15c50ea0
>> 
> 
27bbc95bd387bf90&hb=6caa67be56231d3017859a26db2097b8c8826f4e&f=buildsystem/H
>> owToInstallALibrary
>> 
>> It adds two new macros, currently called determine_installed_location()
> and
>> set_absolute() which should help with that.
>> Once polished, they should go into cmake (2.8.8), so everybody can use
> them.
> The only comment: there are 4 possible combinations of
> cmake -DLIB_INSTALL_DIR=relative_or_absolute -
> DINCLUDE_INSTALL_DIR=relative_or_absolute
> It seems that your library will not be relocatable if INCLUDE_INSTALL_DIR
> is set to an absolute path.
>> 
>> With these two new macros, the developer does not have to calculate the
>> relative and absolute paths himself anymore, but can rely on their logic.
>> Also the CMakeLists.txt becomes a bit simpler, by removing the IMO most
>> obscure part (the calculation of the relative install dir).
>> 
>> Comments ?
> I'm working on another way to solve the same problem. I'll commit results
> to kdeexamples tonight or tomorrow.
An alpha-version is attached.

Usage example:
 // Add EXPORT LibKexiv2 to kexiv2 target and
  INCLUDE(MacroWriteConfigFile)
  INSTALL_CMAKE_CONFIG_FILES(LibKexiv2
                       VERSION ${KEXIV2_LIB_VERSION}
                       VERSION_STRING ${KEXIV2_LIB_VERSION_STRING}
                       EXPORT_NAMESPACE LibKexiv2::
                       TARGETS kexiv2)

Actually, I'd prefer to have
install(EXPORT ... ... INSTALL_CONFIG [bool] PACKAGE_NAME [=ExportName])
or
install(EXPORT ...)
config_for_export(ExportName VERSION ... VERSION_STRING ... EXTRA_VARS ...).
What do you think about this?

I cannot implement config_for_export() because I don't know how to query 
cmake for the list of targets associated with given export (is it 
possible?).
-- 
Yury G. Kudryashov,
mailto: [email protected]
# install_cmake_config_files(PACKAGE
#                     LIBRARY_TARGETS (target|NAME=target)+
#                     [EXECUTABLE_TARGETS (NAME=target)+]
#                     [VERSION version=${PACKAGE_UPPERCASE}_VERSION]
#                     [VERSION_STRING <var|value>]
#                     [EXPORT_NAME name=${PACKAGE}]
#                     [EXPORT_NAMESPACE ns=""]
#                     [DESTINATION destination=platform-specific default]
#                     [INSTALLED_INCLUDES dirs=${INCLUDE_INSTALL_DIR} or ${CMAKE_INSTALL_INCLUDEDIR}]
#                     [BUILD_INCLUDES dirs=${CMAKE_CURRENT_SOURCE_DIR}]
#                     [EXTRA_VARS (name|name=value)*]
#                     [EXTRA_CONFIG_FILE file])
#



function(install_cmake_config_files ICCF_PACKAGE)
  string(TOUPPER ${ICCF_PACKAGE} ICCF_PACKAGE_UPPER)
  include(CMakeParseArguments)
  set(options )
  set(oneValueArgs VERSION VERSION_STRING EXPORT_NAME EXPORT_FILENAME EXPORT_NAMESPACE DESTINATION EXTRA_CONFIG_FILE)
  set(multiValueArgs TARGETS INSTALLED_INCLUDES BUILD_INCLUDES EXTRA_VARS)
  cmake_parse_arguments(ICCF "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
  if(ICCF_UNPARSED_ARGUMENTS)
    message(SEND_ERROR "Unknown argument(s) ${ICCF_UNPARSED_ARGUMENTS}")
  endif()

  # Assign default values to missing arguments
  if(NOT ICCF_DESTINATION)
    # TODO: MacOS X Frameworks support
    if(DEFINED CMAKE_INSTALL_LIBDIR) # GNU style
      set(_default ${CMAKE_INSTALL_LIBDIR}/cmake/${_name})
    elseif(DEFINED LIB_INSTALL_DIR) # KDE style
      set(_default ${LIB_INSTALL_DIR}/cmake/${_name})
    else()
      set(_default lib/cmake/${_name})
    endif()

    set(ICCF_${ICCF_PACKAGE_UPPER}_CMAKEFILES_INSTALL_DIR CACHE PATH "Install path for cmake config files (${ICCF_PACKAGE}Config.cmake etc.)")
    set(ICCF_DESTINATION ${_default} ${ICCF_${ICCF_PACKAGE_UPPER}_CMAKEFILES_INSTALL_DIR})
  endif()

  if(IS_ABSOLUTE ${ICCF_DESTINATION})
    set(ICCF_DESTINATION_ABSOLUTE ${ICCF_DESTINATION})
    file(RELATIVE_PATH ICCF_DESTINATION_RELATIVE ${CMAKE_INSTALL_PREFIX} ${ICCF_DESTINATION})
  else()
    set(ICCF_DESTINATION_RELATIVE ${ICCF_DESTINATION})
    set(ICCF_DESTINATION_ABSOLUTE ${CMAKE_INSTALL_PREFIX}/${ICCF_DESTINATION})
  endif()

  if(NOT ICCF_EXPORT_NAME)
    set(ICCF_EXPORT_NAME ${ICCF_PACKAGE})
  endif()

  if(NOT ICCF_EXPORT_FILENAME)
    # Use the same logic as install(EXPORT)
    # TODO: Use PackageTargets.cmake instead?s
    set(ICCF_EXPORT_FILENAME ${ICCF_EXPORT_NAME}.cmake)
  endif()

  if(NOT ICCF_EXPORT_NAMESPACE)
    set(ICCF_EXPORT_NAMESPACE "")
  endif()

  if(NOT ICCF_VERSION)
    set(ICCF_VERSION ${${ICCF_PACKAGE_UPPER}_VERSION})
  endif()
  if(NOT ICCF_VERSION)
    message(FATAL_ERROR "No VERSION given and ${ICCF_PACKAGE_UPPER}_VERSION is not defined")
  endif()

  if(ICCF_VERSION_STRING)
    if(DEFINED ${ICCF_VERSION_STRING})
      set(ICCF_VERSION_STRING ${ICCF_VERSION_STRING})
    endif()
  elseif(DEFINED ${ICCF_PACKAGE_UPPER}_VERSION_STRING)
    set(ICCF_VERSION_STRING ${${ICCF_PACKAGE_UPPER}_VERSION_STRING})
  else()
    set(ICCF_VERSION_STRING ${ICCF_VERSION})
  endif()

  if(NOT ICCF_INSTALLED_INCLUDES)
    if(CMAKE_INSTALL_INCLUDEDIR)
      set(ICCF_INSTALLED_INCLUDES ${CMAKE_INSTALL_INCLUDEDIR})
    elseif(INCLUDE_INSTALL_DIR)
      set(ICCF_INSTALLED_INCLUDES ${INCLUDE_INSTALL_DIR})
    else()
      set(ICCF_INSTALLED_INCLUDES include)
    endif()
  endif()

  set(ICCF_RELATIVE_INCLUDES)
  foreach(inc ${ICCF_INSTALLED_INCLUDES})
    if(IS_ABSOLUTE ${inc})
      set(abs ${inc})
    else()
      set(abs ${CMAKE_INSTALL_PREFIX}/${inc})
    endif()
    file(RELATIVE_PATH rel ${ICCF_DESTINATION_ABSOLUTE} ${abs})
    list(APPEND ICCF_RELATIVE_INCLUDES "\${ICCF_CWD}/${rel}")
  endforeach()

  if(NOT ICCF_BUILD_INCLUDES)
    set(ICCF_BUILD_INCLUDES ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR})
  endif()

  # Variables set, let's write config files
  # Header
  set(ICCF_CONFIG_EXTERNAL "# Warning: This file is generated automatically. DO NOT EDIT!")
  # Version information
  foreach(suffix VERSION VERSION_STRING)
    set(ICCF_CONFIG_EXTERNAL "${ICCF_CONFIG_EXTERNAL}\nset(${ICCF_PACKAGE_UPPER}_${suffix} ${ICCF_${suffix}})")
  endforeach()
  # After that line internal config differs from external.
  set(ICCF_CONFIG_INTERNAL ${ICCF_CONFIG_EXTERNAL})

  # @PACKAGE@_INCLUDE_DIRS
  set(ICCF_CONFIG_EXTERNAL "${ICCF_CONFIG_EXTERNAL}
get_filename_component(ICCF_CWD \${CMAKE_CURRENT_LIST_FILE} PATH)
set(${ICCF_PACKAGE_UPPER}_INCLUDE_DIRS \"${ICCF_RELATIVE_INCLUDES}\")
include(\${ICCF_CWD}/${ICCF_EXPORT_FILENAME})
")
  set(ICCF_CONFIG_INTERNAL "${ICCF_CONFIG_INTERNAL}
set(${ICCF_PACKAGE_UPPER}_INCLUDE_DIRS ${ICCF_BUILD_INCLUDES})
")

  # Targets
  set(ICCF_LIBRARY_TARGETS)
  set(ICCF_LIBRARY_TARGETS_NS)
  foreach(_t ${ICCF_TARGETS})
    if(_t MATCHES "(.*)=(.*)")
      set(name ${CMAKE_MATCH_1})
      set(target ${CMAKE_MATCH_2})
    else()
      string(TOUPPER ${_t} name)
      set(target ${_t})
    endif()
    if(NOT TARGET ${target})
      message(FATAL_ERROR "${target} is not a target")
    endif()
    get_target_property(type ${target} TYPE)
    if(type STREQUAL STATIC_LIBRARY OR type STREQUAL SHARED_LIBRARY)
      set(type "LIBRARY")
      list(APPEND ICCF_LIBRARY_TARGETS ${target})
      list(APPEND ICCF_LIBRARY_TARGETS_NS ${ICCF_EXPORT_NAMESPACE}${target})
    elseif(NOT type STREQUAL EXECUTABLE)
      message(FATAL_ERROR "Target ${target} is neither of shared library, static library and executable")
    endif()
    set(ICCF_CONFIG_EXTERNAL "${ICCF_CONFIG_EXTERNAL}
set(${ICCF_PACKAGE_UPPER}_${name}_${type} ${ICCF_EXPORT_NAMESPACE}${target})")
    set(ICCF_CONFIG_INTERNAL "${ICCF_CONFIG_INTERNAL}
set(${ICCF_PACKAGE_UPPER}_${name}_${type} ${target})")
  endforeach()

  if(ICCF_LIBRARY_TARGETS)
    set(ICCF_CONFIG_EXTERNAL "${ICCF_CONFIG_EXTERNAL}
set(${ICCF_PACKAGE_UPPER}_LIBRARIES ${ICCF_LIBRARY_TARGETS_NS})")
    set(ICCF_CONFIG_INTERNAL "${ICCF_CONFIG_INTERNAL}
set(${ICCF_PACKAGE_UPPER}_LIBRARIES ${ICCF_LIBRARY_TARGETS})")
  endif()
  foreach(_v ${ICCF_EXTRA_VARS})
    if(_v MATCHES "(.*)=(.*)")
      set(var ${CMAKE_MATCH_1})
      if(DEFINED ${CMAKE_MATCH_2})
        set(value ${${CMAKE_MATCH_2}})
      else()
        set(value ${CMAKE_MATCH_2})
      endif()
    elseif(DEFINED ${_v})
      set(var ${_v})
      set(value ${${_v}})
    else()
      message(SEND_ERROR "Cannot export undefined variable ${_v}")
    endif()

    set(ICCF_CONFIG_EXTERNAL "${ICCF_CONFIG_EXTERNAL}\nset(${var} ${value})")
    set(ICCF_CONFIG_INTERNAL "${ICCF_CONFIG_EXTERNAL}\nset(${var} ${value})")
  endforeach()

  file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/${ICCF_PACKAGE}Config-external.cmake ${ICCF_CONFIG_EXTERNAL})
  file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/${ICCF_PACKAGE}Config.cmake ${ICCF_CONFIG_INTERNAL})

  install(EXPORT ${ICCF_EXPORT_NAME}
    DESTINATION ${ICCF_DESTINATION}
    NAMESPACE ${ICCF_EXPORT_NAMESPACE}
    FILE ${ICCF_EXPORT_FILENAME}
    COMPONENT Devel)
endfunction()

# kate: space-indent on; indent-width 2; replace-tabs on;

_______________________________________________
Kde-buildsystem mailing list
[email protected]
https://mail.kde.org/mailman/listinfo/kde-buildsystem

Reply via email to