ExportTools.cmake
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|MEX") 00099 if (BASIS_TYPE MATCHES "MEX|MCC") 00100 set (TYPE SHARED) 00101 elseif (BASIS_TYPE MATCHES "SCRIPT") 00102 set (TYPE UNKNOWN) 00103 else () 00104 string (REGEX REPLACE "_LIBRARY" "" TYPE "${BASIS_TYPE}") 00105 endif () 00106 set (C "${C}add_library (${UID} ${TYPE} IMPORTED)\n") 00107 else () 00108 message (FATAL_ERROR "Cannot export target ${T} of type ${BASIS_TYPE}! Use NOEXPORT option.") 00109 endif () 00110 set (C "${C}set_target_properties (${UID} PROPERTIES BASIS_TYPE \"${BASIS_TYPE}\")\n") 00111 endforeach () 00112 set (${CODE} "${${CODE}}${C}" PARENT_SCOPE) 00113 endfunction () 00114 00115 # ---------------------------------------------------------------------------- 00116 ## @brief Add code to set properties of imported targets for build tree. 00117 function (basis_export_build_properties CODE) 00118 set (C) 00119 if (CMAKE_BUILD_TYPE) 00120 set (CONFIG "${CMAKE_BUILD_TYPE}") 00121 else () 00122 set (CONFIG "noconfig") 00123 endif () 00124 string (TOUPPER "${CONFIG}" CONFIG_U) 00125 foreach (T IN LISTS ARGN) 00126 basis_get_fully_qualified_target_uid (UID "${T}") 00127 get_target_property (BASIS_TYPE ${T} BASIS_TYPE) 00128 set (C "${C}\n# Import target \"${UID}\" for configuration \"${CONFIG}\"\n") 00129 set (C "${C}set_property (TARGET ${UID} APPEND PROPERTY IMPORTED_CONFIGURATIONS ${CONFIG_U})\n") 00130 set (C "${C}set_target_properties (${UID} PROPERTIES\n") 00131 if (BASIS_TYPE MATCHES "SCRIPT|LIBRARY|MEX") 00132 get_target_property (LANGUAGE ${T} LANGUAGE) 00133 if (LANGUAGE) 00134 set (C "${C} IMPORTED_LINK_INTERFACE_LANGUAGES_${CONFIG_U} \"${LANGUAGE}\"\n") 00135 endif () 00136 get_target_property (LINK_DEPENDS ${T} LINK_DEPENDS) 00137 set (LINK_UIDS) 00138 foreach (LINK_DEPEND IN LISTS LINK_DEPENDS) 00139 basis_get_fully_qualified_target_uid (LINK_UID ${LINK_DEPEND}) 00140 list (APPEND LINK_UIDS "${LINK_UID}") 00141 endforeach () 00142 set (C "${C} IMPORTED_LINK_INTERFACE_LIBRARIES_${CONFIG_U} \"${LINK_UIDS}\"\n") 00143 endif () 00144 basis_get_target_location (LOCATION ${T} ABSOLUTE) 00145 set (C "${C} IMPORTED_LOCATION_${CONFIG_U} \"${LOCATION}\"\n") 00146 set (C "${C} )\n") 00147 endforeach () 00148 set (${CODE} "${${CODE}}${C}" PARENT_SCOPE) 00149 endfunction () 00150 00151 # ---------------------------------------------------------------------------- 00152 ## @brief Add code to set properties of imported targets for installation. 00153 function (basis_export_install_properties CODE) 00154 set (C) 00155 if (CMAKE_BUILD_TYPE) 00156 set (CONFIG "${CMAKE_BUILD_TYPE}") 00157 else () 00158 set (CONFIG "noconfig") 00159 endif () 00160 string (TOUPPER "${CONFIG}" CONFIG_U) 00161 foreach (T IN LISTS ARGN) 00162 basis_get_fully_qualified_target_uid (UID "${T}") 00163 get_target_property (BASIS_TYPE ${T} BASIS_TYPE) 00164 set (C "${C}\n# Import target \"${UID}\" for configuration \"${CONFIG}\"\n") 00165 set (C "${C}set_property (TARGET ${UID} APPEND PROPERTY IMPORTED_CONFIGURATIONS ${CONFIG_U})\n") 00166 set (C "${C}set_target_properties (${UID} PROPERTIES\n") 00167 basis_get_target_location (LOCATION ${T} POST_INSTALL_RELATIVE) 00168 set (C "${C} IMPORTED_LOCATION_${CONFIG_U} \"\${_IMPORT_PREFIX}/${LOCATION}\"\n") 00169 if (BASIS_TYPE MATCHES "SCRIPT|LIBRARY|MEX") 00170 get_target_property (LANGUAGE ${T} LANGUAGE) 00171 if (LANGUAGE) 00172 set (C "${C} IMPORTED_LINK_INTERFACE_LANGUAGES_${CONFIG_U} \"${LANGUAGE}\"\n") 00173 endif () 00174 get_target_property (LINK_DEPENDS ${T} LINK_DEPENDS) 00175 set (LINK_UIDS) 00176 foreach (LINK_DEPEND IN LISTS LINK_DEPENDS) 00177 basis_get_fully_qualified_target_uid (LINK_UID ${LINK_DEPEND}) 00178 list (APPEND LINK_UIDS "${LINK_UID}") 00179 endforeach () 00180 set (C "${C} IMPORTED_LINK_INTERFACE_LIBRARIES_${CONFIG_U} \"${LINK_UIDS}\"\n") 00181 endif () 00182 set (C "${C} )\n") 00183 endforeach () 00184 set (${CODE} "${${CODE}}${C}" PARENT_SCOPE) 00185 endfunction () 00186 00187 # ---------------------------------------------------------------------------- 00188 ## @brief Add footer of exports file. 00189 function (basis_export_footer CODE) 00190 set (C "\n# Cleanup temporary variables.\n") 00191 set (C "${C}set (_IMPORT_PREFIX)\n") 00192 set (C "${C}\n# Commands beyond this point should not need to know the version.\n") 00193 set (C "${C}set (CMAKE_IMPORT_FILE_VERSION)\n") 00194 set (C "${C}cmake_policy (POP)\n") 00195 set (${CODE} "${${CODE}}${C}" PARENT_SCOPE) 00196 endfunction () 00197 00198 # ---------------------------------------------------------------------------- 00199 ## @brief Export all targets added by basis_add_* commands. 00200 function (basis_export_targets) 00201 # parse arguments 00202 CMAKE_PARSE_ARGUMENTS (ARGN "" "FILE;CUSTOM_FILE" "" ${ARGN}) 00203 00204 if (NOT ARGN_FILE) 00205 message (FATAL_ERROR "basis_export_targets(): FILE option is required!") 00206 endif () 00207 if (NOT ARGN_CUSTOM_FILE) 00208 message (FATAL_ERROR "basis_export_targets(): CUSTOM_FILE option is required!") 00209 endif () 00210 00211 if (IS_ABSOLUTE ARGN_FILE) 00212 message (FATAL_ERROR "basis_export_targets(): FILE option argument must be a relative path!") 00213 endif () 00214 if (IS_ABSOLUTE ARGN_CUSTOM_FILE) 00215 message (FATAL_ERROR "basis_export_targets(): CUSTOM_FILE option argument must be a relative path!") 00216 endif () 00217 00218 # -------------------------------------------------------------------------- 00219 # export non-custom targets 00220 basis_get_project_property (EXPORT_TARGETS) 00221 if (EXPORT_TARGETS) 00222 if (BASIS_USE_FULLY_QUALIFIED_UIDS) 00223 set (NAMESPACE_OPT) 00224 elseif (BASIS_PROJECT_NAMESPACE_CMAKE) 00225 set (NAMESPACE_OPT NAMESPACE "${BASIS_PROJECT_NAMESPACE_CMAKE}.") 00226 endif () 00227 export ( 00228 TARGETS ${EXPORT_TARGETS} 00229 FILE "${PROJECT_BINARY_DIR}/${ARGN_FILE}" 00230 ${NAMESPACE_OPT} 00231 ) 00232 basis_get_project_property (INSTALL_EXPORT_TARGETS) 00233 if (INSTALL_EXPORT_TARGETS) 00234 foreach (COMPONENT "${BASIS_RUNTIME_COMPONENT}" "${BASIS_LIBRARY_COMPONENT}") 00235 install ( 00236 EXPORT "${PROJECT_NAME}" 00237 DESTINATION "${INSTALL_CONFIG_DIR}" 00238 FILE "${ARGN_FILE}" 00239 COMPONENT "${COMPONENT}" 00240 ${NAMESPACE_OPT} 00241 ) 00242 endforeach () 00243 endif () 00244 endif () 00245 00246 # -------------------------------------------------------------------------- 00247 # export custom targets and/or test targets 00248 basis_get_project_property (CUSTOM_EXPORT_TARGETS) 00249 basis_get_project_property (TEST_EXPORT_TARGETS) 00250 00251 if (CUSTOM_EXPORT_TARGETS OR TEST_EXPORT_TARGETS) 00252 00253 # write exports for build tree 00254 basis_export_header (CONTENT) 00255 basis_export_import_targets (CONTENT ${CUSTOM_EXPORT_TARGETS} ${TEST_EXPORT_TARGETS}) 00256 basis_export_build_properties (CONTENT ${CUSTOM_EXPORT_TARGETS} ${TEST_EXPORT_TARGETS}) 00257 basis_export_footer (CONTENT) 00258 00259 file (WRITE "${PROJECT_BINARY_DIR}/${ARGN_CUSTOM_FILE}" "${CONTENT}") 00260 unset (CONTENT) 00261 00262 # write exports for installation - excluding test targets 00263 if (CUSTOM_EXPORT_TARGETS) 00264 set (INSTALL_EXPORT_FILE "${PROJECT_BINARY_DIR}/CMakeFiles/Export/${INSTALL_CONFIG_DIR}/${ARGN_CUSTOM_FILE}") 00265 00266 basis_export_header (CONTENT) 00267 basis_export_prefix (CONTENT) 00268 basis_export_import_targets (CONTENT ${CUSTOM_EXPORT_TARGETS}) 00269 basis_export_install_properties (CONTENT ${CUSTOM_EXPORT_TARGETS}) 00270 basis_export_footer (CONTENT) 00271 00272 file (WRITE "${INSTALL_EXPORT_FILE}" "${CONTENT}") 00273 unset (CONTENT) 00274 00275 install ( 00276 FILES "${INSTALL_EXPORT_FILE}" 00277 DESTINATION "${INSTALL_CONFIG_DIR}" 00278 ) 00279 endif () 00280 00281 endif () 00282 endfunction () 00283 00284 00285 ## @} 00286 # end of Doxygen group