After an unfortunate couple days of faffing about with building our app on macOS, it turns out that it was JUCE at fault all along!
The generated Xcode project was crashing our app on app start because code signing was totally broken. Error messages like this were popping up (note that I changed the message’s formatting):
'[...]/Builds/MacOSX/build/Debug/Orba 2.app/Contents/Frameworks/libavcodec.dylib'
not valid for use in process: mapped file has no cdhash, completely unsigned?
Code has to be at least ad-hoc signed.),
Rolling back to before this faulty commit here allows us to build+run successfully:
I’m getting the same here. App won’t start at all on my m1 mac, using xcode 14.2. Trying to downgrade to xcode 14.0 did not work, but is working for my colleague who is on an intel mac with xcode 14.0
I just finished testing the various combinations of code signing identity and development team ID settings in the Projucer to no avail: the app won’t run, as in it crashes immediately on app start.
OTOH, manually editing the Xcode project to have the correct code signing identity along with applying --deep as “other code signing flag” works: the app runs fine from here on in.
I’m reluctant to just revert this change, as it’s necessary to run console apps built with Xcode 14.1+:
It would be helpful to know how your project is configured. Have you specified a code-signing identity and development team ID, or are you leaving those fields blank? Are you manually signing the app, e.g. in a post-build step? How is libavcodec.dylib added to the bundle, and during which part of the build?
After investigating, it looks like previously (with an empty signing identity), Xcode would bypass the signing step for GUI apps, so the resulting app would be linker-signed:
When we completely remove the CODE_SIGN_IDENTITY key from the xcproj, Xcode adds a codesign step, and signs with the identity "-". The resulting binary has the following characteristics:
My suspicion is that adding a framework to the bundle after the signing step will invalidate the bundle signature, but without detailed information about your build process, it’s difficult to say exactly what’s going wrong.
If I create a completely new app in Xcode, setting the development team to “None” in the wizard, then the generated project has no CODE_SIGN_IDENTITY key, but the product will still be automatically signed with an identity of “-”. I think it’s probably a good idea for JUCE projects to mirror this approach, so my preference would be to find a way of ensuring that any embedded frameworks are also correctly signed.
Using --deep is probably not a good idea:
It looks to me like Xcode defaults to resigning embedded frameworks during the build. Assuming the framework was specified as an “embedded framework” in the Projucer, I would expect this to work automatically.
First, thanks for the detailed write-up as always. For context, we’re dealing with a legacy codebase that sorely needs more project work than time we have.
The Development Team ID is blank.
The Code-Signing Identity is blank.
We manually codesign when creating internal and external builds, using an external script.
For the libavcodec.dylib question, we’ve a bit of a kludge happening right now in the Projucer project:
Based on your remarks, it seems we’re either not signing the frameworks before consuming them, relying on bad or outdated build behaviours, or both? In any case, I’ll park this for now because it’s entirely possible that we rip out these libraries for the time being (as we’re not using them) which may inherently fix the issue.