Mac installer overwriting ALL copies of app


#1

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?


#2

This is a rather annoying feature of macOS package installer (at least on development machines). You can however disable relocation by passing “–no-relocate” flag to pkgbuild.


#3

I couldn’t find a --no-relocate flag.

It turns out that

pkgbuild --quiet --analyze --root /tmp/foo/ MyApp.plist

…creates this key:

<key>BundleIsRelocatable</key>
<true/>

…so I modified my build script to this:

pkgbuild  --quiet  --analyze --root /tmp/foo/  MyApp.plist
plutil -replace BundleIsRelocatable -bool NO MyApp.plist

And all is well.