[CMake] Installing OSX Frameworks
Mike Jackson
mike.jackson at imts.us
Wed Jul 23 11:06:21 EDT 2008
On Jul 22, 2008, at 7:58 PM, Shead, Timothy wrote:
> On 7/22/08 10:56 AM, "Mike Arthur" <mike at mikearthur.co.uk> wrote:
>
>> Has anyone worked out a nice way of installing the needed OSX
>> frameworks into
>> my application bundle?
>
> If you use the (bleeding-edge) CPack bundle generator, you can install
> frameworks (or any other dependency) using normal CMake install
> commands:
>
> INSTALL(
> DIRECTORY
> ${QT_LIBRARY_DIR}/QtAssistant.framework
> ${QT_LIBRARY_DIR}/QtCore.framework
> ${QT_LIBRARY_DIR}/QtDesigner.framework
> ${QT_LIBRARY_DIR}/QtGui.framework
> ${QT_LIBRARY_DIR}/QtNetwork.framework
> ${QT_LIBRARY_DIR}/QtScript.framework
> ${QT_LIBRARY_DIR}/QtSql.framework
> ${QT_LIBRARY_DIR}/QtSvg.framework
> ${QT_LIBRARY_DIR}/QtXml.framework
> USE_SOURCE_PERMISSIONS
> DESTINATION Frameworks
> )
>
> You would then use a custom startup command for your bundle that
> ensures the
> "real" executable can find the installed resources:
>
> #!/bin/sh
> BUNDLE="`echo "$0" | sed -e 's/\/Contents\/MacOS\/.*//'`"
> RESOURCES="$BUNDLE/Contents/Resources"
>
> export DYLD_FRAMEWORK_PATH=$RESOURCES/Frameworks
> export DYLD_LIBRARY_PATH=$RESOURCES/bin
>
> exec "$RESOURCES/bin/my_real_application"
>
> This works fine for most applications, but there are a couple of known
> issues to consider:
>
> * This installs the frameworks to Bundle/Contents/Resources/
> Frameworks, my
> understanding is that the "officially sanctioned" location for
> frameworks in
> bundles is Bundle/Contents/Frameworks.
>
> * As others have pointed-out, setting DYLD_FRAMEWORK_PATH and
> DYLD_LIBRARY_PATH can cause subtle problems if your main
> application spawns
> other processes.
>
> I hope to get these issues taken-care-of eventually, suggestions
> welcome.
>
> Cheers,
> Tim
>
> --
> Timothy M. Shead
> Scalable Analytics & Visualization (1424)
> Sandia National Laboratories
> 505-284-0139
>
I just wanted to comment for those playing along at home.
Using a custom startup script can be a bad idea as you mention
because you have to start setting environment variables which can be
prone to error.
What should be happening is that your application should be linked
with libraries that have an "install_name" set to @execuatble_path/../
Frameworks...." or "@executable_path/../Dylibs/...." or something
along those lines. If your application is linked correctly then a
startup script is NOT needed at all as the application will
inherently "know" where to find the libraries.
CMake has support to set the "install_name" of a compiled library.
Brad King posted this to the list back in October of 2007:
==========================================
The default behavior is to make things runnable from the build tree.
You can force it to use your given install_name like this:
ADD_LIBRARY(foo SHARED foo.c)
SET_TARGET_PROPERTIES(foo PROPERTIES
INSTALL_NAME_DIR @executable_path/../Frameworks
BUILD_WITH_INSTALL_RPATH 1
)
This is documented in the SET_TARGET_PROPERTIES command, though it may
not be clear that BUILD_WITH_INSTALL_RPATH applies to install_name too.
==========================================
There are lots of "home grown" solutions floating around to try and
take care of setting the install_name of included libraries. I have
rolled my own (based on some work I submitted to the ParaView
Project) that looks at what libraries the App links against and then
will correct the application executable to look for those libraries
within the App bundle, correct the actual library itself by setting
the correct install_name, and copy the library into the Application
bundle. I have this working for my Qt and VTK based projects but
really should be workable for any other projects. It is under a BSD
license so if you want it you can use it.
What would probably be nice at this point would be an example OS X
centric project that uses all these ideas with code explanations for
each step.
BTW, Xcode doesn't make this any easier. You still have to create a
"Copy files" build phase and correctly set the "install_name" for any
libraries.
Also, while there are "Apple Endorsed" locations for things such as
frameworks and Plugins, you can really put them just about anywhere
in the App Bundle. I don't condone such actions, but it can be done.
--
Mike Jackson Senior Research Engineer
Innovative Management & Technology Services
More information about the CMake
mailing list