How to run packagemaker from a build script? - macos

I have an Ant script which turns my Java application into a nice Mac Bundle using the JarBundler task. The problem is how do I now turn that into a .pkg file for distribution?
I'm looking at using the packagemaker command line tool (located in /Developer/usr/bin/packagemaker) but it has a number of drawbacks:
If I use the '--doc' option to point it to a .pmdoc file (built using the PackageMaker GUI) then I will have to manually change the .pmdoc contents whenever I add files to my project
If I use the '--root' option to build the package based on the app bundle then it seems I don't get many of the features of the GUI (such as including the licence text).
How do other people produce a .pkg file with their build script?
Thanks

I use the following to build a package from a pmdoc and the the DMG containing the package on OS X 10.6:
/Developer/usr/bin/packagemaker --verbose --doc [project].pmdoc --out [project].pkg
mkdir -p dmg
cp -pR [project].pkg dmg
hdiutil create dmg/[Project]-r$SVN_REVISION.dmg -volname "[Project]" -fs HFS+ -srcfolder dmg

I use scripts to automatically update parts of the PackageMaker file. I found it more convenient to keep the old format .pmproj files rather than to switch to the more recent bundle format.

You can use packagemaker's --resources options to add a resources folder to the package. If you're building an older-style package (10.3 and maybe 10.4 target), all you need to do is put files with appropriate names (e.g. (License,ReadMe,Welcome).(rtf|html) and Background.(jpg|gif|pdf|tif)) optionally organized into .lproj subfolders, and they'll included & used by the package. This doesn't seem to work with distribution packages (10.5-style flat packages and some 10.4 packages), as the resource file names have to be listed in the distribution file, and I'm not sure how to put them there with packagemaker.

Related

Can macOS flat file pkg installer throw error dialog?

I want to throw error dialog (and fail the installation) if certain file exists on the system. Is it possible?
pkg = flat file pkg
It's possible to customize the installer in various ways to get whatever functionality is needed generally. Typically in your scenario either a Pre-Installation script could be used or a Package Installer Plugin. The options would normally be defined in the installer package's distribution.dist which essentially functions as the schema it will follow.
See productbuild in the man pages:
--scripts scripts-path
- The contents of scripts-path is added to the product archive for use by system.run() commands commands in the distribution. This is valid only for product archives targeted to the OS X Installer application.
--plugins plugins-path
- The contents of plugins-path is added to the product archive for use by the OS X Installer application's plugin mechanism. It will normally contain a InstallerSections.plist file, and one or more plugin bundles.
↳ About Distribution Definition Files & productbuild

Package a command line script in a Mac OS X pkg

I have a program (created by a colleague, ported from Linux but successfully compiles on Mac) that I need to deploy to lots of Mac workstations. Currently we do so by pushing out pkg files (not ones we created).
My general question (that others may find the answers to useful) is how do I go about packaging a command line program/script into a pkg file that installs the program? The usual method to package an .app file seems documented well enough, but there is scant details about taking an arbitrary program and wrapping it in a pkg installer.
The man pages for pkgbuild (etc) make a lot of assumptions - that you've already built an app with xcode, that you're intending to use an .app and can generate plists, etc. All we want to do is let the mac server install a non-app program, and it wants to use pkgs.
It would be best if the solution were scriptable so that every time we update the program we can easily create a new pkg file. If a decent resource already explaining this process can be linked that of course would also work great. The question here: Making OS X Installer Packages like a Pro - Xcode Developer ID ready pkg doesn't match the need to simply install a basic cli program.
I would recommend Packages.
It's scriptable so it can become part of your build process and generates a nice mpkg for you.
We are using it to automate the download of third-party libraries, and then the invocation of make to compile, as well as the installation of compiled files.
As a note, although this will generate a mpkg, most distributions are done with disk images, so we also use hdiutil to create a sparse image, copy the mpkg into it, convert it to a compressed read-only dmg and then distribute that.
An example of this procedure would be:
1) Create Sparse RW DMG file.
hdiutil create -size 100M -type SPARSE -volname "MyInstaller" -fs HFS+ MyInstaller.dmg.sparseimage
2) Attach to image. Note disk and mounted volume name from output (ex. /dev/disk2s1 and /Volumes/MyInstaller)
hdiutil attach MyInstaller.dmg.sparseimage
3) Copy in mpkg installer
cp -R Packages/build/My_Packages.mpkg /Volumes/MyInstaller/
4) Detech from image.
hdiutil detach -force {mounted disk} (ex. hdiutil detach -force /dev/disk2s1)
5) Create compressed read only image from writable sparse image.
hdiutil convert "MyInstaller.dmg.sparseimage" -format UDZO -o "MyInstaller.dmg" -ov -imagekey zlib-level=9

Using productbuild for mac os x app with additional tools and files

