Upgrading JUCE breaks Projucer + Xcode Projects + code signing

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:

Directly reverting those changes with the tip of develop makes everything work here just fine.

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

1 Like

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.

It really seems the Projucer is broken here.

Hi folks from the JUCE team – please fix this. This breaks our builds and has wasted enough of our time.

Can someone please have a look? Reverting the commit here Projucer: Fix build of default projects in Xcode 14.1 · juce-framework/JUCE@8d0afb6 · GitHub fixes the issue.

1 Like

Affecting me as well using Xcode 14.0 and 14.1 on an M2 Mac. Manually editing the Xcode project also allows the app to start for me.

FYI, related: https://forum.juce.com/t/did-something-change-related-to-code-signing-in-6-1-3-projucer/49166/14

1 Like

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:

CodeDirectory v=20400 size=236163 flags=0x20002(adhoc,linker-signed) hashes=7377+0 location=embedded
Info.plist=not bound
TeamIdentifier=not set
Sealed Resources=none
Internal requirements=none

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:

CodeDirectory v=20400 size=236396 flags=0x2(adhoc) hashes=7377+7 location=embedded
Info.plist entries=20
TeamIdentifier=not set
Sealed Resources version=2 rules=13 files=1
Internal requirements count=0 size=12

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.

  1. The Development Team ID is blank.
  2. The Code-Signing Identity is blank.
  3. 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.