[CMake] BundleUtilities (was RPATH on Mac)

Michael Jackson mike.jackson at bluequartz.net
Mon May 2 11:59:00 EDT 2011


You have a couple of options but basically if you build your executable as a command line application (your first try) and the plugin is located in the same directory as your executable then the loading generally isn't a problem (Barring changes in working directory). But when you create a true OS X application then the executable is now located in a different directory. What you need to decide is where you want to build your executable and plugins which will dictate how the library is loaded. Probably the easiest is to place in your code where you load the plugin some additional search paths for the plugins.
 If you are using Qt there are lots of examples on how to do this in your code. For completeness here is some pseudo code:

string pwd = getCurrentWorkingDirectory();
loadPlugins(pwd);
#ifdef (APPLE)
// Look in a folder called Plugins located inside the .app bundle
  pwd = changeDirectories("../Plugins");
  loadPlugins(pwd);
// Look in a folder called Plugins located at the same level as the .app bundle
  pwd = changeDirectories("../../../");
  loadPlugins(pwd);
#endif

This setup looks both IN the bundle and NEXT to the bundle which allows your build directory to work and also your installed application since those plugins will be copied INTO the bundle during the installation.

Hope that helps
___________________________________________________________
Mike Jackson                      www.bluequartz.net
Principal Software Engineer       mike.jackson at bluequartz.net 
BlueQuartz Software               Dayton, Ohio

On May 2, 2011, at 11:45 AM, tog wrote:

