Because of Mountain Lion's Gatekeeper I finally had to take my PackageMaker build script behind the barn and shoot it. PackageMaker was already removed from Xcode and moved into "Auxiliary Tools for Xcode", so hopefully it will be soon forgotten.

The question is how do I use pkgbuild, productbuild, and pkgutil to replace it?

so I assume the issue with packagemaker is inability to properly sign pkg files for use with gatekeeper on Mountain Lion?
– JasonZAug 12 '12 at 21:36

1

It is possible, but PackageMaker always was buggy has hell, and got deprecated with Mac OS X 10.6 Snow Leopard. It will save you time in the long run to just get familiar with the new tools.
– catlanAug 12 '12 at 23:08

@catlan: Do you have an official link that says packagemaker has been deprecated on 10.6?
– CarlAug 22 '12 at 2:09

2

@carleeto: It was never announced as being deprecated, just removed from Xcode and eventually "disappeared" like a Burmese protester.
– bugOct 23 '12 at 19:53

This give us the component-plist, you find the value description in the "Component Property List" section. pkgbuild -root generates the component packages, if you don't need to change any of the default properties you can omit the --component-plist parameter in the following command.

In the Distribution.xml you can change things like title, background, welcome, readme, license, and so on. You turn your component packages and distribution definition with this command into a product archive:

If you don't have to change the package after it's generated with productbuild you could get rid of the pkgutil --expand and pkgutil --flatten steps. Also you could use the --sign paramenter on productbuild instead of running productsign.

In case your version control doesn't store Xcode Scheme information I suggest to add this as shell script to your project so you can simple restore the action by dragging the script from the workspace into the post-action.

Additional Reading

Known Issues and Workarounds

Destination Select Pane

The user is presented with the destination select option with only a single choice - "Install for all users of this computer". The option appears visually selected, but the user needs to click on it in order to proceed with the installation, causing some confusion.

Apples Documentation recommends to use <domains enable_anywhere ... /> but this triggers the new more buggy Destination Select Pane which Apple doesn't use in any of their Packages.

Using the deprecate <options rootVolumeOnly="true" /> give you the old Destination Select Pane.

You want to install items into the current user’s home folder.

Short answer: DO NOT TRY IT!

Long answer: REALLY; DO NOT TRY IT! Read Installer Problems and Solutions. You know what I did even after reading this? I was stupid enough to try it. Telling myself I'm sure that they fixed the issues in 10.7 or 10.8.

First of all I saw from time to time the above mentioned Destination Select Pane Bug. That should have stopped me, but I ignored it. If you don't want to spend the week after you released your software answering support e-mails that they have to click once the nice blue selection DO NOT use this.

You are now thinking that your users are smart enough to figure the panel out, aren't you? Well here is another thing about home folder installation, THEY DON'T WORK!

I tested it for two weeks on around 10 different machines with different OS versions and what not, and it never failed. So I shipped it. Within an hour of the release I heart back from users who just couldn't install it. The logs hinted to permission issues you are not gonna be able to fix.

So let's repeat it one more time: We do not use the Installer for home folder installations!

RTFD for Welcome, Read-me, License and Conclusion is not accepted by productbuild.

Installer supported since the beginning RTFD files to make pretty Welcome screens with images, but productbuild doesn't accept them.

Workarounds:
Use a dummy rtf file and replace it in the package by after productbuild is done.

Note: You can also have Retina images inside the RTFD file. Use multi-image tiff files for this: tiffutil -cat Welcome.tif Welcome_2x.tif -out FinalWelcome.tif. More details.

Starting an application when the installation is done with a BundlePostInstallScriptPath script:

It is important to run the app as logged in user, not as the installer user. This is done with launchctl asuser uid path. Also we only run it when it is not a command line installation, done with installer tool or Apple Remote Desktop.

This is an excellent tutorial, but assumes the existence of prefabricated bundles. If I were to, for example, install a single file into /tmp to be processed later in a postflight script, how do I structure the component list? All available documentation appears to assume that the developer has generated it with --analyze, at least initially.
– bugOct 21 '12 at 18:11

1

If you don't need to change anything in the Component Property List you don't need to run --analyze. For postprocessing files I suggest put them all into a pkg and set that pkg install location to /tmp. But maybe I misunderstand your question. If so post it in a more detailed version on SO.
– catlanOct 21 '12 at 19:53

2

Please notice that it makes absolutely no sense to make packages via the command line, trying to escape all the bugs in the packaging app. Rather see my comment below on using the "Packages" application by Stéphane Sudre which solves all problems for you!
– Bram de JongAug 14 '13 at 11:24

3

@BramdeJong "makes no sense". I disagree. Apple maintains the command line tools. Packages is a third-party app that isn't community supported and may break in the future if Apple changes something drastic. For me, I'd rather know the command line technique so that, if Apple changes something drastic, then I can keep running.
– VolomikeNov 26 '15 at 6:22

3

$ pkgbuild --root ./HelloWorld.app is wrong (assuming that .app is an actual app bundle). pkgbuild operates on a destination root :i.e.: a folder that CONTAINS a bundle generated by the xcode tool chain. So the argument to pkgbuild is the path to the containing folder of the bundle we want to package. Failing to get this right results in a package that contains just the app contents folder. It won't install as an actual app bundle. The giveaway is in the component plist. If that doesn't contain a RootRelativeBundlePath entry specifying the app bundle then you have screwed up.
– Jonathan MitchellJul 22 '16 at 21:25

There is one very interesting application by Stéphane Sudre which does all of this for you, is scriptable / supports building from the command line, has a super nice GUI and is FREE. Sad thing is: it's called "Packages" which makes it impossible to find in google.

I cannot believe that this post doesn't have more point. That software is amazing and it supports building from the command line.
– Cesar MendozaApr 16 '13 at 21:42

1

Anyone tried to sign a package with this tool? I cannot get the "Set Certificate" menu item to activate....
– GTAE86Jan 23 '14 at 22:20

1

@user283182: Very late bump, surely you've already figured it out, but maybe this will help others - I think the issue you are facing is detailed in the [Mac App Store Review Guidelines]( developer.apple.com/app-store/review/guidelines/mac/…), rule 2.14: "Apps must be packaged and submitted using Apple's packaging technologies included in Xcode - no third party installers allowed."
– elder elderSep 23 '14 at 19:55

4

I wish this was a payed app and the developer is constantly updating and patching. Packages.app is awesome especially if you want to quickly deploy your app. It took me total of 3 min to install read the Overview, set up my project and create the installable package. Big kudos to Stéphane.
– Nikolay ChristovSep 28 '14 at 1:14

This works well, but with a GOT'CHA: If you first install per-user, then install per-machine, the install will be in the user-dir, not the machine-dir, but with sudo-rights. The opposite is not the case: you can install per-machine, and then per-user afterwards and have it in both places.
– Terje DahlJan 10 at 18:51

@TerjeDahl yes this is because post installation the bundle is moved to the location same bundle id was installed previously by installer (and installer knows that). This can be prevented by some settings in the manifest file that I dont remember right now.
– PnotNPJan 10 at 20:37

@ PnotNP Ah. If you would be so kind as to come back with those setting if you could remember, then that would be great!
– Terje DahlJan 12 at 11:32