On Thursday 16 February 2012, Alexander Neundorf wrote:
> On Thursday 16 February 2012, Brad King wrote:
...
> > >> Good.  Did you consider other prefixes?
> > > 
> > > It should match with the other variable names which are generated, and
> > > they use the CONFIG_HELPER_ prefix.
> > 
> > I was asking if *all* the prefixes of generated variables for the entire
> > config file could use a different prefix, not just the INIT one.  If I
> > read the .in file and do not know what CONFIG_HELPER means I have no
> > indication that it comes from a magic macro that does not have
> > CONFIG_HELPER in its name.  If the prefix were configurable than "grep"
> > in the source tree would reveal the origin of the name because it would
> > appear in the call to the configuration macro.  Alternatively if the
> > prefix were to match part of the macro name it would be clear also.
> 
> Ok, I can do that.
> 
> > >> Okay.  The set_and_check macro is perhaps overkill.  I've never
> > >> done an explicit existence check on such directories in a package
> > >> configuration file.
> > > 
> > > Yes, but I think it's better to do it.
> > 
> > Sure.  Users who don't like it can just not call it.  I'd also like an
> > option to the macro to exclude it from appearing so that my package
> > configuration files do not add any macros.
> 
> Ok.
> I'd go with default on.


Done (except the renaming).

Before reading on, please have a look at the attached files, especially 
BarConfig.cmake.in.




Actually I expected I would prefer this over the fixed names, but now that 
I've done it and look at what Config.cmake.in file I have to write, I think I 
liked the previous version with the fixed names (CONFIG_HELPER) better. I 
think it was easier to do, a simple scheme.

Before you had to think
"ok, put @CONFIG_HELPER_DIRS_INIT@ at the top, and then use 
@CONFIG_HELPER_+<VariableName>@ instead of @<VariableName>@ in the set() 
commands".

Now you have to think
"ok, put @<MyPrefix>+_HELPER_VARS_INIT@ at the top, and then use 
@<MyPrefix>+_HELPER_+<VariableName>@ instead of @<VariableName>@ in the set() 
commands"

With the fixed names it is probably also better google-able.

What do you think ?

(I wouldn't make setting the prefix optional: either it makes sense, then it 
should always be done, or it does not really make sense, then why should it be 
offered ?)

Alex
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}"
                      HELPER_VAR_PREFIX BAR
#                      NO_SET_AND_CHECK_MACRO
                      PATH_VARS INCLUDE_INSTALL_DIR
                                BIN_INSTALL_DIR
                                FOO_INSTALL_DIR
                                DATA_INSTALL_DIR
                                BAR_INSTALL_DIR
                     )

# 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})

# 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} )

@BAR_HELPER_VARS_INIT@

set_and_check(BAR_INCLUDE_DIR "@BAR_HELPER_INCLUDE_INSTALL_DIR@")
set_and_check(BAR_BIN_DIR     "@BAR_HELPER_BIN_INSTALL_DIR@")
set(BAR_DATA_DIR    "@BAR_HELPER_DATA_INSTALL_DIR@")
set(BAR_BAR_DIR     "@BAR_HELPER_BAR_INSTALL_DIR@")
set(BAR_FOO_DIR     "@BAR_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 )
include(CMakeParseArguments)

function(CONFIGURE_CONFIG_FILE _inputFile _outputFile)

  set(options NO_SET_AND_CHECK_MACRO )
  set(oneValueArgs INSTALL_DESTINATION HELPER_VAR_PREFIX)
  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 CCF_HELPER_VAR_PREFIX)
    message(FATAL_ERROR "No HELPER_VAR_PREFIX 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}" "\${${CCF_HELPER_VAR_PREFIX}_HELPER_PREFIX_DIR}"
                        ${CCF_HELPER_VAR_PREFIX}_HELPER_${var} "${${var}}")
      else()
        set(${CCF_HELPER_VAR_PREFIX}_HELPER_${var} "\${${CCF_HELPER_VAR_PREFIX}_HELPER_PREFIX_DIR}/${${var}}")
      endif()
    endif()
    message(STATUS "${CCF_HELPER_VAR_PREFIX}_HELPER_${var} = -${${CCF_HELPER_VAR_PREFIX}_HELPER_${var}}-")
  endforeach()

  set(${CCF_HELPER_VAR_PREFIX}_HELPER_VARS_INIT "
####### Expanded from @${CCF_HELPER_VAR_PREFIX}_HELPER_DIRS_INIT@ by ConfigureConfigFile.cmake #######
get_filename_component(${CCF_HELPER_VAR_PREFIX}_HELPER_PREFIX_DIR \"\${CMAKE_CURRENT_LIST_DIR}/${CONFIG_RELATIVE_PATH}\" ABSOLUTE)
")
  if(NOT CCF_NO_SET_AND_CHECK_MACRO)
    set(${CCF_HELPER_VAR_PREFIX}_HELPER_VARS_INIT "${${CCF_HELPER_VAR_PREFIX}_HELPER_VARS_INIT}
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()
")
  endif()
  set(${CCF_HELPER_VAR_PREFIX}_HELPER_VARS_INIT "${${CCF_HELPER_VAR_PREFIX}_HELPER_VARS_INIT}
####################################################################################
")

  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} )


####### Expanded from @BAR_HELPER_DIRS_INIT@ by ConfigureConfigFile.cmake #######
get_filename_component(BAR_HELPER_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 "${BAR_HELPER_PREFIX_DIR}/include")
set_and_check(BAR_BIN_DIR     "${BAR_HELPER_PREFIX_DIR}/bin")
set(BAR_DATA_DIR    "${BAR_HELPER_PREFIX_DIR}/share/bar")
set(BAR_BAR_DIR     "/opt/xyz/foo/abc")
set(BAR_FOO_DIR     "${BAR_HELPER_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

Reply via email to