I’ve just spent the past two days fighting MacOS X installers. I saw that Privoxy still didn’t have a Universal Binary, so I set out to create one. The end result is available on on Etresoft.org. I used what I learned to finally put together a nice installer for , after only a couple of tries 🙂
What follows here is a detailed description of how to put together a MacOS X installer package. The end result is available in the Privoxy source code, but this is the thinking behind it. You should be able to follow these steps to create a Universal Binary installer for just about any open-source project.
First, you’ll need a place to work. I suggest creating a directory for all your Mac installer stuff. Create a directory named something like “PackageMaker”.
Next, you want to know what the final install is going to look like. Run “configure” on your utilities and specify an unusual prefix – something like ‘./configure –prefix=PackageMaker/Root”. Do a make and install. That will give you a self-contained snapshot of what you want to install.
Also, if you want to build a Universal Binary, you will probably need a nasty configure call like “env CFLAGS=”-isysroot /Developer/SDKs/MacOSX10.4u.sdk -arch i386 -arch ppc” ./configure –prefix=PackageMaker/Root –disable-dependency-tracking” and probably run make using “env CFLAGS=”-isysroot /Developer/SDKs/MacOSX10.4u.sdk -arch i386 -arch ppc” make”. You may even need to specify LDFLAGS just like CFLAGS. YMMV.
Fire up /Developer/Tools/PackageMaker.
- Create a “Single Package Product”.
- In the “Installer Interface” tab, give your utility a nice title and description.
- If you have a nice background image you want to use for when the installer runs, add it and specify the position in the “Show Installer Interface Editor”. That is the only thing you want to use the “Installer Interface Editor” for. You’ll handle the License, Readme, and Welcome message elsewhere.
- In the “Contents” tab, specify the Root location. This is the prefix where you installed your utility – in this example, it is “PackageMaker/Root”. Make sure the “Discard Resource Forks” is checked. Otherwise, the user will have to authenticate as Administrator in order to install. Don’t go into “File Permissions” as it is very poorly implemented. Do that manually later. Set up the desired install location in “Locator Definitions” using “CheckPath”. I don’t know how well this particular feature works. In “File Filters” specify any files or directories you want to installer to ignore. CVS and svn stuff is ignored by default.
- In the “Configuration” tab, define the install location for your utility. Everything under “PackageMaker/Root” will be installed under the directory you specify here. The only other really important setting is “Authentication”. If the utility you are installing needs to be owned by root, use “Administrator”. Otherwise, use “None”. Turn on “Relocatable” if you want the user to be able to specify where to install. Don’t change anything else here.
- Don’t do anything in the “Scripts” tab.
- In the “Package Version” tab, set values as appropriate.
- Save and build a package
The PackageMaker GUI is pretty crippled and buggy, so you really don’t want to use it other that for that one time. What you need it to do for you is build the “Info.plist” and “Description.plist” files. Once you have those files, you can use the command line tool “/Developer/Tools/packagemaker” that works much better.
In order to use that packagemaker tool, you (may) need one additional thing. You probably want to display a license to make the user agree to. You might also want to display a read me and welcom message. You will also need this if you have specified a background image. What you want is an “Install_Resources” folder with the appropriate files. That folder shall be organized as follows:
Everything in this folder is optional. You can add additional languages. You can move the background image (if you have one) into the language-specific folders if you want. You can use various standard file formats, but otherwise, case and spelling are significant.Tip:If you use HTML, you can also include separate style sheet files.
There are some scripts you can include in the Install_Resources folder that will be run by the installer automatically. The primary ones are “postinstall” and/or “postupgrade”. Since the installer is run by the (possibly Administrator-authenticated) user, you can do whatever you want in these scripts and they will run as the user. Typically, you will want to assign good permissions and ownership, backup old config files, etc.
Run the following command line:
/Developer/Tools/packagemaker -build -f "PackageMaker Files/Applications" -p "MyUtility.pkg" -ds -v -r "PackageMaker/Install_Resources" -i "PackageMaker/Info.plist" -d "PackageMaker/Description.plist"
and with any luck, it will work.
By this point, you probably have a script to do this stuff for you. Add the following to it:
echo Creating a disk image for the installer.
rm -Rf "MyUtility"
mv "MyUtility.pkg" "MyUtility"
hdiutil create -srcfolder "MyUtility" -anyowners -format UDZO "MyUtility.dmg"
rm -Rf "MyUiltity"
That will create a disk image with the installer package. If you have something like DropDMG or a similar utility, you can make your installer image all fancy-like.
If you know how to add all this stuff to a configure-generated makefile, I’ll love to see it!
And that’s all there is to it! What could be simpler?