1# Distributed under the OSI-approved BSD 3-Clause License. See accompanying 2# file Copyright.txt or https://cmake.org/licensing for details. 3 4#[=======================================================================[.rst: 5DeployQt4 6--------- 7 8Functions to help assemble a standalone Qt4 executable. 9 10A collection of CMake utility functions useful for deploying Qt4 11executables. 12 13The following functions are provided by this module: 14 15:: 16 17 write_qt4_conf 18 resolve_qt4_paths 19 fixup_qt4_executable 20 install_qt4_plugin_path 21 install_qt4_plugin 22 install_qt4_executable 23 24Requires CMake 2.6 or greater because it uses function and 25PARENT_SCOPE. Also depends on BundleUtilities.cmake. 26 27:: 28 29 write_qt4_conf(<qt_conf_dir> <qt_conf_contents>) 30 31Writes a qt.conf file with the <qt_conf_contents> into <qt_conf_dir>. 32 33:: 34 35 resolve_qt4_paths(<paths_var> [<executable_path>]) 36 37Loop through <paths_var> list and if any don't exist resolve them 38relative to the <executable_path> (if supplied) or the 39CMAKE_INSTALL_PREFIX. 40 41:: 42 43 fixup_qt4_executable(<executable> 44 [<qtplugins> <libs> <dirs> <plugins_dir> <request_qt_conf>]) 45 46Copies Qt plugins, writes a Qt configuration file (if needed) and 47fixes up a Qt4 executable using BundleUtilities so it is standalone 48and can be drag-and-drop copied to another machine as long as all of 49the system libraries are compatible. 50 51<executable> should point to the executable to be fixed-up. 52 53<qtplugins> should contain a list of the names or paths of any Qt 54plugins to be installed. 55 56<libs> will be passed to BundleUtilities and should be a list of any 57already installed plugins, libraries or executables to also be 58fixed-up. 59 60<dirs> will be passed to BundleUtilities and should contain and 61directories to be searched to find library dependencies. 62 63<plugins_dir> allows an custom plugins directory to be used. 64 65<request_qt_conf> will force a qt.conf file to be written even if not 66needed. 67 68:: 69 70 install_qt4_plugin_path(plugin executable copy installed_plugin_path_var 71 <plugins_dir> <component> <configurations>) 72 73Install (or copy) a resolved <plugin> to the default plugins directory 74(or <plugins_dir>) relative to <executable> and store the result in 75<installed_plugin_path_var>. 76 77If <copy> is set to TRUE then the plugins will be copied rather than 78installed. This is to allow this module to be used at CMake time 79rather than install time. 80 81If <component> is set then anything installed will use this COMPONENT. 82 83:: 84 85 install_qt4_plugin(plugin executable copy installed_plugin_path_var 86 <plugins_dir> <component>) 87 88Install (or copy) an unresolved <plugin> to the default plugins 89directory (or <plugins_dir>) relative to <executable> and store the 90result in <installed_plugin_path_var>. See documentation of 91INSTALL_QT4_PLUGIN_PATH. 92 93:: 94 95 install_qt4_executable(<executable> 96 [<qtplugins> <libs> <dirs> <plugins_dir> <request_qt_conf> <component>]) 97 98Installs Qt plugins, writes a Qt configuration file (if needed) and 99fixes up a Qt4 executable using BundleUtilities so it is standalone 100and can be drag-and-drop copied to another machine as long as all of 101the system libraries are compatible. The executable will be fixed-up 102at install time. <component> is the COMPONENT used for bundle fixup 103and plugin installation. See documentation of FIXUP_QT4_BUNDLE. 104#]=======================================================================] 105 106# The functions defined in this file depend on the fixup_bundle function 107# (and others) found in BundleUtilities.cmake 108 109set(DeployQt4_apple_plugins_dir "PlugIns") 110 111function(write_qt4_conf qt_conf_dir qt_conf_contents) 112 set(qt_conf_path "${qt_conf_dir}/qt.conf") 113 message(STATUS "Writing ${qt_conf_path}") 114 file(WRITE "${qt_conf_path}" "${qt_conf_contents}") 115endfunction() 116 117function(resolve_qt4_paths paths_var) 118 unset(executable_path) 119 if(ARGC GREATER 1) 120 set(executable_path ${ARGV1}) 121 endif() 122 123 set(paths_resolved) 124 foreach(path ${${paths_var}}) 125 if(EXISTS "${path}") 126 list(APPEND paths_resolved "${path}") 127 else() 128 if(${executable_path}) 129 list(APPEND paths_resolved "${executable_path}/${path}") 130 else() 131 list(APPEND paths_resolved "\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${path}") 132 endif() 133 endif() 134 endforeach() 135 set(${paths_var} ${paths_resolved} PARENT_SCOPE) 136endfunction() 137 138cmake_policy(GET CMP0080 _cmp0080_value) 139if(NOT DEFINED CMAKE_GENERATOR OR NOT _cmp0080_value STREQUAL "NEW") 140 set(_CMP0080_SUPPRESS_WARNING TRUE) 141 include("${CMAKE_CURRENT_LIST_DIR}/BundleUtilities.cmake") 142 unset(_CMP0080_SUPPRESS_WARNING) 143 144 function(fixup_qt4_executable executable) 145 cmake_policy(GET CMP0080 _cmp0080_value) 146 if(_cmp0080_value STREQUAL "" AND DEFINED CMAKE_GENERATOR) 147 _warn_cmp0080() 148 endif() 149 150 unset(qtplugins) 151 if(ARGC GREATER 1) 152 set(qtplugins ${ARGV1}) 153 endif() 154 unset(libs) 155 if(ARGC GREATER 2) 156 set(libs ${ARGV2}) 157 endif() 158 unset(dirs) 159 if(ARGC GREATER 3) 160 set(dirs ${ARGV3}) 161 endif() 162 unset(plugins_dir) 163 if(ARGC GREATER 4) 164 set(plugins_dir ${ARGV4}) 165 endif() 166 unset(request_qt_conf) 167 if(ARGC GREATER 5) 168 set(request_qt_conf ${ARGV5}) 169 endif() 170 171 message(STATUS "fixup_qt4_executable") 172 message(STATUS " executable='${executable}'") 173 message(STATUS " qtplugins='${qtplugins}'") 174 message(STATUS " libs='${libs}'") 175 message(STATUS " dirs='${dirs}'") 176 message(STATUS " plugins_dir='${plugins_dir}'") 177 message(STATUS " request_qt_conf='${request_qt_conf}'") 178 179 if(QT_LIBRARY_DIR) 180 list(APPEND dirs "${QT_LIBRARY_DIR}") 181 endif() 182 if(QT_BINARY_DIR) 183 list(APPEND dirs "${QT_BINARY_DIR}") 184 endif() 185 186 if(APPLE) 187 set(qt_conf_dir "${executable}/Contents/Resources") 188 set(executable_path "${executable}") 189 set(write_qt_conf TRUE) 190 if(NOT DEFINED plugins_dir) 191 set(plugins_dir "${DeployQt4_apple_plugins_dir}") 192 endif() 193 else() 194 get_filename_component(executable_path "${executable}" PATH) 195 if(NOT executable_path) 196 set(executable_path ".") 197 endif() 198 set(qt_conf_dir "${executable_path}") 199 set(write_qt_conf ${request_qt_conf}) 200 endif() 201 202 foreach(plugin ${qtplugins}) 203 set(installed_plugin_path "") 204 install_qt4_plugin("${plugin}" "${executable}" 1 installed_plugin_path) 205 list(APPEND libs ${installed_plugin_path}) 206 endforeach() 207 208 foreach(lib ${libs}) 209 if(NOT EXISTS "${lib}") 210 message(FATAL_ERROR "Library does not exist: ${lib}") 211 endif() 212 endforeach() 213 214 resolve_qt4_paths(libs "${executable_path}") 215 216 if(write_qt_conf) 217 set(qt_conf_contents "[Paths]\nPlugins = ${plugins_dir}") 218 write_qt4_conf("${qt_conf_dir}" "${qt_conf_contents}") 219 endif() 220 221 fixup_bundle("${executable}" "${libs}" "${dirs}") 222 endfunction() 223endif() 224 225function(install_qt4_plugin_path plugin executable copy installed_plugin_path_var) 226 unset(plugins_dir) 227 if(ARGC GREATER 4) 228 set(plugins_dir ${ARGV4}) 229 endif() 230 unset(component) 231 if(ARGC GREATER 5) 232 set(component ${ARGV5}) 233 endif() 234 unset(configurations) 235 if(ARGC GREATER 6) 236 set(configurations ${ARGV6}) 237 endif() 238 239 if(EXISTS "${plugin}") 240 if(APPLE) 241 if(NOT plugins_dir) 242 set(plugins_dir "${DeployQt4_apple_plugins_dir}") 243 endif() 244 set(plugins_path "${executable}/Contents/${plugins_dir}") 245 else() 246 get_filename_component(plugins_path "${executable}" PATH) 247 if(NOT plugins_path) 248 set(plugins_path ".") 249 endif() 250 if(plugins_dir) 251 string(APPEND plugins_path "/${plugins_dir}") 252 endif() 253 endif() 254 255 set(plugin_group "") 256 257 get_filename_component(plugin_path "${plugin}" PATH) 258 get_filename_component(plugin_parent_path "${plugin_path}" PATH) 259 get_filename_component(plugin_parent_dir_name "${plugin_parent_path}" NAME) 260 get_filename_component(plugin_name "${plugin}" NAME) 261 string(TOLOWER "${plugin_parent_dir_name}" plugin_parent_dir_name) 262 263 if("${plugin_parent_dir_name}" STREQUAL "plugins") 264 get_filename_component(plugin_group "${plugin_path}" NAME) 265 set(${plugin_group_var} "${plugin_group}") 266 endif() 267 string(APPEND plugins_path "/${plugin_group}") 268 269 if(${copy}) 270 file(MAKE_DIRECTORY "${plugins_path}") 271 file(COPY "${plugin}" DESTINATION "${plugins_path}") 272 else() 273 get_property(_isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) 274 if(configurations AND (_isMultiConfig OR CMAKE_BUILD_TYPE)) 275 set(configurations CONFIGURATIONS ${configurations}) 276 else() 277 unset(configurations) 278 endif() 279 install(FILES "${plugin}" DESTINATION "${plugins_path}" ${configurations} ${component}) 280 endif() 281 set(${installed_plugin_path_var} "${plugins_path}/${plugin_name}" PARENT_SCOPE) 282 endif() 283endfunction() 284 285function(install_qt4_plugin plugin executable copy installed_plugin_path_var) 286 unset(plugins_dir) 287 if(ARGC GREATER 4) 288 set(plugins_dir ${ARGV4}) 289 endif() 290 unset(component) 291 if(ARGC GREATER 5) 292 set(component ${ARGV5}) 293 endif() 294 295 if(EXISTS "${plugin}") 296 install_qt4_plugin_path("${plugin}" "${executable}" "${copy}" "${installed_plugin_path_var}" "${plugins_dir}" "${component}") 297 else() 298 string(TOUPPER "QT_${plugin}_PLUGIN" plugin_var) 299 set(plugin_release_var "${plugin_var}_RELEASE") 300 set(plugin_debug_var "${plugin_var}_DEBUG") 301 set(plugin_release "${${plugin_release_var}}") 302 set(plugin_debug "${${plugin_debug_var}}") 303 if(DEFINED "${plugin_release_var}" AND DEFINED "${plugin_debug_var}" AND NOT EXISTS "${plugin_release}" AND NOT EXISTS "${plugin_debug}") 304 message(WARNING "Qt plugin \"${plugin}\" not recognized or found.") 305 endif() 306 if(NOT EXISTS "${${plugin_debug_var}}") 307 set(plugin_debug "${plugin_release}") 308 endif() 309 310 get_property(_isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) 311 if(_isMultiConfig OR CMAKE_BUILD_TYPE) 312 set(_RELEASE_CONFIGS ${CMAKE_CONFIGURATION_TYPES} "${CMAKE_BUILD_TYPE}") 313 if (_RELEASE_CONFIGS) 314 list(FILTER _RELEASE_CONFIGS EXCLUDE REGEX "[Dd][Ee][Bb][Uu][Gg]") 315 endif() 316 string(REPLACE ";" "|" _RELEASE_CONFIGS "${_RELEASE_CONFIGS}") 317 install_qt4_plugin_path("${plugin_release}" "${executable}" "${copy}" "${installed_plugin_path_var}_release" "${plugins_dir}" "${component}" "${_RELEASE_CONFIGS}") 318 install_qt4_plugin_path("${plugin_debug}" "${executable}" "${copy}" "${installed_plugin_path_var}_debug" "${plugins_dir}" "${component}" "Debug") 319 unset(_RELEASE_CONFIGS) 320 321 if(CMAKE_BUILD_TYPE MATCHES "^Debug$") 322 set(${installed_plugin_path_var} ${${installed_plugin_path_var}_debug}) 323 else() 324 set(${installed_plugin_path_var} ${${installed_plugin_path_var}_release}) 325 endif() 326 else() 327 install_qt4_plugin_path("${plugin_release}" "${executable}" "${copy}" "${installed_plugin_path_var}" "${plugins_dir}" "${component}") 328 endif() 329 endif() 330 set(${installed_plugin_path_var} ${${installed_plugin_path_var}} PARENT_SCOPE) 331endfunction() 332 333function(install_qt4_executable executable) 334 unset(qtplugins) 335 if(ARGC GREATER 1) 336 set(qtplugins ${ARGV1}) 337 endif() 338 unset(libs) 339 if(ARGC GREATER 2) 340 set(libs ${ARGV2}) 341 endif() 342 unset(dirs) 343 if(ARGC GREATER 3) 344 set(dirs ${ARGV3}) 345 endif() 346 unset(plugins_dir) 347 if(ARGC GREATER 4) 348 set(plugins_dir ${ARGV4}) 349 endif() 350 unset(request_qt_conf) 351 if(ARGC GREATER 5) 352 set(request_qt_conf ${ARGV5}) 353 endif() 354 unset(component) 355 if(ARGC GREATER 6) 356 set(component ${ARGV6}) 357 endif() 358 359 if(QT_LIBRARY_DIR) 360 list(APPEND dirs "${QT_LIBRARY_DIR}") 361 endif() 362 if(QT_BINARY_DIR) 363 list(APPEND dirs "${QT_BINARY_DIR}") 364 endif() 365 if(component) 366 set(component COMPONENT ${component}) 367 else() 368 unset(component) 369 endif() 370 371 get_filename_component(executable_absolute "${executable}" ABSOLUTE) 372 if(EXISTS "${QT_QTCORE_LIBRARY_RELEASE}") 373 gp_file_type("${executable_absolute}" "${QT_QTCORE_LIBRARY_RELEASE}" qtcore_type) 374 elseif(EXISTS "${QT_QTCORE_LIBRARY_DEBUG}") 375 gp_file_type("${executable_absolute}" "${QT_QTCORE_LIBRARY_DEBUG}" qtcore_type) 376 endif() 377 if(qtcore_type STREQUAL "system") 378 set(qt_plugins_dir "") 379 endif() 380 381 if(QT_IS_STATIC) 382 message(WARNING "Qt built statically: not installing plugins.") 383 else() 384 foreach(plugin ${qtplugins}) 385 set(installed_plugin_paths "") 386 install_qt4_plugin("${plugin}" "${executable}" 0 installed_plugin_paths "${plugins_dir}" "${component}") 387 list(APPEND libs ${installed_plugin_paths}) 388 endforeach() 389 endif() 390 391 resolve_qt4_paths(libs "") 392 393 install(CODE 394"include(\"${CMAKE_CURRENT_FUNCTION_LIST_DIR}/DeployQt4.cmake\") 395set(BU_CHMOD_BUNDLE_ITEMS TRUE) 396FIXUP_QT4_EXECUTABLE(\"\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${executable}\" \"\" \"${libs}\" \"${dirs}\" \"${plugins_dir}\" \"${request_qt_conf}\")" 397 ${component} 398 ) 399endfunction() 400