JUCE and macOS 11 / ARM

It’s the project based on the latest JUCE 4 branch tip. I’ve cherry picked commit from this thread for ARM compatibility and it builds using the latest Xcode 12 beta without any issues. I’ve deliberately removed Intel architecture (x86_64) from project and left only arm64, just to avoid any confusion.

I’ve build Juce demo plugin as well … waiting for feedback…

Good news is that Juce demo plugin is loading properly as ARM64.

Bad news is that i still can’t make my plugin work as ARM64 … the same issue as before. With the latest Big Sur beta 1 update, now even AUVAL doesn’t work - getting "FATAL ERROR: OpenAComponent: result -1 : 0xFFFFFFFF.

Everything is working perfectly on Intel. Currently i am trying to find the differences in Xcode project between Juce demo and my plugin. So far no success, checked build settings several times.

Are you sure it’s not just a problem with the AU cache?

Try rebooting and repeat the auval…

Not juce related, but anybody know how to cross compile on macOS? I’m trying to write a build script that will compile both a arm64 and x86_64 library no matter the host architecture the script is run on. I am working with nghttp2, but have other libraries to do as well, like curl.

To build the x86_64 version my script looks like this:

autoreconf -i
./configure --enable-lib-only --build x86_64
make install

After building I test the architecture of the binary:

% lipo -info ./lib/.libs/libnghttp2.a         
Non-fat file: ./lib/.libs/libnghttp2.a is architecture: arm64

What an I doing wrong, why is the architecture not correct?

I use to do that
./configure CFLAGS="-arch x86_64" --build=x86_64

You probably want to set isysroot and mmacosx-version-min as well

Looks like i’ve succeeded … after i’ve compared Juce Demo plugin and my plugin Xcode settings and remedied the differences, now my plugin loads as ARM64 successfully. Changed many small things in Xcode, so i can’t really remember what exactly i did :slight_smile: I will have to compare Xcode files once again.


It would be very useful to work out what the differences were and which made it work if you have the time, you know for sure somebody is going to stumble on this in a few months and ask you what you did, right?


There is a chance that AUVAL -1 error and Logic’s arm64e false detection happened because of mistakes when building my AU plugin component - i experienced unpredicted behaviour on Intel also, if project folder was not properly cleaned before building for another architecture. Now i always manually delete existing plugin and Xcode build folder, then clean project folder in Xcode and then build.

Regarding Xcode settings, i changed some minor things which i personally don’t believe could cause misbehaviour on arm64 - for example, setting compiler language standard and library to “compiler-default”, setting deployment target to 11.0 etc.

On the other side, I removed OpenGL and QTKit frameworks from Xcode project, which i believe could be important.

Currently i don’t have arm machine in front of me, so i can’t really try preferences one by one and find the problematic one(s). Will do when possible.


VERY IMPORTANT: How is JUCE handling this ARM specific behaviour?

I can see objc_msgSendSuper is still using variadic parameters (…) which could lead to some unexpected behaviour.

1 Like

Finally getting around to taking a look at making some arm builds due as the need for them is now impending.

I’m struggling to get a plugin to load which initialises a lot of stuff in prepareToPlay (loading some wavs and initialising some impulse responses). In arm logic this plugin loads happily when all of this is commented out. When the code is all compiled the plugins don’t load - the plugin has an empty window and no sound processing occurs. When some of the stuff being initialised is commented out (not all), the plugin manages to load with a portion of the audio parameters exposed in logic’s basic plugin window and processes audio but doesn’t load the editor.

I’m presuming there is something going on with memory capping? A bit odd considering the plugin loads fine on an iPhone 5s…

Any thoughts on why I may be having this problem would be greatly appreciated!

It sounds more like some threading/concurrency issue.
Did you try running with thread sanitizer? I don’t yet have access to an ARM machine. but it might even just be Logic threading is different or order execution that shows up more easily on that specific setup.

1 Like

You may like to see what happens for that plugin with the Reaper build that supports Apple Si, check for the arm64_notarized.dmg builds here.


So apologies if this is a naive question, but for those of us who don’t have an ARM mac to test on, and haven’t upgraded our development machines to Big Sur, what steps should we take to make our VST/AU plugins Big Sur/ARM compatible?

  • Does one need an ARM machine to build on?
  • Can we build a plugin as an Intel/ARM universal binary, or will we need to release a separate ARM version?
  • Will our existing plugins still work in Big Sur when it is installed on an Intel mac?
  • No. Xcode 12.2 can build ARM and Intel binaries independent of what platform it’s running on.
  • Yes, you can build Universal Binaries.
  • Yes

I did a bit of testing this morning, it looks like DAWs compiled for ARM will load Intel AU plugins. This does not appear to be the case for VST (unless the DAW implements a bridge)

If your plugins are all C++ it should be as simple as getting latest Xcode and JUCE and recompiling.


That’s a relief! Thank you for the quick reply.

No. How did you test? Are you sure your host was compiled for ARM?

You can look in Activity Monitor and it’ll list if it’s an Intel or ARM process.

If I’m using Juce6/Cmake, is there anything special I need to do to compile for Apple Silicon?

A few quick questions, I’ve been able to successfully compile Universal Binaries of our plugins with the latest XCode and JUCE. They work fine on my Intel Mac and I’ll be testing on an ARM Mac when it arrives this week.

I’ve heard some stirrings elsewhere online however about Universal Binaries not working on macOS versions earlier than 10.12 Sierra. Something with the code signatures not being recognized? I don’t really have a way to test this for myself but I was wondering if anyone had run into that here and potentially found a solution for it. I also wanted to be sure that I could build an Intel-only binary in XCode 12.2 to avoid running into this problem if need be. If it is indeed a UB issue that should work, but I’m just curious if anyone with more insight could confirm that it really is just UB and not the Big Sur SDK/something else.

Lastly, I couldn’t get AAX versions to build as UBs due to errors in the SDK. I’m assuming Avid will be releasing a new version once they have a UB version of Pro Tools but I was just curious if anyone had seen anything about a timeline for when that might be. I came up empty handed after some googling and searching through their forums.


I guess you want to create universal binary builds and not Apple Silicon builds, only, right? It works super straightforward. You have to define CMAKE_OSX_ARCHITECTURES to x86_64;arm64 either at configuration time by passing it to CMake via command line or at the top of your CMakeListst.txt to enable universal binary builds.

You can also enable/disable it on a per-target base by setting the property like set_target_properties(myTarget PROPERTIES OSX_ARCHITECTURES x86_64;arm64). This comes in handy especially if you want to disable universal binary builds for a specific target, e.g. the AAX version which isn’t ARM ready yet as @benschmitz mentioned above (and probably won’t be for some time if Avid acts like they usually do :wink: ). To build all your formats as universal binary but AAX for x86_64 only, set the CMAKE_OSX_ARCHITECTURES as described above and then exclude the AAX target like set_target_properties(myPlugin_AAX PROPERTIES OSX_ARCHITECTURES x86_64) and it will happily only output a x86_64 version of it.

Keep in mind that any third party lib you link against has to be a universal binary library as well. In case it’s not straightforward to build some dependency as universal binary, you might want to build an arm64 and x86_64 version separately and use the lipo tool to merge them. A propos lipo, this tool is also useful to check the architecture some library or executable has been built for with lipo -archs path/to/my/lib.a