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.
Related
I am new to MAC App development and working on project which uses Zoom Mac SDK but that SDK doesn't support archive with Xcode so I need to make archive with other tools suggested by zoom support center. As per their reply app can be archived with pkgbuild/pkgutil/productbuild but I don't know the exact steps to create archive/pkg/dmg file for my Mac App.
Also please let me know which file extension I need to create for downloading my app from website for users.
I am using "Developer ID Application" and "Developer ID Installer" certificates for sign my build but don't know how to create build without using Xcode because with Xcode I am getting error for third party framework as "code object is not signed at all".
Appreciated your great help.
First, you need pkgbuild AND productbuild, to do something productive.
Here you specify a root folder, identifier, version, install-location, signage, and post-install scripts.
For example:
pkgbuild --root "${ROOTFOLDER}" \
--identifier "${IDENTIFIER}" \
--version ${VERSION} \
--install-location "/" \
--sign "${IDENTITY}" \
--scripts '${SCRIPT}' \
"${PKGNAME}.pkg"
In your ${ROOTFOLDER}, you can control files/folders like it would be on your local machine after "/".
For example, if you want to put "xy.app" into /Applications, you would create inside your ${ROOTFOLDER} a "Applications" folder and put xy.app into that. When you install the package, inside your "/Applications" folder on your machine, there will be xy.app.
You can also copy files to /Library or whatever, just by creating the folder inside your specified rootfolder.
When you want any .pkg / .dmg or .sdk's installed, you would create a scripts folder that you specify under --scripts ${SCRIPTSFOLDER}, and inside there you create a "postinstall" file.
The postinstall file will contain stuff that will be execute with your package, for example installing another .pkg or .sdk, that will be inside your ${ROOTFOLDER}.
So put multiple .pkg' files into ${ROOTFOLDER}/Packages for example. On your root folder, the /Packages folder will be created. Means, in your postinstall you can say:
sudo installer -pkg /Packages/anotherPackageOrApp.pkg target /
After you've done that, you got a simple package. However, you don't really want only that.
With productbuild, you can create a distribution file: it includes all the configuration of the product archive, including a product license, product README file, the list of component packages, constraints (such as minimum OS version).
Go ahead and do the following:
productbuild --synthesize --package "${PKGNAME}.pkg" distribution.dist
Now that you got your distribution.dist out of your package, you can edit it however you want.
Build it back together:
productbuild --distribution distribution.dist --scripts "${SCRIPTS}" --sign "${IDENTITY}" --package-path "${PKGNAME}.pkg" --resources . --version ${VERSION} "${PKGNAME}_New.pkg"
Now you got your final signed Package. Containing the locations for your .sdk's, .pkg's and .dmg's that can be installed via the postinstall file, or just copied to a directory on the machine that the pkg will be installed on.
Greets
I need to make Mac OS app installer, which also installs other third-party package.
When trying to add it via productbuild --synthesize, it tells "ThirdPartyPackage.pkg is a product archive, not a component package".
So, how should I correctly insert third-party product installer into my installer?
You can actually split up a "product archive" into its component packages by using:
pkgutil --expand your_product_archive.pkg some_folder
This will create the some_folder directory with the contents of the product archive.
If the third-party archive is reliably available for download, then you could have a post (or pre) install script use curl to fetch it (probably into /tmp) and installer to install it.
Error handling with curl is a little janky, since it tends to report no error for lots of errors: 404 not found, domain not resolved, etc. You could just assume it worked, and count on installer to error out if there's not an actual package where you tried to download it.
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).
My Java application has a launcher which is a .app and a helper app which is bundled with it.
I am trying to make .pkg installer with a background image using the following commands:
pkgbuild --root "./Temp" --identifier "com.company.id" --install-location "/Applications" --sign "signature" "temp.pkg"
productbuild --package-path "temp.pkg" --distribution "./Distribution.xml" --package-path "./Temp" --resources "./Resources" --sign "installer signature" "$FINAL_PKG"
When I look in the directory at ./Temp both of the .app folders are there and when I deconstruct the .pkg with:
pkgutil --expand "temp.pkg" "temp"
I see the .app folders but sometimes one of the .app folders do not show up when it is installed from the pkg. They always seem to show up the first time it is installed, but on machines where the application is installed and deleted many times (like on test and development machines) one of the .app folders will eventually not show up. I am wondering what could be going on here?
Initially we had the helper app inside a separate directory as the main app and in this case, the helper app would sometimes not get installed but the main app always would be. Next, we tried putting the helper app inside of the main app and then this worked the first time but the next time I tried to to install from the installer the main app wasn't there!
I have had roughly the same problem. It appears that the OS X installer uses information about already installed packages and application bundles in order to decide where and if to install new packages. As a result, sometimes my installer did not install any files whatsoever, and sometimes it just overwrote the .app bundle in my build tree. Not necessarily the one used to build the installer, but any .app bundle that OS X had found. In order to get the installer to install the files properly I had to do two things:
Tell OS X to forget about the installed package
sudo pkgutil --forget <package id> Not sure if this is needed for you nor in my case, but it is probably a good idea anyway.
Delete all existing .app bundles for the app. If I didn't do this, the existing app bundle was overwritten on install instead of the app being placed in /Applications. Maybe there is a way to prevent this while building the installer package, but I haven't found it.
If you can you should probably try to make your application self contained so that users can install it by just drag and dropping it into /Applications. Of course, this only works if you don't need to install anything outside of your .app bundle.
If you don't want to (or can't expect other users to) hunt down and delete all existing copies of the app as described by villintehaspam, or just really need the app not to be relocated, you can provide a Component Property List file with BundleIsRelocatable set to false.
An easy way to create a valid version of the plist file is with pkgbuild --analyze; then you can edit the one property and use the file. E.g.:
pkgbuild --root myapp.root --analyze myapp.plist
/usr/libexec/PlistBuddy -c 'set :Dict:BundleIsRelocatable false' myapp.plist
pkgbuild --root myapp.root --component-plist myapp.plist [...other options...] myapp.pkg
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.