Issue with Audio Unit on 10.11

As @jpo described, I made a special build using XCode 13 of one of my plugins for a customer running 10.12 and removed the CoreAudioKit.framework manually in XCode from the AU/AAX/VST/VST3 targets before building. Using otool -l I made sure CoreAudioKit is no longer referenced by the binaries. This solved the issue and the plugin now loads again in Logic and Pro Tools.

Now to make this practical I’d need a way to integrate this step into my build process. I’m still using ProJucer and I don’t think CoreAudioKit can be avoided with that at all. Unfortunately, building a plugin seems to require adding hosting support as well which then leads to the inclusion of CoreAudioKit. It would be nice if ProJucer was a bit smarter when it comes to selecting frameworks to link to. It also keeps adding DiscBurning.framework even if the burning flags are disabled.

With CMake this would probably be easy, but migrating my old stuff without creating new problems seems tricky at best. So what I’m looking for now is a non-manual way to disable linking to CoreAudioKit.framework after resaving from ProJucer.

There seem to be two command-line friendly projects that could potentially do it: Xcodeproj (Ruby) and pbxproj (Python). Unfortunately, both seem to be a bit lacking when it comes to documentation and maybe there’s an easier way somehow? Does anyone have an idea?

1 Like

I tested that workaround as well, manually removing CoreAudioKit in XCode, and it appears to work for the plugin targets. If I were to integrate this with my build scripts, I’d probably just mess with the xcode project files directly, if they’re text based and self explanatory enough… I’m a bit reluctant embracing such a solution though…

The funny thing is that people who reported the issue to me was saying that the standalone version was working.

The .pbxproj files are tricky to change because the frameworks are identified using hex references which need to be fetched first. The libs I linked would do that for us, but unfortunately I’m bad at both Ruby and Python.

Standalone working comes as no surprise… otherwise all executables using CoreAudioKit would be broken - which means all AU hosts. That’s clearly not the case.

So this means that the solution would be to only link with CoreAudioKit in the standalone version which will work as well.
Maybe the JUCE guys can just push this modification ?

1 Like

I think so, but there are exceptions. If a plugin wants to host AUs or use Bluetooth-Midi, it still needs to link to CoreAudioKit.framework. Maybe if the linkage to CoreAudioKit was “optional” and not “required”, things would work automagically… but I can’t test that without having a 10.12 machine myself.

Anyway the real fix should come from Apple IMHO. They pushed the broken file onto 10.11 and 10.12 machines since March and reverting the file to an older version isn’t trivial. In the meantime if there was a simple script solution… I’d use that to help customers running older OSes.

Yeah I’ve seen my standalone test builds working too, which pointed me in the general direction of “must be something super specific with dylibs”. So I conclude it’s something todo with the way dylibs are loaded on macos, whereas the standalone probably only starts crashing if it tries to access any of the broken/missing stuff…

D’oh I’m sorry I accidentally removed my original post. To sum up… I ended up patching ProJucer for the time being so the frameworks are not added for plugin targets until Apple releases an update to fix the underlying issue. None of my plugins require CoreAudioKit and doing it this way was much easier than trying to remove the framework again. None of the 3rd party Xcode project modification utilities I found seemed to be able to do that without issues.

Here is my brute-force ProJucer patch if anyone is interested. It could be done smarter by not removing CoreAudioKit in case JUCE_PLUGINHOST_AU is set, but I don’t need that. Should the plugin still require something from CoreAudioKit, linking will fail.

diff --git a/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_Xcode.h b/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_Xcode.h
index 7723b12ccb3a34ab4da5d1d454ffabd7824a3b2e..660989310f391b03255ca3476f05978a5cc3a788 100644
--- a/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_Xcode.h
+++ b/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_Xcode.h
@@ -2309,8 +2309,25 @@ private:
 
                 target->addBuildPhase ("PBXSourcesBuildPhase", sourceFiles);
 
-                if (! projectType.isStaticLibrary() && target->type != XcodeTarget::SharedCodeTarget)
+                if (! projectType.isStaticLibrary() && target->type != XcodeTarget::SharedCodeTarget) {
+                    switch (target->type) {
+                    case XcodeTarget::VSTPlugIn:
+                    case XcodeTarget::VST3PlugIn:
+                    case XcodeTarget::AudioUnitPlugIn:
+                    case XcodeTarget::AAXPlugIn:
+                        {
+                            std::string frameworksToStrip[] = {"CoreAudioKit"};
+                            for (auto& framework : frameworksToStrip) {
+                                auto idx = target->frameworkNames.indexOf(framework.c_str());
+                                if (idx >= 0) {
+                                    target->frameworkNames.remove(idx);
+                                    target->frameworkIDs.remove(idx);
+                                }
+                            }
+                        } break;
+                    }
                     target->addBuildPhase ("PBXFrameworksBuildPhase", target->frameworkIDs);
+                }
             }
 
             target->addShellScriptBuildPhase ("Post-build script", getPostBuildScript());
