Readme buildpkg.py -- A Python tool to build OS X packages for Apple's Installer.app. Purpose This is a Python tool for building packages to be installed with the Mac OS X Installer.app application. It is much inspired by Apple's GUI tool called PackageMaker.app, which is part of the OS X developer tools installed in /Developer/Applications. There are other free GUI tools to do the same thing (1), (2). This tool has no GUI which is a feature and not a bug. Version The current version is 0.3. License The current license for this version is the "BSD License" as described by the Open Source Initiative (7). About Apples's Installer.app Apple has defined its own format for software packages to be installed on an OS X system. This format stems originally from the Mach/NeXTSTEP operating system of which OS X is a direct successor. The shape of such a package is basically a set of nested directories with the top-level one having the extension .pkg (or .mpkg). It contains one archive compressed with "pax", plus a set of further files describing the package content, plus additional optional scripts to be run during installation. Unfortunately, Apple does not fully document all features of its Installer or announces changes in the package layout. Features of buildpkg.py The essential work performed by buildpkg.py for a new package named is to: - create a package directory .pkg/ plus its entire layout (subdirectories) - add a file .pkg/.info containing the installation options - add "bill of materials" file .pkg/.bom (using "mkbom") - add the source root directory as .pkg/.pax.gz - add optional resources to .pkg/Contents/Resources - add a file .pkg/.sizes indicating the total size of the installed package Among the optional resource files there are the Welcome, ReadMe and License files (either in .txt, .rtf, .rtfd/ or .html format) shown during installation. These can also be inside localization bundles, like English.lproj/ or German.lproj/). Other resources will mostly be installation scripts (e.g. preflight, .{pre,post}-{upgrade,install}, postflight, and probably others as well) called by the installer at the appropriate moment. buildpkg.py does not try to be smart enough to filter only the relevant files from the resources you indicate. It simply copies them into the package. Command-line usage The intended use of the buildpkg.py script is both, as a command-line tool and as a Python module which can be imported in other Python programs (with "distutils" being the most obvious Python candidate package). - Call the program without any options/arguments darwin% python buildpkg.py No argument given! Usage: buildpkg.py [] [] with arguments: (mandatory) root: the package root folder (optional) resources: the package resources folder and options: (mandatory) opts1: --Title --Version --Description (optional) opts2: (with default values) --Application: 'NO' --DefaultLocation: '/' --DeleteWarning: '' --DisableStop: 'NO' --Diskname: '(null)' --InstallFat: 'NO' --InstallOnly: 'NO' --NeedsAuthorization: 'NO' --Relocatable: 'YES' --Required: 'NO' --RequiresReboot: 'NO' --UseUserMask: 'YES' - Call the program with only the mandatory options and arguments darwin% python buildpkg.py --Title=readline-4.3 --Version=4.3\ --Description="GNU Readline Library" /my/space/readline-4.3 - As above but with additional option --RequiresReboot YES darwin% python buildpkg.py --Title=readline-4.3 --Version=4.3\ --Description="GNU Readline Library" --RequiresReboot YES\ /my/space/readline-4.3 - As above but with additional resources directory argument (will copy its content into /my/space/readline-4.3/pkg/Contents/Resources/) darwin% python buildpkg.py --Title=readline-4.3 --Version=4.3\ --Description="GNU Readline Library" --RequiresReboot YES\ /my/space/readline-4.3 /my/space/resources/readline/ Usage as a Python module - Create a readline-4.3.pkg from a folder containing the GNU Readline library sources: pm = PackageMaker("readline-4.3", "4.3", "GNU Readline Library") pm.build("/my/space/readline-4.3") - As above but with additional option --RequiresReboot YES pm = PackageMaker("readline-4.3", "4.3", "GNU Readline Library") pm.build("/my/space/readline-4.3", RequiresReboot="YES") - As above but with additional resources directory argument (will copy its content into /my/space/readline-4.3/pkg/Contents/Resources/) pm = PackageMaker("readline-4.3", "4.3", "GNU Readline Library") pm.build("/my/space/readline-4.3", "/my/space/resources/readline/") - As above but with additional single resource file pm = PackageMaker("readline-4.3", "4.3", "GNU Readline Library") pm.build("/my/space/readline-4.3", "/my/space/resources/readline/") pm.addResource("/my/space/resources/scripts/postflight") Notes Although the package layout is adopted from pre-10.2 versions of OS X, the Installer.app on 10.2 should have no problems in dealing with the resulting packages. For the time being this layout seems sufficient enough, so there is no point in dealing with creating packages that can be installed only by the new Installer.app! Given that such packages have a directory "shape", they are not suited for downloading over the internet. Hence, they need to be flattened somehow into a single binary file. This could be a .tar.gz, which is possible but unusual on OS X (for reasons not described here). On OS X there is a dedicated format named "Disk Image" with extension .dmg which represents an archive that can be directly mounted into the filesystem. Creating such disk images without GUI tools is somewhat of a black art (6). For now you should be able to run buildpkg.py even on a non-OS X system and get something similar to a package, but without the real archive (needs pax) and bom files (needs mkbom) inside! This is only for providing a chance for testing to folks without OS X. Beware of the multi-package features of Installer.app (which are not yet supported here) that can potentially screw-up your installation and are discussed in two articles on Stepwise (4). At least for versions of OS X prior to 10.2 this seemed to be a concern. Todo - test pre-process and post-process scripts - handle meta-packages (extension .mpkg) - integrate into distutils - use alternatives for "pax" (2) Links (1) Brian Hill's PackageMaker: http://personalpages.tds.net/~brian_hill/packagemaker.html (2) Chris Roberts's OSXPM: http://www.osxgnu.org/ (3) BSD License: http://opensource.org/licenses/bsd-license.php (4) Stepwise articles: http://www.stepwise.com/Articles/Technical/Packages/InstallerWoes.html http://www.stepwise.com/Articles/Technical/Packages/InstallerOnX.html (5) http://developer.apple.com/techpubs/macosx/Essentials/SystemOverview/InstallIntegrate/Installing__Application.html http://developer.apple.com/techpubs/macosx/ReleaseNotes/PackageMaker.html (6) Andrew Stone's notes on creating disk images: http://www.stone.com/The_Cocoa_Files/Just_Ship_it_.html (7) Open Source Initiative, BSD License: http://opensource.org/licenses/bsd-license.php Dinu C. Gherman, gherman@europemail.com September 2002