To target an older intel mac do I need an old mac to build it?

The docs dont explain this much.
I have been trying to find old computers to build plugins for people running logic on an i5 processor under old versions of osx.
I developed it on an m2 macbook pro and it runs fine but lots of grief trying to target older systems what am I supposed to do ? Is this documented anywhere ?

If you use Projucer, you use Xcode, and so on Xcode, you just have to target to what you want.

Hope it helps :wink:

1 Like

To be fair, this is a can of worms that isn’t easily consumed by just using the latest XCode on M2. You can do that if you’re really only targeting that latest MacOS versions for x86 and M-series CPU’s - but if you have requirements beyond that scope, its not enough.

The absolute best practice is to have an M-series Mac alongside an x86-series Mac, and on both of those systems maintain VM’s for the earlier versions of MacOS/XCode that you will be targetting for each architecture. You’ll be best served by building VM’s for the specific MacOS versions, and having the relevant XCode tooling onboard, segregated in a VM ‘sandbox’, rather than having multiple XCode versions on the same machine - this is a disaster waiting to happen.

In short, if you want to do this properly and save yourself infinite headaches, build a VM for each of your release target MacOS versions, and keep them free of each others toolchains.

1 Like

The problem with using older Xcode and macOS SDK versions is that those SDKs are unaware of APIs/features added in later SDK versions. This means that programs built with old SDKs will always use old APIs.

If you instead build against a newer SDK version, then the SDK is aware of both new and old APIs, and can switch between them at runtime depending on the version of the OS running the program.

A concrete example of this is MIDI 2.0 support in macOS. If you build against an old SDK, your program cannot support MIDI 2.0 because that API doesn’t exist in the old SDK. If you instead build against a new SDK, then the same binary will use the old MIDI API on old macOS versions, but can also take advantage of MIDI 2.0 when running on newer versions.

Therefore, my recommendation would be to build using the newest macOS SDK and Xcode version, but to set an older deployment target.

1 Like

That’s some good reasoning, but even still I would recommend that the builds be performed within the context of the VM, so that for development you can switch XCode versions, but for builds will always have stability. This is based on endless hassles trying to keep different XCode versions happily co-existing - its not feasible. Use a VM, even for the latest releases! :stuck_out_tongue:

1 Like

I think you need to specify a bit better how to old the targeted Mac should be.

Generally, you have to set a deployment target that matches the oldest macOS version you want to target and create a universal binary build like @kob-j recommended. This creates a plugin or application that runs just fine on old machines down to the specified deployment target. As a CMake user I’m not completely sure where you find the deployment target setting in the Projucer, but I’m pretty sure that it’s there (in CMake it is CMAKE_OSX_DEPLOYMENT_TARGET).

The range of supported deployment targets might vary depending on the Xcode version that you are using. For an example, we currently are on Xcode 14.0.1 which supports deployment targets down to 10.9. I think more recent Xcode versions raised the minimum possible deployment target a bit and that is probably why @austrianaudioJV recommends keeping older Xcode versions in a VM, do I get that right?

It’s always a tradeoff to decide what should be the oldest macOS version supported by your products. You might notice that there are standard library features that are not supported on older deployment targets, some examples that annoyed us recently are e.g. aligned operator new which is not available prior to 10.14 or some member functions of std::variant that are not available prior to 10.13 or std::counting_semaphore which requires at least 10.15 if I remember that right. So depending on what C++ features you need you might not be completely free to chose any deployment target supported by your Xcode version.

1 Like

Yup, thats the thing: newer XCode versions mean newer “oldest deployment targets”, so this is why we keep multiple XCode versions around in various VM’s designed for the purpose.

1 Like

Even though not officially supported, I’m building for 10.9 with the latest Xcode. If you want to support older than that, you’ll need to find an older mac.

1 Like

How did you set up the latest Xcode to be able to build for 10.9? I don’t think there’s much reason to go further back than 10.9, but IIRC the latest Xcode does not have 10.9 as an available deployment target.

1 Like

The Deployment Target drop down indeed stops at 10.13, but it is a text field.
I just typed 10.9 into it and it builds.
But I haven’t tried if it actually runs on an old mac.


Ah I see, I’ll give that a shot.

I am trying targeting 10.13 in xcode like this

xcode looks like this.
It builds and works fine on my M2 and passes the validation like this

seanwayland@Air-de-sean ~ % auval -strict -v aumu SWws SWsw
* * PASS

I will see if I can load this one on older machines

I understand not wanting to continually update your docs to keep up with XCODE but this sort of info in the JUCE docs would save a bit of time and perhaps all this chatter.

I’m doing the same thing, I only have VMs going back to 10.10 but I believe I have users on 10.9.

I did need to specify XCODE_ATTRIBUTE_CLANG_LINK_OBJC_RUNTIME or else it wouldn’t link, starting with Xcode 14.


users using various OSX 13 versions on intel macs can run the standalone app.
The plugin is found by auval and passes validation but is not found by logic.
Should I start a seperate thread in this forum for that problem ?
Amazing to me that using XCODE it is apple’s own software that is so finicky.

If the standalone runs and the plugin passes auval you can be pretty sure that everything deployment target related worked as expected, so the remaining issue is probably something completely different. If might be related to caching behavior of Logic that does not recognize that the plugin has been updated.

Sometimes bugs in your code also only show up on a certain platform so if your plugin crashes on an Intel Mac you probably have an undiscovered bug in your code. In order to track down issues like that it’s indeed best to have an Intel Mac with all the developer tools that can be used to test and debug the plugin in the native environment.

Maybe it’s a good idea to start a new thread for that specific problem

What virtualization software do you use/recommend? Are there issues with the iLoks needed for signing the AAX plug-ins?