Journeys' End
20050201
  Creating OS X application bundles step by step
Introduction This guide is the result of attempting to package a network visualiser (tcprose) I wrote so that it can be distributed as an application bundle. I gathered information from many places, and while I try to be accurate as possible should you notice any bugs feel free to contact me. Step 1 - The folder hierachy Each application bundle is on disk a file that ends in .app and contains a strict folder hierachy. The folder hierarchy is the form: The first thing you need to do then is to create such a folder tree somewhere. Step 2 - The binaries The binaries of your program reside in the MacOS folder. If your program depends on libraries that are not present by default, then you need to do the following:
  1. Figure out what libraries your application depends on, and figure out what libraries need to be distributed with the program. In order to see the dynamic libraries your binaries depend on, use the otool thus:
    otool -L binary
    In my case:
    solaris:~/code/tcprose steve$ otool -L tcprose tcprose: /sw/lib/libSDL-1.2.0.dylib (compatibility version 8.0.0, current version 8.1.0) /System/Library/Frameworks/Cocoa.framework/Versions /A/Cocoa (compatibility version 1.0.0, current version 9.0.0) /System/Library/Frameworks/OpenGL.framework/Versions /A/OpenGL (compatibility version 1.0.0, current version 1.0.0) /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 71.1.1) /sw/lib/libpcap.0.dylib (compatibility version 0.8.3, current version 0.8.3) solaris:~/code/tcprose steve$
  2. Anything in /System or /usr can be safely assumed to be present on all default systems. Notice then the 2 libraries in /sw/lib. For those unfamiliar with fink, its where it installs all its packages. Those 2 libraries need to be copied into the Frameworks folder. Do be careful however that you copy the actual file, not the symbolic links. For example:
    solaris:/sw/lib steve$ ls -l libpcap.0.dylib lrwxr-xr-x 1 root admin 19 20 Aug 03:35 libpcap.0.dylib -> libpcap.0.8.3.dylib solaris:/sw/lib steve$
    Notice that libpcap.0.dylib is in fact a symlink to libpcap.0.8.3.dylib, thus you need to copy /sw/lib/libpcap.0.8.3.dylib, not /sw/lib/libpcap.0.dylib.
  3. Once the required libraries have been copied into Frameworks folder, its time to do some linking manipulation. Use the install_name_tool to remapped the dynamically linked libraries so your binary links against the libraries in Frameworks folder. To do this you issue the command:
    install_name_tool -change old_library_path new_library_path binary
    In tcprose's case:
    solaris:/sw/lib steve$ install_name_tool -change /sw/lib/libpcap.0.dylib @executable_path/../Frameworks/libpcap.0.8.3.dylib ./tcprose
    Notice the use of @executable_path: this is what makes it "tick". @executable_path will automatically map to the path where the executable is located. Now if you move the binary into the MacOS directory, it will link against the libraries you have copied into the Frameworks folder
Word of caution: as far as I know there is no way to re-map the paths of any files in the binaries. Thus if you open files by using fopen("file", "rw"); then it will fail, because the working directory will be the directory that contains the application bundle, not the directory where the binary is stored. You will therefore need to take this into account, and adjust your paths accordinly. Note: It might be possible to set the environmental variable PWD via Info.plist (see next step) to certain directory so that the working directory is somewhat more manageable. I didn't have any luck with this, so kindly let me know if you figure something out. Update - 6/3/05: as pointed out by a reader, you can extract the path of the executable from argv[0], and thus determine the relative paths of whatever resources your program needs. Step 3 - Info.plist Now we come to the most important step of creating an application bundle: creating a proper Info.plist inside the Contents folder. Info.plist is an xml file that describes properties that finder reads Info.plist and determines many things, including which binary inside MacOS to execute, what icon inside Resources to display, etc. The best tool to use for editing it is no doubt Property List Editor in /Developer/Applications/Utilities. You can of course do this by hand. Apple has a detailed document on how to create a proper Info.plist file, but at the absolute minimum the following keys are required: Extra: if you want to specify a custom icon, first create a .icns file with Icon Composer found in /Developer/Applications/Utilities then save the .icns file in the Resources folder, and add the CFBundleIconFile key. Conclusion Creating an application bundle is a relatively easy affair, the most difficult part being remapping the dynamically linked libraries and adjusting any hardwired paths and generating a proper Info.plist file. Have fun, and if you have any suggestions or bug reports, do let me know! Cheers, Steve
 
Comments:
I tried to create an application for Ethereal (that comes with fink) but I failed. It must be more than just is said here. I get "can't open application "ethereal" because it may be damaged or incomplete".

:-(
 
If you can, email me the output of otool -L ethereal (ethereal in the MacOS directory) and also your iInfo.pList file.

My email is freespace \at gmail \. com.

Cheers,
Steve
 
Just wanted to say thanks for this fast introduction into bundleing macosx packages.

It took me some time to figure the best way out to access resources that are put into the bundle. Best way seems to use the argv[0] and cut off the everything before the last "/". That will give you a usable directory to access everything.
 
To previous commenter - Thats is an ingenious idea! Why one earth didn't I think of that!

I'll add it to the guide as a tip. Thank you for letting me also this helped you, made the effort worth while :-)

Cheers,
Steve
 
Post a Comment



Links to this post:

Create a Link



<< Home
“Ah, but a man's reach should exceed his grasp, or what's a heaven for?” - Robert Browning

Resume
pdf / doc

Email
gmail / usyd

Downloads

Links
Chris' snippets

Archives
September 2003 / October 2003 / November 2003 / December 2003 / January 2004 / February 2004 / March 2004 / April 2004 / May 2004 / June 2004 / July 2004 / August 2004 / September 2004 / October 2004 / November 2004 / December 2004 / January 2005 / February 2005 / March 2005 / April 2005 / May 2005 / June 2005 / July 2005 / August 2005 / September 2005 / October 2005 / November 2005 / December 2005 / January 2006 / March 2006 / April 2006 / May 2006 / June 2006 / July 2006 / August 2006 / September 2006 / October 2006 / November 2006 / December 2006 / January 2007 / February 2007 / March 2007 / April 2007 /

Powered by Blogger

Subscribe to
Posts [Atom]