[CMake] Creating OSX bundles with CMake (without Xcode)

Jonatan Magnusson jonatan.magnusson at gmail.com
Mon Oct 1 05:16:41 EDT 2012


Hi

I'm a new OSX developer with many years of experience developing
applications using Emacs and Makefiles and I'm not happy about
resorting to Xcode on OSX. So I'm trying to compile and create OSX
bundles using CMake. Getting the application I'm currently working on
to build was no problem - it required just a few tweaks, since I have
happily used CMake to build on Linux for years.

But I'm not sure how to handle bundle creation!

I have two uses for bundles - first I have to create a bundle for
running the application during development, and second I have to
create a bundle for distribution. They could probably be the same, but
I'm mostly concerned about the first for now. So my problem is not
including library dependencies in the bundle, but rather to include
the application libraries, executables, plugins and resources for
testing the application after each code change.

There are a lot of alternatives to do this it seems: using
MACOSX_BUNDLE for the add_executable function call, using CPack or
creating the directory structure "by hand".

So, my directory structure looks something like this:

/plugins/plugin-A - Code for plugin A (shared library)
/plugins/plugin-B - Code for plugin B (shared library)
/libapp           - Application logic code
/ui               - User interface code (contains the main() function)
/data/pictures    - Picture resources
/data/settings    - XML-files etc

I have a root CMakeLists.txt that just declares the top project, sets
some variables and calls add_subdirectory() for each subdirectory
(plugins, libapp, ui, data).

The "plugin" and "libapp" subdirectories contains CMakeLists.txt that
create (shared and static) libraries.

The "ui" subdirectory contains the add_executable() function call that
builds the executable and links to "libapp".

Also, each directory has a CMakeLists.txt that contains installation
instructions for standard unix installation.

Now, the easiest way to create a bundle is to add MACOSX_BUNDLE to
add_executable in "ui". This creates a new bundle "/ui/ui.app" that
contains an Info.plist and the executable. But I must also add plugins
and resources to this bundle before I'm able to run it. What's the
best way to handle this? I don't like the idea that it is the
add_executable-function that creates the bundle - the bundle should be
for the entire project, not just that executable.

Since each subdirectory include an install() function call the
information about what to put in the bundle is more or less there
already: the same files should be put in the bundle as would be
installed on other Unix-systems (but in a different directory
structure).

I've played around with setting LIBRARY_OUTPUT_DIRECTORY to
"/theapp.app/Contents/PlugIns" for each plugin and similar for the
executable, and it kinda works, but it feels hackish. And I'm not sure
how to add resources in the same way. And Info.plist is not created
automatically, so I have to create it myself or perhaps set the output
path of the bundle created by MACOSX_BUNDLE to the same path …

Best practices? Is there even anyone doing it this way, or is everyone
using Xcode?

Regards,
Jonatan Magnusson

(I've sent this mail before, last week, but it never got out on the
mailing list, so I'm sending again. Sorry about any duplicates.)


More information about the CMake mailing list