BASIS  version 1.2.3 (revision 2104)
ConfigureIncludeFiles.cmake
Go to the documentation of this file.
00001 ##############################################################################
00002 # @file  ConfigureIncludeFiles.cmake
00003 # @brief CMake script used to configure and copy the public header files.
00004 #
00005 # Besides configuring the files, this script optionally copies the header
00006 # files to the build tree using the final relative path as used for the
00007 # installation. This could be done directly during the configure step of
00008 # CMake by code executed as part of the CMakeLists.txt files, but then
00009 # whenever a header file is modified, CMake reconfigures the build system.
00010 # Instead, this script is executed using execute_process() during the
00011 # configure step of CMake and a custom build target is added which rebuilds
00012 # whenever a header file was modified. Thus, only this script is re-executed,
00013 # but not the entire build system re-configured.
00014 #
00015 # The relative path of each configured input header file in the source tree
00016 # is appended to the output log file. This file can be used to determine
00017 # whether a new header was added to the source tree and thus this script has
00018 # to be re-executed.
00019 #
00020 # Copyright (c) 2011, 2012 University of Pennsylvania. All rights reserved.<br />
00021 # See https://www.cbica.upenn.edu/sbia/software/license.html or COPYING file.
00022 #
00023 # Contact: SBIA Group <sbia-software at uphs.upenn.edu>
00024 #
00025 # @ingroup CMakeUtilities
00026 ##############################################################################
00027 
00028 # ----------------------------------------------------------------------------
00029 # requires bug fixed get_filename_component() of BASIS tools
00030 include ("${CMAKE_CURRENT_LIST_DIR}/CommonTools.cmake")
00031 
00032 # ----------------------------------------------------------------------------
00033 # check arguments
00034 if (NOT PROJECT_INCLUDE_DIRS)
00035   message (FATAL_ERROR "Missing argument PROJECT_INCLUDE_DIR!")
00036 endif ()
00037 
00038 if (NOT BINARY_INCLUDE_DIR)
00039   message (FATAL_ERROR "Missing argument BINARY_INCLUDE_DIR!")
00040 endif ()
00041 
00042 if (NOT EXTENSIONS)
00043   message (FATAL_ERROR "Missing argument EXTENSIONS!")
00044 endif ()
00045 
00046 if (NOT INCLUDE_PREFIX)
00047   set (INCLUDE_PREFIX "")
00048 endif ()
00049 
00050 if (NOT VARIABLE_NAME)
00051   set (VARIABLE_NAME "PUBLIC_HEADERS")
00052 endif ()
00053 
00054 # ----------------------------------------------------------------------------
00055 # include file which defines CMake variables for use in .h.in files
00056 if (INCLUDE_FILE)
00057   include ("${INCLUDE_FILE}")
00058 endif ()
00059 
00060 # ----------------------------------------------------------------------------
00061 # configure header files
00062 set (_CONFIGURED_HEADERS)
00063 get_filename_component (INCLUDE_PREFIX_DIR "${INCLUDE_PREFIX}" PATH)
00064 basis_sanitize_for_regex (INCLUDE_PREFIX_REGEX "${INCLUDE_PREFIX}")
00065 basis_sanitize_for_regex (INCLUDE_PREFIX_DIR_REGEX "${INCLUDE_PREFIX_DIR}")
00066 foreach (INCLUDE_DIR IN LISTS PROJECT_INCLUDE_DIRS)
00067   # glob header files
00068   set (GLOB_EXPR)
00069   foreach (E IN LISTS EXTENSIONS)
00070     list (APPEND GLOB_EXPR "${INCLUDE_DIR}/*${E}.in")
00071   endforeach ()
00072   foreach (E IN LISTS EXTENSIONS)
00073     list (APPEND GLOB_EXPR "${INCLUDE_DIR}/*${E}")
00074   endforeach ()
00075   file (GLOB_RECURSE _HEADERS RELATIVE "${INCLUDE_DIR}" ${GLOB_EXPR})
00076   # configure file if not run in PREVIEW mode which is used to determine
00077   # whether or not files were added/removed from the source directory
00078   if (NOT PREVIEW)
00079     foreach (HEADER IN LISTS _HEADERS)
00080       get_filename_component (TEMPLATE "${INCLUDE_DIR}/${HEADER}" ABSOLUTE)
00081       if (AUTO_PREFIX_INCLUDES)
00082         if (HEADER MATCHES "^${INCLUDE_PREFIX_REGEX}")
00083           if (HEADER MATCHES "\\.in$")
00084             string (REGEX REPLACE "\\.in$" "" HEADER "${HEADER}")
00085             set (MODE "@ONLY")
00086           else ()
00087             set (MODE "COPYONLY")
00088           endif ()
00089           configure_file (
00090             "${TEMPLATE}"
00091             "${BINARY_INCLUDE_DIR}/${HEADER}"
00092             ${MODE}
00093           )
00094         else ()
00095           get_filename_component (DIR "${HEADER}" PATH)
00096           if (HEADER MATCHES "\\.in$")
00097             get_filename_component (NAME "${HEADER}" NAME_WE)
00098             set (MODE "@ONLY")
00099           else ()
00100             get_filename_component (NAME "${HEADER}" NAME)
00101             set (MODE "COPYONLY")
00102           endif ()
00103           if (INCLUDE_PREFIX MATCHES "/$")
00104             configure_file (
00105               "${TEMPLATE}"
00106               "${BINARY_INCLUDE_DIR}/${INCLUDE_PREFIX}${DIR}/${NAME}"
00107               ${MODE}
00108             )
00109           else ()
00110             configure_file (
00111               "${TEMPLATE}"
00112               "${BINARY_INCLUDE_DIR}/${DIR}/${INCLUDE_PREFIX}${NAME}"
00113               ${MODE}
00114             )
00115           endif ()
00116         endif ()
00117         list (APPEND _CONFIGURED_HEADERS "${TEMPLATE}")
00118       else ()
00119         if (NOT HEADER MATCHES "^${INCLUDE_PREFIX_REGEX}")
00120           set (WARN TRUE)
00121           if (INCLUDES_CHECK_EXCLUDE)
00122             foreach (REGEX IN LISTS INCLUDES_CHECK_EXCLUDE)
00123               if (HEADER MATCHES "${REGEX}")
00124                 set (WARN FALSE)
00125                 break ()
00126               endif ()
00127             endforeach ()
00128           endif ()
00129           if (WARN)
00130             message (WARNING "Public header file ${HEADER} should have"
00131                              " the path prefix\n"
00132                              "\t${INCLUDE_DIR}/${INCLUDE_PREFIX}\n"
00133                              "to avoid conflicts with other projects!\n"
00134                              "If you were using a pre-release version of BASIS"
00135                              " or want BASIS to auto-prefix the path of public"
00136                              " header files, which requires copying them to the"
00137                              " build tree with the modified file path,"
00138                              " set BASIS_AUTO_PREFIX_INCLUDES to"
00139                              " TRUE in the project's Settings.cmake file.")
00140           endif ()
00141         endif ()
00142         if (HEADER MATCHES "\\.in$")
00143           string (REGEX REPLACE "\\.in$" "" HEADER "${HEADER}")
00144           configure_file (
00145             "${TEMPLATE}"
00146             "${BINARY_INCLUDE_DIR}/${HEADER}"
00147             @ONLY
00148           )
00149           list (APPEND _CONFIGURED_HEADERS "${TEMPLATE}")
00150         endif ()
00151       endif ()
00152     endforeach ()
00153   else ()
00154     # accumulate header files for output in ascending order later on
00155     foreach (HEADER IN LISTS _HEADERS)
00156       if (AUTO_PREFIX_INCLUDES OR HEADER MATCHES "\\.in$")
00157         get_filename_component (TEMPLATE "${INCLUDE_DIR}/${HEADER}" ABSOLUTE)
00158         list (APPEND _CONFIGURED_HEADERS "${TEMPLATE}")
00159       endif ()
00160     endforeach ()
00161   endif ()
00162 endforeach ()
00163 
00164 # ----------------------------------------------------------------------------
00165 # write CMake script with list of public header files
00166 if (CMAKE_FILE)
00167   if (_CONFIGURED_HEADERS)
00168     list (SORT _CONFIGURED_HEADERS) # deterministic order
00169   endif ()
00170   file (WRITE "${CMAKE_FILE}" "# Automatically generated by BASIS. Do not edit this file!\nset (${VARIABLE_NAME}\n")
00171   foreach (HEADER IN LISTS _CONFIGURED_HEADERS)
00172     file (APPEND "${CMAKE_FILE}" "  \"${HEADER}\"\n")
00173   endforeach ()
00174   file (APPEND "${CMAKE_FILE}" ")\n")
00175 endif ()