How to unpackage and repackage a pkg (OS X Lion+ / Xcode 4.3+)
The first thing you may ask is "AJ, why are you wasting your time on this? There are already tutorials on how to do this!"
Well, yes, but there are new tools for Xcode 4.3 and up that do a better,
simpler job than the
cat <Payload|Script> | gzip -d - | cpio -id method.
Plus, here we get a chance to look at the
plist as well!
Here's my use case. A friend of mine packaged a package for a company we used to work, but the documentation was never written or lost.
I want to use that work as the basis for a package that I'm creating, but I don't know where to start... so I'm going to rip apart the old package instead of starting from scratch.
You can get Xcode from App Store, but you'll also need the Command line tools from https://developer.apple.com/downloads/index.action (Log in and then search for it in Developer Downloads)
Note: On Ubuntu (or other Linux) you will need to have
See the File Commands section of http://developer.apple.com/.../pkgutil.1.html
So let's say I have
~/Downloads/ExampleApp.pkg (which I do!) and I want to extract / upack it.
pushd /tmp pkgutil --expand ~/Downloads/ExampleApp.pkg /tmp/ExampleApp.unpkg
Then, for fun, I like to see what all was extracted
For reference, the long way of doing this (i.e. for Linux) is
mkdir -p /tmp/ExampleApp.unpkg pushd /tmp/ExampleApp.unpkg xar -xf ~/Downloads/ExampleApp.pkg ls -d *.pkg | while read PKGDIR do pushd $PKGDIR || continue mv Scripts Scripts.bin mkdir -p Scripts pushd Scripts cat ../Scripts.bin | gzip -d | cpio -id popd popd done
Note that the file
Scripts is unpackaged to a folder Scripts, with the scripts inside.
I'm going to take a wild guess and say that Bom stands for Bill of materials, which is hardware engineers submit to off-site manufacturing facilities.
It's basically the
tar --list (same as
tar -t) of pkgs.
See the options section of http://developer.apple.com/.../lsbom.8.html
Note that you can extract just the Boms, with slightly less verbosity with
pkgutil --bom ~/Downloads/ExampleApp.pkg
PackageInfo is already a plain text file.
It contains the organization identifiers, install location, number of files and bytes to install, etc.
So, you still end up having to use the old black magic for the payload
pushd ~/tmp/ExampleApp.unpkg/ pushd example.pkg/ cat Payload | gzip -d | cpio -id ls
The Distribution file and the Resources folder
The Resources folder contains resources that are needed for the installer, but not to be installed - such as the background image to use.
If you somehow accidentally deleted the package, but you didn't change anything you can repackage the pkg like-a-so:
pkgutil --flatten /tmp/ExampleApp.unpkg ~/Desktop/ExampleApp.pkg
But let's say you do change a file (or add one, etc). What then?
First we extract the Payload to a clean directory, like so:
mkdir /tmp/ExampleApp-example.pkg pushd /tmp/ExampleApp-example.pkg cat /tmp/ExampleApp.unpkg/example.pkg/Payload | gzip -d | cpio -id
Next you add / remove / edit your files
Then you repackage the Payload with a new Bom
rm /tmp/ExampleApp.unpkg/example.pkg/Payload rm /tmp/ExampleApp.unpkg/example.pkg/Bom # Still in /tmp/ExampleApp-example.pkg find . | cpio -o --format odc | gzip -c \ > /tmp/ExampleApp.unpkg/example.pkg/Payload mkbom /tmp/ExampleApp-example.pkg/ /tmp/ExampleApp.unpkg/example.pkg/Bom
And finally update the PackgeInfo with the number of KB and files
installKBytes is the number of KiB assuming that the disk using 4KiB blocks, minus 4KiB:
du -sk /tmp/ExampleApp-example.pkg/ # subtract 4 from that number!!!
numberOfFiles is the number of nodes (files, directories, sockets, whatever), including
find /tmp/ExampleApp-example.pkg/ | wc
Those values can be edited at
With all of that done you can now repackage the entire shebang:
pkgutil --flatten /tmp/ExampleApp.unpkg/ /tmp/ExampleApp.new.pkg
Note: If you used
xar to extract (on Linux) instead of
you'll need to use that again:
pushd /tmp/ExampleApp.unpkg xar -cf ../ExampleApp.new.pkg .
Test and enjoy!
If you need to do all of this from Linux - perhaps you need to edit a uuid for every download or something - then make sure to peek at the notes here as well:
By AJ ONeal
Did I make your day?
Buy me a coffee