macospkgbuildproductbuild

Mac installer overwrites ALL copies of file


I’m having an odd issue where my installer properly overwrites the previously installed app, but then overwrites the app in my build directory.

My installer build looks like this:

mkdir /tmp/foo
cp -R ~/Projects/MyApp/Builds/MacOSX/build/Release/MyApp.app /tmp/foo
pkgbuild  --quiet  --analyze --root /tmp/foo/  MyApp.plist

pkgbuild  --quiet --root /tmp/foo/  \
 --component-plist MyApp.plist \
 --identifier com.mycompany.myapp \
 --version $VERSION \
 --install-location "/Applications" \
 MyApp.pkg

productbuild  --quiet --distribution "./Distribution.xml" \
 --package-path "./" --resources "./Resources" \
 --sign "Developer ID Installer: My LLC" "MyApp Installer.pkg"

Now, this works…it installs the app in the /Applications folder as I’d expect. But I was noticing some issues with my next Xcode build. After some investigating, I noticed that my build folder looked like this after the Xcode build and before running the installer:

drwxr-xr-x@ 3 me staff 96 Jul 11 23:15 My.app

…and like this, AFTER running the installer:

drwxr-xr-x 3 root wheel 96 Jul 11 23:44 My.app

Somehow, the owner of my app had changed. I double checked everything and didn’t see anything that touched my build folder. But then I checked the installer log and found this mysterious line:

PackageKit: Applications/MyApp.app relocated to 
  Users/me/Projects/MyApp/Builds/MacOSX/build/Release/MyApp.app

After some googling, others have speculated that the installer overwrites ANY copy of the app it finds anywhere on the drive…not just the one in the folder you tell it. It makes some sense…if I delete that copy of my app in the build folder, the installer doesn’t create a new one. It only overwrites it if it’s there.

While this isn’t a huge problem, it’s somewhat problematic as it changes the owner of the file which prevents the next build from working.

Has anyone else run into this issue? Is there some option for the installer to NOT overwrite EVERY copy of the installed app?


Solution

  • The Installer has a few features that allow it to locate application bundles that have moved in the file system. Inside your compiled .pkg, have a look at the PackageInfo and Distribution files, and see if you see any <locator> tags. The <locator> tag is defined at the link below, and is one of the main ways to enable this sort of thing.

    https://developer.apple.com/library/archive/documentation/DeveloperTools/Reference/DistributionDefinitionRef/Chapters/Distribution_XML_Ref.html#//apple_ref/doc/uid/TP40005370-CH100-SW15

    Another possibility is that you may have a <bundle> element with the search property set, as documented here:

    https://developer.apple.com/library/archive/documentation/DeveloperTools/Reference/DistributionDefinitionRef/Chapters/Distribution_XML_Ref.html#//apple_ref/doc/uid/TP40005370-CH100-SW36

    If you want to easily inspect the internal structure of your compiled package, you can use Pacifist to do that fairly easily. (disclaimer: I'm the author of Pacifist)