> Hi,
> 
> I am back on this topic.
> 
> I have rewritten my  example to load the library with a path relative
> to the location of my executable.
> Everything is working fine in my build directory specifying:
>     ADD_EXECUTABLE(main main.cpp sub.cpp)  <- executable is created
> as example/main
> but is not working if I state:
>     ADD_EXECUTABLE(main  MACOSX_BUNDLE main.cpp sub.cpp)  <-
> executable is created as example/main.app/Contents/MacOS/main
> This is due to the fact that the plugin lib cannot be located.
> Is there a standard a convention for loading my libs that will work
> for both my build and install dirs as well as for all my architecture
> ?
> 
> Then my remaining problems will be to be able to install the NON
> plugin libs in a Frameworks (do we have something similar to
> BundleUtilities for that)
> 
> 
> Regards
> Guillaume
> On Sat, Apr 23, 2011 at 7:44 PM, tog <guillaume.alleon at gmail.com> wrote:
>> 
>> To mixup a framework. From my project I would like to create a framework with the libs. Then with the framework I would like to create the .app.
>> Nota: I would like to do that from a "neutral" location i.e. without installing on my machine
>> 
>> On Apr 23, 2011, at 6:37 PM, Michael Jackson <mike.jackson at bluequartz.net> wrote:
>> 
>>> To Copy in a framework into a .app bundle or to fixup a framework? In the first case things should "just work" as I copy in Qt Frameworks all the time.
>>> 
>>> --
>>> Mike Jackson <www.bluequartz.net>
>>> 
>>> On Apr 22, 2011, at 10:31 PM, tog wrote:
>>> 
>>>> Hi
>>>> 
>>>> Do we have something similar to BundleUtilities for Frameworks ?
>>>> 
>>>> Best Regards
>>>> Guillaume
>>>> 
>>>> On Wed, Apr 20, 2011 at 9:48 PM, David Cole <david.cole at kitware.com> wrote:
>>>>> On Wed, Apr 20, 2011 at 11:38 AM, Michael Jackson
>>>>> <mike.jackson at bluequartz.net> wrote:
>>>>>> 
>>>>>> ___________________________________________________________
>>>>>> Mike Jackson                      www.bluequartz.net
>>>>>> Principal Software Engineer       mike.jackson at bluequartz.net
>>>>>> BlueQuartz Software               Dayton, Ohio
>>>>>> 
>>>>>> On Apr 20, 2011, at 11:25 AM, David Cole wrote:
>>>>>> 
>>>>>>> On Wed, Apr 20, 2011 at 11:17 AM, Michael Jackson
>>>>>>> <mike.jackson at bluequartz.net> wrote:
>>>>>>> On Apr 20, 2011, at 10:55 AM, David Cole wrote:
>>>>>>> 
>>>>>>>> 
>>>>>>>> What is wrong with that one ?
>>>>>>>> 
>>>>>>>> Nothing is wrong with it, but there is no link from the app to the
>>>>>>>> plugin, so fixup_bundle cannot determine that it's necessary and
>>>>>>>> automatically pull it in. The plugin, from the app's point of view, is
>>>>>>>> something that may or may not exist, and if it does, it's dynamically
>>>>>>>> loaded. So you need to install it into the bundle first, and then you need
>>>>>>>> to tell fixup_bundle about it so that it gets included in the set of fixed
>>>>>>>> up libraries.
>>>>>>>> 
>>>>>>>> Hope this helps,
>>>>>>>> David
>>>>>>> 
>>>>>>> Is that the part that changed from CMake 2.8.3 to 2.8.4? I am using
>>>>>>> CMake 2.8.3 and all my code works fine but I don't think I explicitly
>>>>>>> "install" the plugin but rather list it (the absolute path to the built
>>>>>>> plugin) as an argument to the "fixup_bundle" function. Will that scheme
>>>>>>> still work under CMake 2.8.4?
>>>>>>> 
>>>>>>> There are some other issues with CMake 2.8.4 with BundleUtilities and
>>>>>>> my code which is why I have not updated from 2.8.3
>>>>>>> 
>>>>>>> Mike Jackson
>>>>>>> www.bluequartz.net
>>>>>>> 
>>>>>>> 
>>>>>>> 
>>>>>>> In CMake 2.8.3 and earlier, libs listed in the 2nd arg to fixup_bundle
>>>>>>> were copied into the bundle. Half the people using it considered that
>>>>>>> behavior a bug, half liked it just fine.
>>>>>>> 
>>>>>>> In 2.8.4, we "fixed" the bug (really, transferred it to the other half
>>>>>>> of the people)...
>>>>>>> 
>>>>>>> In retrospect, I never should have allowed that change to go into CMake,
>>>>>>> but there you have it: 2.8.3 and earlier copy the plugins, 2.8.4 and later
>>>>>>> do not.
>>>>>>> 
>>>>>>> So: if you want a plugin inside your bundle, with CMake 2.8.4 and later,
>>>>>>> you have to copy/install the plugin into the bundle yourself before calling
>>>>>>> fixup_bundle.
>>>>>>> 
>>>>>>> 
>>>>>>> Sorry for the persisting confusion,
>>>>>>> David
>>>>>>> 
>>>>>> 
>>>>>> So I should probably put the copy step into my configured cmake file that
>>>>>> runs the 'fixup_bundle'? I guess an install rule with the proper path inside
>>>>>> the app bundle should work. Isn't there an easier way? BUNDLE DESTINATION
>>>>>> argument to the INSTALL(target.. ) should do it also correct?
>>>>>> 
>>>>>> Thanks
>>>>>> Mike Jackson
>>>>>> 
>>>>> 
>>>>> I would recommend something like this (top of my head, not actually building
>>>>> from this):
>>>>> 
>>>>>  install( TARGETS myapp BUNDLE DESTINATION . )
>>>>> 
>>>>> That should produce a directory structure in CMAKE_INSTALL_PREFIX like so:
>>>>> 
>>>>>  ./myapp.app/Contents/MacOS/myapp
>>>>> 
>>>>> Then for the plugin, something like:
>>>>> 
>>>>>  install( TARGETS plugin DESTINATION myapp.app/Contents/plugins )
>>>>> 
>>>>> Which should yield:
>>>>> 
>>>>>  ./myapp.app/Contents/MacOS/myapp
>>>>>  ./myapp.app/Contents/plugins/libplugin.dylib
>>>>> 
>>>>> Something along those lines. And then pass the full path to libplugin.dylib
>>>>> to fixup_bundle.
>>>>> 
>>>> PGP KeyID: 2048R/EA31CFC9  subkeys.pgp.net
>>>> 
>>> 
>> 
> 
> 
> 
> -- 
> PGP KeyID: 2048R/EA31CFC9  subkeys.pgp.net
> _______________________________________________
> Powered by www.kitware.com
> 
> Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html
> 
> Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ
> 
> Follow this link to subscribe/unsubscribe:
> http://www.cmake.org/mailman/listinfo/cmake



More information about the CMake mailing list