On Tuesday 14 February 2012, Alexander Neundorf wrote: > 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()
Ok, a working ConfigureConfigFile.cmake is attached, together with example files, input and the configured output and the driving CMakeLists.txt. The call now looks like this: configure_config_file(BarConfig.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/BarConfig.cmake INSTALL_DESTINATION "${CMAKECONFIG_INSTALL_DIR}" PATH_VARS INCLUDE_INSTALL_DIR BIN_INSTALL_DIR FOO_INSTALL_DIR ... ) and in the Config.cmake.in file you have to put: @CONFIG_HELPER_DIRS_INIT@ set_and_check(BAR_INCLUDE_DIR "@CONFIG_HELPER_INCLUDE_INSTALL_DIR@") set(BAR_DATA_DIR "@CONFIG_HELPER_DATA_INSTALL_DIR@") The set_and_check() macro is provided by the @CONFIG_HELPER_DIRS_INIT@, it sets the variable and checks that the given directory or file exists. IMO it's a bit much macro magic. I'll also try an alternative approach tomorrow. Comments ? Alex
# set the version of myself set(BAR_VERSION_MAJOR @BAR_VERSION_MAJOR@) set(BAR_VERSION_MINOR @BAR_VERSION_MINOR@) set(BAR_VERSION_PATCH @BAR_VERSION_PATCH@) set(BAR_VERSION ${BAR_VERSION_MAJOR}.${BAR_VERSION_MINOR}.${BAR_VERSION_PATCH} ) # get_filename_component(CONFIG_PREFIX_DIR "${CMAKE_CURRENT_LIST_DIR}/@CONFIG_RELATIVE_PATH@" ABSOLUTE) @CONFIG_HELPER_DIRS_INIT@ set_and_check(BAR_INCLUDE_DIR "@CONFIG_HELPER_INCLUDE_INSTALL_DIR@") set_and_check(BAR_BIN_DIR "@CONFIG_HELPER_BIN_INSTALL_DIR@") set(BAR_DATA_DIR "@CONFIG_HELPER_DATA_INSTALL_DIR@") set(BAR_BAR_DIR "@CONFIG_HELPER_BAR_INSTALL_DIR@") set(BAR_FOO_DIR "@CONFIG_HELPER_FOO_INSTALL_DIR@") # what is my include directory set(BAR_INCLUDES "${BAR_INCLUDE_DIR}") # import the exported targets include(${CMAKE_CURRENT_LIST_DIR}/BarTargets.cmake) # set the expected library variable set(BAR_LIBRARIES bar )
cmake_minimum_required(VERSION 2.8.7) project(Bar) # the version number, needed for # - the library version # - version detection by cmake set(BAR_VERSION_MAJOR 1) set(BAR_VERSION_MINOR 2) set(BAR_VERSION_PATCH 3) set(BAR_VERSION ${BAR_VERSION_MAJOR}.${BAR_VERSION_MINOR}.${BAR_VERSION_PATCH} ) # set up install directories. INCLUDE_INSTALL_DIR and LIB_INSTALL_DIR must not be absolute paths set(LIB_INSTALL_DIR_SUFFIX "" CACHE STRING "The directories where to install libraries to") set(LIB_INSTALL_DIR lib${LIB_INSTALL_DIR_SUFFIX} ) set(CMAKECONFIG_INSTALL_DIR ${LIB_INSTALL_DIR}/cmake/Bar ) # Use a versioned install directory for the headers so multiple versions can be installed in parallel set(INCLUDE_INSTALL_DIR include ) # not changable, but we set a variable anyway for consistency set(BIN_INSTALL_DIR bin) set(DATA_INSTALL_DIR share/bar CACHE PATH "Where to install data files") set(FOO_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/foo/abc ) set(BAR_INSTALL_DIR /opt/xyz/foo/abc ) # actually add the directory where the library is built add_subdirectory(src) # This "exports" all targets which have been put into the export set "BarExport". # This means that cmake generates a file with the given filename, which can later on be loaded # by projects using this package. # This file contains add_library(bar IMPORTED) statements for each target in the export set, so # when loaded later on cmake will create "imported" library targets from these, which can be used # in many ways in the same way as a normal library target created via a normal add_library(). install(EXPORT BarExport DESTINATION ${CMAKECONFIG_INSTALL_DIR} FILE BarTargets.cmake ) # Create a BarConfig.cmake file. <name>Config.cmake files are searched by find_package() # automatically. We configure that file so that we can put any information we want in it, # e.g. version numbers, include directories, etc. include(ConfigureConfigFile.cmake) configure_config_file(BarConfig.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/BarConfig.cmake INSTALL_DESTINATION "${CMAKECONFIG_INSTALL_DIR}" PATH_VARS INCLUDE_INSTALL_DIR BIN_INSTALL_DIR FOO_INSTALL_DIR DATA_INSTALL_DIR BAR_INSTALL_DIR ) #configure_file(BarConfig.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/BarConfig.cmake @ONLY ) # Additionally, when cmake has found a BarConfig.cmake, it can check for a BarConfigVersion.cmake # in the same directory when figuring out the version of the package when a version # has been specified in the find_package() call, e.g. find_package(Bar 1.0) include(WriteBasicConfigVersionFile) write_basic_config_version_file(${CMAKE_CURRENT_BINARY_DIR}/BarConfigVersion.cmake VERSION ${BAR_VERSION} COMPATIBILITY AnyNewerVersion ) # Install these two files into the same directory as the generated exports-file. install(FILES ${CMAKE_CURRENT_BINARY_DIR}/BarConfig.cmake ${CMAKE_CURRENT_BINARY_DIR}/BarConfigVersion.cmake DESTINATION ${CMAKECONFIG_INSTALL_DIR} ) install(FILES README DESTINATION ${DATA_INSTALL_DIR})
include(CMakeParseArguments) function(CONFIGURE_CONFIG_FILE _inputFile _outputFile) set(oneValueArgs INSTALL_DESTINATION ) set(multiValueArgs PATH_VARS ) cmake_parse_arguments(CCF "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) if(CCF_UNPARSED_ARGUMENTS) message(FATAL_ERROR "Unknown keywords given to CONFIGURE_CONFIG_FILE(): \"${CCF_UNPARSED_ARGUMENTS}\"") endif() if(NOT CCF_INSTALL_DESTINATION) message(FATAL_ERROR "No INSTALL_DESTINATION given to CONFIGURE_CONFIG_FILE()") endif() if(NOT IS_ABSOLUTE "${CCF_INSTALL_DESTINATION}") set(absInstallDir "${CMAKE_INSTALL_PREFIX}/${CCF_INSTALL_DESTINATION}") endif() file(RELATIVE_PATH CONFIG_RELATIVE_PATH "${absInstallDir}" "${CMAKE_INSTALL_PREFIX}" ) message(STATUS "abs: -${absInstallDir}- REL: -${CONFIG_RELATIVE_PATH}-") foreach(var ${CCF_PATH_VARS}) message(STATUS "proc ${var} = -${${var}}-") if(NOT DEFINED ${var}) message(FATAL_ERROR "Variable ${var} does not exist") else() if(IS_ABSOLUTE "${${var}}") string(REPLACE "${CMAKE_INSTALL_PREFIX}" "\${CONFIG_PREFIX_DIR}" CONFIG_HELPER_${var} "${${var}}") else() set(CONFIG_HELPER_${var} "\${CONFIG_PREFIX_DIR}/${${var}}") endif() endif() message(STATUS "CONFIG_HELPER_${var} = -${CONFIG_HELPER_${var}}-") endforeach() set(CONFIG_HELPER_DIRS_INIT " ####### Expanded from @CONFIG_HELPER_DIRS_INIT@ by ConfigureConfigFile.cmake ####### get_filename_component(CONFIG_PREFIX_DIR \"\${CMAKE_CURRENT_LIST_DIR}/${CONFIG_RELATIVE_PATH}\" ABSOLUTE) macro(set_and_check _var _file) set(\${_var} \"\${_file}\") if(NOT EXISTS \"\${_file}\") message(FATAL_ERROR \"File or directory \${_file} referenced by variable \${_var} does not exist !\") endif() endmacro() #################################################################################### ") configure_file("${_inputFile}" "${_outputFile}" @ONLY) endfunction()
# set the version of myself set(BAR_VERSION_MAJOR 1) set(BAR_VERSION_MINOR 2) set(BAR_VERSION_PATCH 3) set(BAR_VERSION ${BAR_VERSION_MAJOR}.${BAR_VERSION_MINOR}.${BAR_VERSION_PATCH} ) # get_filename_component(CONFIG_PREFIX_DIR "${CMAKE_CURRENT_LIST_DIR}/../../../" ABSOLUTE) ####### Expanded from @CONFIG_HELPER_DIRS_INIT@ by ConfigureConfigFile.cmake ####### get_filename_component(CONFIG_PREFIX_DIR "${CMAKE_CURRENT_LIST_DIR}/../../../" ABSOLUTE) macro(set_and_check _var _file) set(${_var} "${_file}") if(NOT EXISTS "${_file}") message(FATAL_ERROR "File or directory ${_file} referenced by variable ${_var} does not exist !") endif() endmacro() #################################################################################### set_and_check(BAR_INCLUDE_DIR "${CONFIG_PREFIX_DIR}/include") set(BAR_BIN_DIR "${CONFIG_PREFIX_DIR}/bin") set(BAR_DATA_DIR "${CONFIG_PREFIX_DIR}/share/bar") set(BAR_BAR_DIR "/opt/xyz/foo/abc") set(BAR_FOO_DIR "${CONFIG_PREFIX_DIR}/foo/abc") # what is my include directory set(BAR_INCLUDES "${BAR_INCLUDE_DIR}") # import the exported targets include(${CMAKE_CURRENT_LIST_DIR}/BarTargets.cmake) # set the expected library variable set(BAR_LIBRARIES bar )
-- Powered by www.kitware.com Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ Follow this link to subscribe/unsubscribe: http://public.kitware.com/cgi-bin/mailman/listinfo/cmake-developers