I work on a macOS application that functions as a daemon. To test it, I:
-
Compile executables.
-
Use
pkgbuild
andproductbuild
to build an application bundle. -
Use
codesign
andnotarytool
to sign and notarize the app. -
Install the app with
/usr/sbin/installer -target LocalSystem -pkg ...
. This often overwrites the previous version of the app.
Sometimes, the installation fails at the postinstall
stage, when it can not find the application's install directory. We explicitly check for this error in our script:
if ! [ -d "$APP_INSTALL_DIR"/Contents ]; then
echo "directory ${APP_INSTALL_DIR}/Contents is missing"
exit 1
fi
This is unexpected!
Even worse, some of our customers have occasionally seen the same issue!
We use a postinstall script in order to install files into the /Library/LaunchDaemons
and /Library/ LaunchAgents
directories, and start the agent with launchctl bootstrap
.
Our preinstall
script makes sure that the previous version of our application is fully uninstalled (so there is no confusion), and we wonder if that is part of the problem.
While researching this error, I ran across a discussion of a similar issue on Stackoverflow: <https:// stackoverflow.com/questions/19283889>. One of the commenters there wrote:
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.
On the other hand, the man page for pkgutil
says not to use --forget
from an installer:
Discard all receipt data about package-id, but do not touch the installed files. DO NOT use this command from an installer package script to fix broken package design.
What is the correct approach to fix this problem?