I'm trying to get an app notarized, which fails with this error:
The signature of the binary is invalid.
However, locally checking the signature does succeed:
$ codesign -vvv --deep --strict TheApp.app
[…]
TheApp.app: valid on disk
TheApp.app: satisfies its Designated Requirement
Performing this check on every single item in the app's MacOS folder also succeeds.
Context: embedded prebuilt binaries
Now, the app has something unusual about it: it embeds prebuilt binaries, arranged in various nested folders. So, the app bundle's MacOS folder actually contains another folder with a whole tree of executables and libraries:
Removing these (before building) does fix the notarization issue, but obviously I'd like to keep them in. I did my best to properly sign these items:
- At build time, they're copied into the product by a Copy Files phase (but not signed), then signed by a script phase
- That signing uses the same signing identity as the running Xcode build, and enables the hardened runtime
- The app builds and runs correctly, even as a release build
- The app has runtime hardening and app sandbox enabled
How should I go about diagnosing the notarization issue?
At the top of Placing Content in a Bundle you’ll find this warning:
If you put content in the wrong location, you may encounter hard-to-debug code signing and distribution problems. These problems aren’t always immediately obvious. For example, when building a Mac app, incorrectly placed code might work during day-to-day development, but might cause problems during notarization.
And this is exactly what’s come to pass )-:
The best way to solve this problem is to follow the rules in Placing Content in a Bundle. However, that can be tricky when dealing with code structures from other platforms. We talk about this in Embedding nonstandard code structures in a bundle. I also go into the rpath stuff in more more detail in the Dynamic Library Standard Setup for Apps forums post.
If you’re unable to completely rework your structure, see the Use symlinks for gnarly edge cases section of that doc.
Finally, it’s possible to bend these rules a bit, but the more you bend the more problems you run into. For example, code signing and notarisation are both quite happy for you to put code in an area reserved for data. However, it looks like you’re using Xcode and it’s more persnickety. That’s one of the advantages of the symlink approach. As far as Xcode is concerned, you’re just embedding:
-
A bunch of pre-built binaries into a location reserved for executables
-
A bunch of pre-built libraries into a location reserved for libraries
-
A weird directory hierarchy, that happens to include a lot of symlinks, into an area reserved for data
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"