6 Likes

Thanks for sharing!

Can this be safely integrated into JUCE?. 10.11./10.12 has not been supported by Apple for a long time (10.12 last patch is from 2019) , wonder how a solution from apple would look like (if it comes)

Seeing that the problematic file found its way onto 10.11 and 10.12 machine this March hopefully the same mechanism could be used again to make it work again. As far as I know it was part of a mobile device compatibility update.

If someone with a machine that is affected could check whether weak-linking is enough to solve the problem (instead of removing the framework), then maybe that could be a universally compatible solution. Juce7 just added support for weak-linking - initially I thought it’s to solve this issue.

@pflugshaupt I already tried declaring the dependencies as “optional”, but to no avail, dylibs fail to load.

Some more investigation:

In the meantime, I was able to do a direct comparison with a pretty mint 10.12 install vs. an equally mint 10.13 install. So, both systems just received a small hand of automatic “latest patch level” updates.

A look at the appstore update history told me that the “broken” update happened on the 10.12 machine, in particular I suspect “Device Support Upgrade” and “iTunes Device Support Upgrade”. These updates were not installed on the 10.13 machine.

I also compared what Macdependency showed: (GitHub - kwin/macdependency: MacDependency shows all dependent libraries and frameworks of a given executable, dynamic library or framework on Mac OS X).
In case of the broken system, as we already knew, the MobileDevice Framework has a modified date of March 9 2022.
On the “unpatched” 10.13 system, the same library has a modification date of May 24 2019. Afaik that makes sense in combination with the “end of support” that is valid for these systems.

Just sharing the specifics because it strengthens the hypothesis that SOME update compatibility check fails on systems 10.11 and 10.12, leading to the installation of something that relies on way newer OS features. Like trying to force-install directx 12 on a Windows Vista machine :smiley:

If you open affected dynlibs with Macdependency and navigate into the CoreAudioKit/MobileDevice dependency tree, it will show errors if the system is affected.
Here’s a screenshot, just for completeness sake:

@chkn as far as solutions go, Apple would probably need to deliver an update to affected systems that rolls back these libraries to their last working state, because as far as I know there is no mechanism in macOS that allows users to uninstall such patches… broken system stays broken.

If I understood right. Those update are required for newer iPhone to work on those older system.

But why not on 10.13 then?

I wonder if it actually works as intended, because according to the dependency tool, they’re broken.

Thanks for sharing your code snippet, I integrated it with my stuff, it turned out to be the easiest solution and it’s not that problematic to maintai :slight_smile:
It seems to solve the issue just fine for the time being!
Rolling out betas to affected customers. Hopefully back to developing features now :wink:
Cheers

1 Like

Could the Juce guys update cmake with this ?

1 Like

We’re going to wait for a response from Apple before we add complexity to the build system. Optional dependencies like this cause real pain integrating with package managers, and we’d like to avoid it if possible.

2 Likes

Did anyone try the following workaround:

sudo install_name_tool -change /System/Library/Frameworks/CoreAudioKit.framework/Versions/A/CoreAudioKit /System/Library/Frameworks/Cocoa.framework/Versions/A/Cocoa <PLUGIN>/Contents/MacOS/<EXEC>
sudo codesign -fs <MY-IDENTITY> <PLUGIN>

It replaces the CoreAudioKit load command with an extra Cocoa load command, which is equivalent to removing CoreAudioKit
I don’t have a test machine next to me atm to check it but I did verify on my macOS 12 laptop that it doesn’t break the plugins.

4 Likes

@yairadix - nice find! I didn’t know about install_name_tool and this seems like a nice workaround to temporarily include in build scripts without having to do anything nasty - but unfortunately I do not have a 10.11/10.12 machine to test this.

2 Likes

Btw, we’ve tried to reproduce this on our systems and it seems Apple stopped pushing the faulty version?

We weren’t able to get the problematic update on our systems.

1 Like

I guess the update is/was only downloaded once iTunes was updated and a newer iOS device had been connected. Maybe Apple has excluded that update from 10.11 and 10.12.
The big question remains whether customers who already received the faulty update can somehow undo the damage in a simple way we can explain to them.