For one of my projects i used building script using packagemaker. Packagemaker allows specify all files i need install from root, so my root had following structure:
Applications
My Application.app
Library
Preferences
MyCompanyName
some.xml
another.xml
tmp
default.p12
usr
local
bin
sometool
I.e. it had following features:
Some configuration files preinstalled for all users, to global Preferences (some.xml, another.xml)
Some command line tool being used as by main app as user in /usr/local/bin
Program uses certificates and there is one default certificate which will be moved to right place in postflight
How to do same with productbuild? Possible?
The basic tool that does the packaging you want is pkgbuild, not productbuild. pkgbuild will let you specify a root directory that, upon installation, will be expanded to '/'. So, you can use that for all of what you discuss in your question (though an installer putting something in /tmp is a bit weird - I'd suggest baking the cert right into your postinstall script).

Scriptable way to create flat .pkg files with custom resources and scripts

I have created a flat .pkg file with following options on 10.7 using PackageMaker 3.0.6:
/Applications/PackageMaker.app/Contents/MacOS/Package --root ./myroot \
--id com.myroot.pkg --title "My Root" --scripts ./scripts --target 10.5 \
--verbose --resources ./resources --root-volume-only --domain system \
--no-relocate --versio 1.0 --certificate "My Cert Name"
In the resources folder I have background.png, Welcome.rtf and License.rtf and in the scripts folder I have preflight, postflight and various support files for those scripts. The resulting .pkg appears to be fully functional except that the installer does not display my background, welcome or license.
How can I add a custom background, welcome and license to a flat package?
As far as I can tell, the Distribution file in the .pkg is missing references to the background, welcome and license files.
As a workaround I tried using xar. If I unpack the package with xar like so:
xar -xf ./myroot.pkg -C work
and add the 3 tags for those files, then pack it again with xar:
cd work && xar -cf ../myroot2.pkg *
I get a package that starts installation ok with my background etc., but when it comes time to install my .app I get these errors (from /var/log/install.log):
run preupgrade script for myroot
Could not create task for action: run preupgrade script for myroot2
Install failed: The Installer could not extract files from the package for myroot2. Contact the software manufacturer for assistance.
IFDInstallController 863170 state = 7
I have also tried Flat Package Editor: open myroot.pkg, drag out Distribution, edit it, drag it back, delete old Distribution, save. Same problem as with xar.
I would prefer to have a fully scriptable solution as opposed to using GUIs.
Edit: I have also tried to use pkgutil to expand, edit Distribution, and reflatten a flat package. This gets the icons and readme in the installer, but the installer is then unable to unpack the payload. Same if I reflatten with Flat Package Editor. I have also tried to create an expanded package without PackageMaker (which works, except on 10.8), but when I try to flatten that with pkgutil the result is a corrupted package again.
PackageMaker always was buggy has hell, and got deprecated with Mac OS X 10.6 Snow Leopard.
You should use pkgbuild together with productbuild.
This Mac Installers Blog has some useful posts about Packagemaker including details about the usage and solutions to common problems. Hope it will help.
Check out the Luggage - it's a Makefile helper file that lets you create OS X packages with sane Makefiles. Disclaimer: I am the original author for it, though there are a lot of other people's contributions in it now.

How to build a dmg Mac OS X file (on a non-Mac platform)?

Is it possible to build a .dmg file (for distributing apps) from a non-Mac platform?
And if yes, how?
Yep, mkfs.hfsplus does it.
dd if=/dev/zero of=/tmp/foo.dmg bs=1M count=64
mkfs.hfsplus -v ThisIsFoo /tmp/foo.dmg
This creates a dmg file (in this case 64M) that can be mounted on a mac. It can also be mounted on linux, with something like
mount -o loop /tmp/foo.dmg /mnt/foo
after wich you just copy the content you want to it (in /mnt/foo). Unmount it, and the dmg can be copied over to a mac and mounted there.
A project I work on creates DMG files on Linux using genisoimage:
mkdir -p dmgdir/progname.app/Contents/{MacOS,Resources}
...copy your PkgInfo, Info.plist to Contents...
...copy your .icns to Resources...
...copy your other things to where you expect them to go...
genisoimage -V progname -D -R -apple -no-pad -o progname.dmg dmgdir
If you want to be really fancy, you can steal the .DS_Store file from a DMG made on a Mac with a volume name progname and app bundle called progname.app (i.e., matching what you want to create off the Mac) where you've put a background in .background/background.png and a symbolic link to /Applications in the root dir, and put that in dmgdir along with your own a symbolic link to /Applications.
Finally, if you want to create a compressed DMG, get the dmg tool from libdmg-hfsplus:
dmg uncompressed.dmg compressed.dmg
git clone https://github.com/hamstergene/libdmg-hfsplus
cd libdmg-hfsplus && cmake . && make && cd dmg
./dmg --help
Makefile:
dmg:
genisoimage -D -V "$(PROJECT) $(VERSION)" -no-pad -r -apple -o project-$(VERSION)-uncompressed.dmg $(DARWIN_DIR)
./dmg dmg project-$(VERSION)-uncompressed.dmg project-$(VERSION).dmg
uncompressed works out of the box, compression may cause problems - the origin/master at least produces a 'checksum' error on snow-leopard
It does seem possible to create DMG files with some third party tools. A quick google search reveals at least a few commercial tools:
TransMac
MagicISO
Not sure about any OSS/freeware options, but it does at least seem possible if you are so inclined.
Edit: I also forgot about MacDrive, which is another great tool for working with HFS+ filesystems under windows. Since a DMG is basically just a HFS+ filesystem snapshot, it is probably possible with MacDrive to create DMG's as well.
I'm not sure if anyone is still watching this thread, but I tried TransMac as recommended by Nik Reiman.
Using this tool I was able to, running on Windows 7, create dmg files which were mountable on OSX 10.8.3.
Downside
The only downside for us is that this tool doesn't appear to be command-line friendly; for us that's a deal-breaker as we need to be able to have an automated tool which our build server (Windows based) can use to build dmg files on-the-fly.
See mkfs.hfsplus
If you're distributing Mac apps, then surely you have a Mac to write and test them. Why not simply use that same Mac to create the disk image?
[Edit] Alternatively, if you're distributing a portable app, for example a Java .jar file, why bother with a disk image? Macs understand .zip and .tar.gz archives just fine.
I guess what I'm getting at is, I don't understand how one might need a DMG disk image, but not have a Mac with which to create it.

Resources