Deploying Qt applications with DeployQt4

CMake 2.8.7 has been released and includes the DeployQt4 module I created.

DeployQt4 will take an executable and any specified Qt plugins and install and setup all the linked dependencies.

DeployQt4 does this by using e.g. otool, ldd or depends.exe to find the linked libraries, installing a qt.conf file (if needed) to ensure the correct Qt is used and install any specified Qt plugins to the default Qt application plugin path. On OSX it will also use install_name_tool to make sure your application is linked directly to the libraries inside its bundle.

For example an OSX application bundle before DeployQt4 might look like:
Before DeployQt4 directory tree

and afterwards like:
After DeployQt4 directory tree

The most commonly used DeployQt4 function is INSTALL_QT4_EXECUTABLE function. For example:
INSTALL_QT4_EXECUTABLE(${EXECUTABLE_PATH} qsqlite)

If you wanted to do this in a CMake script rather than at install time (i.e. for an already compiled executable) you could instead call:
FIXUP_QT4_EXECUTABLE(${EXECUTABLE_PATH} qsqlite)

Other DeployQt4 options include manually specifying libraries or non-Qt plugins to install their linked dependencies, additional directories to check for linked dependencies (the Qt directories are added by default), override the default plugin installation directory, override whether a qt.conf file is installed and the use of CMake INSTALL components.

You can see an example of using DeployQt4 (combined with CPack to generate installers) in the CMakeLists.txt file for my Fabula project.

For more information read the DeployQt4 section of the official CMake documentation, read the DeployQt4 source code or post a question in the comments.

If you want the same functionality for non-Qt projects I suggest you investigate the BundleUtilities module in CMake. Despite the confusing name this installs linked dependencies on Windows, Mac and Linux. DeployQt4 extends this functionality to improve the API and add some Qt-specific deployment help.

If you want the same functionality for Mac-only non-CMake projects I suggest you investigate the Mac deployment tool (macdeployqt) that is bundled with Qt. It lacks the DeployQt4 added features of automatic installation of any linked dependencies, CMake/CPack integration and support for Windows and Linux but will install the Qt libraries correctly.

David Cole says:

Thanks, Mike for the excellent blog post, and all the links, especially to a public example.

And of course, for contributing DeployQt4 for the CMake 2.8.7 release.

Cheers!

Thanks David, a pleasure. Thanks for accepting my work! This is under a CC license so feel free to reproduce elsewhere.

“make install” works fine and I get a nice fixed up bundle, but I can’t get cpack to work. it fails like this:

CPack: Create package using PackageMaker
CPack: Install projects
CPack: – Run preinstall target for: SuperCollider
CPack: – Install project: SuperCollider
CPack: – Install component: Unspecified
CMake Error at /Applications/CMake 2.8-7.app/Contents/share/cmake-2.8/Modules/BundleUtilities.cmake:668 (message):
error: fixup_bundle: not a valid bundle
Call Stack (most recent call first):
/Applications/CMake 2.8-7.app/Contents/share/cmake-2.8/Modules/DeployQt4.cmake:161 (fixup_bundle)
/Users/lijon/Coding/supercollider/build3.5/platform/mac/cmake_install.cmake:117 (FIXUP_QT4_EXECUTABLE)
/Users/lijon/Coding/supercollider/build3.5/platform/cmake_install.cmake:32 (INCLUDE)
/Users/lijon/Coding/supercollider/build3.5/cmake_install.cmake:75 (INCLUDE)

any advice?

“Not a valid bundle” basically means that not all the dependencies have been resolved correctly. I recommend finding out more by running cpack --verbose in the build directory which should print more output.

I think the dependencies are all right, since I can zip the installed .app directory and run it on another computer without problems.

this is the output of cpack –verbose

CPack Verbose: fixup_qt4_executable
CPack Verbose: executable=’/Users/lijon/Coding/supercollider/build3.5/_CPack_Packages/Darwin/PackageMaker/SuperCollider-3.5.dev-Darwin/Unspecified/usr/SuperCollider.app’
CPack Verbose: qtplugins=”
CPack Verbose: libs=”
CPack Verbose: dirs=’/Library/Frameworks’
CPack Verbose: plugins_dir=”
CPack Verbose: request_qt_conf=”
CPack Verbose: Writing /Users/lijon/Coding/supercollider/build3.5/_CPack_Packages/Darwin/PackageMaker/SuperCollider-3.5.dev-Darwin/Unspecified/usr/SuperCollider.app/Contents/Resources/qt.conf
CPack Verbose: fixup_bundle
CPack Verbose: app=’/Users/lijon/Coding/supercollider/build3.5/_CPack_Packages/Darwin/PackageMaker/SuperCollider-3.5.dev-Darwin/Unspecified/usr/SuperCollider.app’
CPack Verbose: libs=”
CPack Verbose: dirs=’/Library/Frameworks’
CPack Verbose: warning: *NOT* handled – .app directory case…
CMake Error at /Applications/CMake 2.8-7.app/Contents/share/cmake-2.8/Modules/BundleUtilities.cmake:668 (message):
error: fixup_bundle: not a valid bundle
Call Stack (most recent call first):
/Applications/CMake 2.8-7.app/Contents/share/cmake-2.8/Modules/DeployQt4.cmake:161 (fixup_bundle)
/Users/lijon/Coding/supercollider/build3.5/platform/mac/cmake_install.cmake:117 (FIXUP_QT4_EXECUTABLE)
/Users/lijon/Coding/supercollider/build3.5/platform/cmake_install.cmake:32 (INCLUDE)
/Users/lijon/Coding/supercollider/build3.5/cmake_install.cmake:75 (INCLUDE)

CPack Verbose: fixup_bundle: done
CPack Error: Error when generating package: SuperCollider

Hmm. Still not quite obvious what’s gone wrong there. I suggest poking around and adding debug statements into BundleUtilities.cmake as this is seemingly failing in that code rather than mine.

If you’ve got this committed to a Subversion repository or Github somewhere I can try and take a look for you.

Perhaps better to continue this directly. You can get my contact details from the contact page.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>