Difference between revisions of "BundleUtilitiesExample"

From KitwarePublic
Jump to navigationJump to search
Line 1: Line 1:
== Overview ==
== Overview ==
CMake 2.6.2 includes a new module called 'BundleUtilities'. This module is intended to make the task of creating a fully standalone OS X application bundle much easier than before. It still requires some setup on your part though. In this example we will walk through the necessary files and CMake code that are needed to use the 'BundleUtilities.cmake' effectively. Get the project [http://www.bluequartz.net/software/files/QtTest.zip here].
CMake 2.6.2 includes a new module called 'BundleUtilities'. This module is intended to make the task of creating a fully standalone OS X application bundle much easier than before. It still requires some setup on your part though. In CMake 2.8, the module was ported to Linux and Windows.  In this example we will walk through the necessary files and CMake code that are needed to use the 'BundleUtilities.cmake' effectively. Get the project [[Media:QtTest-Package-Example.zip]]‎.


== Basic Flow ==
== Basic Flow ==
The CMake code that we will generate will do a couple of things.
The CMake code in the example does a few things.
It will configure a couple of template files to be run during the 'install' phase of the build.
- It has install commands for targets built by the CMake code.
During the install phase of the build a cmake script is run, which in turn runs a base shell script to ensure all
- It has an install command for Qt plugins
the necessary folders are created and any pre-existing application bundle is removed. At the completion of the
- It has an install command for creating a qt.conf file
shell script, cmake continues by calling the 'BundleUtilities' module which will complete the actual copying of
- It has an install command for executing CMake code at install time. This code uses BundleUtilities which gathers and includes prerequisites into the application bundle. On Mac OS X, BundleUtilities also modifies the install names.
libraries into the Application bundle. After copying the libraries, the cmake code will then adjust the 'install_name'
property of the libraries and executable to finally make the application bundle stand-alone.
 
== Additional Files ==
There are 2 additional files that are added to the project (They are already in the sample project linked above).
# QtTest/Resources/OSX_Tools/CompleteBundle.cmake.in
# QtTest/Resources/OSX_Tools/CreateBundle.sh.in


== Additions to your CMakeLists.txt File ==
== Additions to your CMakeLists.txt File ==
The first additional bit of code that we need will be placed in the CMakeLists.txt file just after the '''target_link_libraries(...)''' command.
A simpler version of this example would have something like:
set(APPS ...)  # paths to executables
<font color="green"># If we are build a "Debug" version then put that on the built Application</font>
  set(DIRS ...)  # directories to search for prerequisites
  SET (EXE_DEBUG_EXTENSION "_debug")
INSTALL(CODE "
<font color="green">#-- Set the Debug and Release names for the libraries</font>
     include(BundleUtilities)
  SET_TARGET_PROPERTIES(QtTest
     fixup_bundle(\"${APPS}\"   \"\"   \"${DIRS}\")
    PROPERTIES
     " COMPONENT Runtime)
    DEBUG_OUTPUT_NAME QtTest${EXE_DEBUG_EXTENSION}
    RELEASE_OUTPUT_NAME QtTest
)
  <font color="green"> # --- If we are on OS X copy all the embedded libraries to the app bundle</font>
  IF (APPLE)
   <font color="green"># -------- Function to build OS X Stand Alone Bundles -----------------</font>
  function(MakeOSXBundleApp target binary_dir)
    <font color="green">#-- Set some useful variables</font>
     SET (OSX_MAKE_STANDALONE_BUNDLE_CMAKE_SCRIPT <font color="red">"${binary_dir}/${target}_OSX_MakeStandAloneBundle.cmake"</font>)
     SET (OSX_MAKE_STANDALONE_BUNDLE_BASH_SCRIPT <font color="red">"${binary_dir}/${target}_OSX_MakeStandAloneBundle.sh"</font>)
    <font color="green">#-- Configure the cmake file and the shell script</font>
    CONFIGURE_FILE(<font color="red">"${PROJECT_RESOURCES_DIR}/OSX_Tools/CompleteBundle.cmake.in"</font>
      <font color="red">"${OSX_MAKE_STANDALONE_BUNDLE_CMAKE_SCRIPT}"</font> @ONLY IMMEDIATE)
     CONFIGURE_FILE(<font color="red">"${PROJECT_RESOURCES_DIR}/OSX_Tools/CreateBundle.sh.in"</font>
      <font color="red">"${OSX_MAKE_STANDALONE_BUNDLE_BASH_SCRIPT}"</font> @ONLY IMMEDIATE)
    <font color="green">#-- Create the installation code</font>
    install(SCRIPT <font color="red">"${OSX_MAKE_STANDALONE_BUNDLE_CMAKE_SCRIPT}"</font>)             
  endfunction(MakeOSXBundleApp)
  IF(CMAKE_BUILD_TYPE MATCHES <font color="red">"Debug"</font>)
      MakeOSXBundleApp( <font color="red">"QtTest${EXE_DEBUG_EXTENSION}"</font> ${PROJECT_BINARY_DIR})
  ELSE (CMAKE_BUILD_TYPE MATCHES <font color="red">"Debug"</font>)
      MakeOSXBundleApp(QtTest ${PROJECT_BINARY_DIR})
  ENDIF(CMAKE_BUILD_TYPE MATCHES <font color="red">"Debug"</font>)
ENDIF (APPLE)


#This cmake code adds a '_debug' extension to the normal application name if we are building in debug mode.
But since we include Qt plugins, we use the second argument to fixup_bundle().
#It will then configure the cmake.in file and the sh.in file and place those new files in the project binary directory.
#The code finally executes an 'install' command so that during a 'make install' phase the bundle creation code is actually executed


After all this is added to your project, rerun cmake on your project, build your project and finally try 'make install' or run the 'Installation' target from Xcode. You will see lots of text output during the installation phase indicating what is currently being performed. After all the libraries are copied and the install_name of each is corrected a verification phase will be performed to make sure the application bundle is properly created.  
After all this is added to your project, rerun cmake on your project, build your project and finally try 'make install' or run the 'Installation' target from Xcode. You will see lots of text output during the installation phase indicating what is currently being performed. After all the libraries are copied to the install tree, a verification phase will be performed to make sure the application bundle is properly created.  
Assuming the verification has passed you should now have a QtTest.app that you can place on another computer and successfully run.
Assuming the verification has passed you should now have a QtTest.app that you can place on another computer and successfully run.


== Notes ==
To create a package, one can execute cpack -G <generator name> on the CMake generated CPackConfig.cmake file.
This example does not cover the copying of any Qt Plugins or any other plugins. There is an additional argument to the 'BundleUtilities' module that can take care of the plugins.

Revision as of 00:18, 13 December 2009

Overview

CMake 2.6.2 includes a new module called 'BundleUtilities'. This module is intended to make the task of creating a fully standalone OS X application bundle much easier than before. It still requires some setup on your part though. In CMake 2.8, the module was ported to Linux and Windows. In this example we will walk through the necessary files and CMake code that are needed to use the 'BundleUtilities.cmake' effectively. Get the project Media:QtTest-Package-Example.zip‎.

Basic Flow

The CMake code in the example does a few things. - It has install commands for targets built by the CMake code. - It has an install command for Qt plugins - It has an install command for creating a qt.conf file - It has an install command for executing CMake code at install time. This code uses BundleUtilities which gathers and includes prerequisites into the application bundle. On Mac OS X, BundleUtilities also modifies the install names.

Additions to your CMakeLists.txt File

A simpler version of this example would have something like:

set(APPS ...)  # paths to executables
set(DIRS ...)   # directories to search for prerequisites
INSTALL(CODE "
   include(BundleUtilities)
   fixup_bundle(\"${APPS}\"   \"\"   \"${DIRS}\")
   " COMPONENT Runtime)

But since we include Qt plugins, we use the second argument to fixup_bundle().

After all this is added to your project, rerun cmake on your project, build your project and finally try 'make install' or run the 'Installation' target from Xcode. You will see lots of text output during the installation phase indicating what is currently being performed. After all the libraries are copied to the install tree, a verification phase will be performed to make sure the application bundle is properly created. Assuming the verification has passed you should now have a QtTest.app that you can place on another computer and successfully run.

To create a package, one can execute cpack -G <generator name> on the CMake generated CPackConfig.cmake file.