Go to the documentation of this file.00001 ##############################################################################
00002 # @file ExportTools.cmake
00003 # @brief Functions and macros for the export of targets.
00004 #
00005 # Copyright (c) 2011, 2012 University of Pennsylvania. All rights reserved.<br />
00006 # See https://www.cbica.upenn.edu/sbia/software/license.html or COPYING file.
00007 #
00008 # Contact: SBIA Group <sbia-software at uphs.upenn.edu>
00009 #
00010 # @ingroup CMakeTools
00011 ##############################################################################
00012
00013 if (__BASIS_EXPORTIMPORTTOOLS_INCLUDED)
00014 return ()
00015 else ()
00016 set (__BASIS_EXPORTIMPORTTOOLS_INCLUDED TRUE)
00017 endif ()
00018
00019
00020 ## @addtogroup CMakeUtilities
00021 # @{
00022
00023
00024 # ----------------------------------------------------------------------------
00025 ## @brief Get soname of object file.
00026 #
00027 # This function extracts the soname from object files in the ELF format on
00028 # systems where the objdump command is available. On all other systems,
00029 # an empty string is returned.
00030 #
00031 # @param [out] SONAME The soname of the object file.
00032 # @param [in] OBJFILE Object file in ELF format.
00033 function (basis_get_soname SONAME OBJFILE)
00034 # get absolute path of object file
00035 basis_get_target_uid (TARGET_UID ${OBJFILE})
00036 if (TARGET TARGET_UID)
00037 basis_get_target_location (OBJFILE ${TARGET_UID} ABSOLUTE)
00038 else ()
00039 get_filename_component (OBJFILE "${OBJFILE}" ABSOLUTE)
00040 endif ()
00041 # usually CMake did this already
00042 find_program (CMAKE_OBJDUMP NAMES objdump DOC "The objdump command")
00043 # run objdump and extract soname
00044 execute_process (
00045 COMMAND ${CMAKE_OBJDUMP} -p "${OBJFILE}"
00046 COMMAND sed -n "-e's/^[[:space:]]*SONAME[[:space:]]*//p'"
00047 RESULT_VARIABLE STATUS
00048 OUTPUT_VARIABLE SONAME_OUT
00049 ERROR_QUIET
00050 )
00051 # return
00052 if (STATUS EQUAL 0)
00053 set (${SONAME} "${SONAME_OUT}" PARENT_SCOPE)
00054 else ()
00055 set (${SONAME} "" PARENT_SCOPE)
00056 endif ()
00057 endfunction ()
00058
00059 # ----------------------------------------------------------------------------
00060 ## @brief Generate header of exports file.
00061 function (basis_export_header CODE)
00062 set (C "# Generated by BASIS\n\n")
00063 set (C "${C}if (\"\${CMAKE_MAJOR_VERSION}.\${CMAKE_MINOR_VERSION}\" LESS 2.8)\n")
00064 set (C "${C} message (FATAL_ERROR \"CMake >= 2.8.4 required\")\n")
00065 set (C "${C}endif ()\n")
00066 set (C "${C}cmake_policy (PUSH)\n")
00067 set (C "${C}cmake_policy (VERSION 2.8.4)\n")
00068 set (C "${C}#----------------------------------------------------------------\n")
00069 set (C "${C}# Generated CMake target import file.\n")
00070 set (C "${C}#----------------------------------------------------------------\n")
00071 set (C "${C}\n# Commands may need to know the format version.\n")
00072 set (C "${C}set (CMAKE_IMPORT_FILE_VERSION 1)\n")
00073 set (${CODE} "${C}" PARENT_SCOPE)
00074 endfunction ()
00075
00076 # ----------------------------------------------------------------------------
00077 ## @brief Add code to compute prefix relative to @c INSTALL_CONFIG_DIR.
00078 function (basis_export_prefix CODE)
00079 set (C "\n# Compute the installation prefix relative to this file.\n")
00080 set (C "${C}get_filename_component (_IMPORT_PREFIX \"\${CMAKE_CURRENT_LIST_FILE}\" PATH)\n")
00081 string (REGEX REPLACE "[/\\]" ";" DIRS "${INSTALL_CONFIG_DIR}")
00082 foreach (D IN LISTS DIRS)
00083 set (C "${C}get_filename_component (_IMPORT_PREFIX \"\${_IMPORT_PREFIX}\" PATH)\n")
00084 endforeach ()
00085 set (${CODE} "${${CODE}}${C}" PARENT_SCOPE)
00086 endfunction ()
00087
00088 # ----------------------------------------------------------------------------
00089 ## @brief Add code to add import targets.
00090 function (basis_export_import_targets CODE)
00091 set (C)
00092 foreach (T IN LISTS ARGN)
00093 basis_get_fully_qualified_target_uid (UID "${T}")
00094 set (C "${C}\n# Create import target \"${UID}\"\n")
00095 get_target_property (BASIS_TYPE ${T} "BASIS_TYPE")
00096 if (BASIS_TYPE MATCHES "EXECUTABLE")
00097 set (C "${C}add_executable (${UID} IMPORTED)\n")
00098 elseif (BASIS_TYPE MATCHES "LIBRARY|MODULE_SCRIPT|MEX")
00099 string (REGEX REPLACE "_LIBRARY" "" TYPE "${BASIS_TYPE}")
00100 if (TYPE MATCHES "MEX|MCC")
00101 set (TYPE "SHARED")
00102 elseif (TYPE MATCHES "^MODULE_SCRIPT$")
00103 set (TYPE "UNKNOWN")
00104 endif ()
00105 set (C "${C}add_library (${UID} ${TYPE} IMPORTED)\n")
00106 else ()
00107 message (FATAL_ERROR "Cannot export target ${T} of type ${BASIS_TYPE}! Use NO_EXPORT option.")
00108 endif ()
00109 set (C "${C}set_target_properties (${UID} PROPERTIES BASIS_TYPE \"${BASIS_TYPE}\")\n")
00110 endforeach ()
00111 set (${CODE} "${${CODE}}${C}" PARENT_SCOPE)
00112 endfunction ()
00113
00114 # ----------------------------------------------------------------------------
00115 ## @brief Add code to set properties of imported targets for build tree.
00116 function (basis_export_build_properties CODE)
00117 set (C)
00118 if (CMAKE_BUILD_TYPE)
00119 set (CONFIG "${CMAKE_BUILD_TYPE}")
00120 else ()
00121 set (CONFIG "noconfig")
00122 endif ()
00123 string (TOUPPER "${CONFIG}" CONFIG_UPPER)
00124 foreach (T IN LISTS ARGN)
00125 basis_get_fully_qualified_target_uid (UID "${T}")
00126 set (C "${C}\n# Import target \"${UID}\" for configuration \"${CONFIG}\"\n")
00127 set (C "${C}set_property (TARGET ${UID} APPEND PROPERTY IMPORTED_CONFIGURATIONS ${CONFIG})\n")
00128 set (C "${C}set_target_properties (${UID} PROPERTIES\n")
00129 basis_get_target_location (LOCATION ${T} ABSOLUTE)
00130 set (C "${C} IMPORTED_LOCATION_${CONFIG_UPPER} \"${LOCATION}\"\n")
00131 if (BASIS_TYPE MATCHES "LIBRARY|MEX")
00132 set (C "${C} IMPORTED_LINK_INTERFACE_LANGUAGES_${CONFIG_UPPER} \"CXX\"\n")
00133 endif ()
00134 set (C "${C} )\n")
00135 endforeach ()
00136 set (${CODE} "${${CODE}}${C}" PARENT_SCOPE)
00137 endfunction ()
00138
00139 # ----------------------------------------------------------------------------
00140 ## @brief Add code to set properties of imported targets for installation.
00141 function (basis_export_install_properties CODE)
00142 set (C)
00143 if (CMAKE_BUILD_TYPE)
00144 set (CONFIG "${CMAKE_BUILD_TYPE}")
00145 else ()
00146 set (CONFIG "noconfig")
00147 endif ()
00148 string (TOUPPER "${CONFIG}" CONFIG_UPPER)
00149 foreach (T IN LISTS ARGN)
00150 basis_get_fully_qualified_target_uid (UID "${T}")
00151 set (C "${C}\n# Import target \"${UID}\" for configuration \"${CONFIG}\"\n")
00152 set (C "${C}set_property (TARGET ${UID} APPEND PROPERTY IMPORTED_CONFIGURATIONS ${CONFIG})\n")
00153 set (C "${C}set_target_properties (${UID} PROPERTIES\n")
00154 basis_get_target_location (LOCATION ${T} POST_INSTALL_RELATIVE)
00155 set (C "${C} IMPORTED_LOCATION_${CONFIG_UPPER} \"\${_IMPORT_PREFIX}/${LOCATION}\"\n")
00156 if (BASIS_TYPE MATCHES "LIBRARY|MEX")
00157 set (C "${C} IMPORTED_LINK_INTERFACE_LANGUAGES_${CONFIG_UPPER} \"CXX\"\n")
00158 endif ()
00159 set (C "${C} )\n")
00160 endforeach ()
00161 set (${CODE} "${${CODE}}${C}" PARENT_SCOPE)
00162 endfunction ()
00163
00164 # ----------------------------------------------------------------------------
00165 ## @brief Add footer of exports file.
00166 function (basis_export_footer CODE)
00167 set (C "\n# Cleanup temporary variables.\n")
00168 set (C "${C}set (_IMPORT_PREFIX)\n")
00169 set (C "${C}\n# Commands beyond this point should not need to know the version.\n")
00170 set (C "${C}set (CMAKE_IMPORT_FILE_VERSION)\n")
00171 set (C "${C}cmake_policy (POP)\n")
00172 set (${CODE} "${${CODE}}${C}" PARENT_SCOPE)
00173 endfunction ()
00174
00175 # ----------------------------------------------------------------------------
00176 ## @brief Export all targets added by basis_add_* commands.
00177 function (basis_export_targets)
00178 # parse arguments
00179 CMAKE_PARSE_ARGUMENTS (ARGN "" "FILE;CUSTOM_FILE" "" ${ARGN})
00180
00181 if (NOT ARGN_FILE)
00182 message (FATAL_ERROR "basis_export_targets(): FILE option is required!")
00183 endif ()
00184 if (NOT ARGN_CUSTOM_FILE)
00185 message (FATAL_ERROR "basis_export_targets(): CUSTOM_FILE option is required!")
00186 endif ()
00187
00188 if (IS_ABSOLUTE ARGN_FILE)
00189 message (FATAL_ERROR "basis_export_targets(): FILE option argument must be a relative path!")
00190 endif ()
00191 if (IS_ABSOLUTE ARGN_CUSTOM_FILE)
00192 message (FATAL_ERROR "basis_export_targets(): CUSTOM_FILE option argument must be a relative path!")
00193 endif ()
00194
00195 # --------------------------------------------------------------------------
00196 # export non-custom targets
00197 basis_get_project_property (EXPORT_TARGETS PROPERTY EXPORT_TARGETS)
00198
00199 if (EXPORT_TARGETS)
00200 if (BASIS_USE_FULLY_QUALIFIED_UIDS)
00201 set (NAMESPACE_OPT)
00202 else ()
00203 set (NAMESPACE_OPT NAMESPACE "${BASIS_PROJECT_NAMESPACE_CMAKE}.")
00204 endif ()
00205
00206 export (
00207 TARGETS ${EXPORT_TARGETS}
00208 FILE "${PROJECT_BINARY_DIR}/${ARGN_FILE}"
00209 ${NAMESPACE_OPT}
00210 )
00211 foreach (COMPONENT "${BASIS_RUNTIME_COMPONENT}" "${BASIS_LIBRARY_COMPONENT}")
00212 install (
00213 EXPORT "${PROJECT_NAME}"
00214 DESTINATION "${INSTALL_CONFIG_DIR}"
00215 FILE "${ARGN_FILE}"
00216 COMPONENT "${COMPONENT}"
00217 ${NAMESPACE_OPT}
00218 )
00219 endforeach ()
00220 endif ()
00221
00222 # --------------------------------------------------------------------------
00223 # export custom targets and/or test targets
00224 basis_get_project_property (CUSTOM_EXPORT_TARGETS)
00225 basis_get_project_property (TEST_EXPORT_TARGETS)
00226
00227 if (CUSTOM_EXPORT_TARGETS OR TEST_EXPORT_TARGETS)
00228
00229 # write exports for build tree
00230 basis_export_header (CONTENT)
00231 basis_export_import_targets (CONTENT ${CUSTOM_EXPORT_TARGETS} ${TEST_EXPORT_TARGETS})
00232 basis_export_build_properties (CONTENT ${CUSTOM_EXPORT_TARGETS} ${TEST_EXPORT_TARGETS})
00233 basis_export_footer (CONTENT)
00234
00235 file (WRITE "${PROJECT_BINARY_DIR}/${ARGN_CUSTOM_FILE}" "${CONTENT}")
00236 unset (CONTENT)
00237
00238 # write exports for installation - excluding test targets
00239 if (CUSTOM_EXPORT_TARGETS)
00240 basis_export_header (CONTENT)
00241 basis_export_prefix (CONTENT)
00242 basis_export_import_targets (CONTENT ${CUSTOM_EXPORT_TARGETS})
00243 basis_export_install_properties (CONTENT ${CUSTOM_EXPORT_TARGETS})
00244 basis_export_footer (CONTENT)
00245
00246 # DO NOT use '-' in the filename prefix for the custom exports.
00247 # Otherwise, it is automatically included by the exports file written
00248 # by CMake for the installation tree. This is, however, not the case
00249 # for the build tree. Therefore, we have to include the custom exports
00250 # file our selves in the use file.
00251 get_filename_component (TMP_FILE "${ARGN_CUSTOM_FILE}" NAME_WE)
00252
00253 set (TMP_FILE "${TMP_FILE}.install")
00254 file (WRITE "${PROJECT_BINARY_DIR}/${TMP_FILE}" "${CONTENT}")
00255 unset (CONTENT)
00256
00257 install (
00258 FILES "${PROJECT_BINARY_DIR}/${TMP_FILE}"
00259 DESTINATION "${INSTALL_CONFIG_DIR}"
00260 RENAME "${ARGN_CUSTOM_FILE}"
00261 )
00262 endif ()
00263
00264 endif ()
00265 endfunction ()
00266
00267
00268 ## @}
00269 # end of Doxygen group