[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