Anybody using llvm 19 (or not-AppleClang) on macOS?

I know this probably isn’t supported but I thought I’d ask here in case anyone else has gone through the process.

If install LLVM19 via homebrew and then specify its use like this:

export PATH="/opt/homebrew/opt/llvm/bin:$PATH"
export CC=clang
export CXX=clang++

I can’t compile juce due to this error:

-- The C compiler identification is Clang 19.1.6
-- The CXX compiler identification is Clang 19.1.6
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - failed
-- Check for working C compiler: /opt/homebrew/opt/llvm/bin/clang
-- Check for working C compiler: /opt/homebrew/opt/llvm/bin/clang - broken
CMake Error at /opt/homebrew/share/cmake/Modules/CMakeTestCCompiler.cmake:67 (message):
  The C compiler

    "/opt/homebrew/opt/llvm/bin/clang"

  is not able to compile a simple test program.

  It fails with the following output:

    Change Dir: '/Users/dave/Documents/Developement/Code/Tracktion/waveform/modules/tracktion_engine/modules/juce/cmake-clang/CMakeFiles/CMakeScratch/TryCompile-L1RBV9'
    
    Run Build Command(s): /opt/homebrew/bin/cmake -E env VERBOSE=1 /usr/bin/make -f Makefile cmTC_7c9b0/fast
    /Applications/Xcode.app/Contents/Developer/usr/bin/make  -f CMakeFiles/cmTC_7c9b0.dir/build.make CMakeFiles/cmTC_7c9b0.dir/build
    Building C object CMakeFiles/cmTC_7c9b0.dir/testCCompiler.c.o
    /opt/homebrew/opt/llvm/bin/clang   -arch arm64 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX15.2.sdk -mmacosx-version-min=15.1 -MD -MT CMakeFiles/cmTC_7c9b0.dir/testCCompiler.c.o -MF CMakeFiles/cmTC_7c9b0.dir/testCCompiler.c.o.d -o CMakeFiles/cmTC_7c9b0.dir/testCCompiler.c.o -c /Users/dave/Documents/Developement/Code/Tracktion/waveform/modules/tracktion_engine/modules/juce/cmake-clang/CMakeFiles/CMakeScratch/TryCompile-L1RBV9/testCCompiler.c
    Linking C executable cmTC_7c9b0
    /opt/homebrew/bin/cmake -E cmake_link_script CMakeFiles/cmTC_7c9b0.dir/link.txt --verbose=1
    ld: library 'System' not found
    clang: error: linker command failed with exit code 1 (use -v to see invocation)
    /opt/homebrew/opt/llvm/bin/clang  -arch arm64 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX15.2.sdk -mmacosx-version-min=15.1 -Wl,-search_paths_first -Wl,-headerpad_max_install_names CMakeFiles/cmTC_7c9b0.dir/testCCompiler.c.o -o cmTC_7c9b0
    make[1]: *** [cmTC_7c9b0] Error 1
    make: *** [cmTC_7c9b0/fast] Error 2

The compiler seems to be detected correctly and the -isysroot is the correct location, but it can’t seem to find the System library folder.
After reading other similar posts (Has anyone used anything other than AppleClang, e.g., LLVM Clang, to build a JUCE project on macOS?) it seems I’m doing things the correct way.

Anyone else seen this problem?

1 Like

A while back I ran into a similar problem, not sure if the fix is applicable to you, but check it out here:

In general, its probably a better idea to put new toolchains in a VM, though. Apple are quite disrespectful when it comes to interacting with the developer toolchain ecosystem maintained by the brew folks …

But if you put them in a VM (which would be a massive PITA), you’d still need to install Xcode for the frameworks wouldn’t you? And then presumably you’re back to square one here?

VM’s: Its a pick-your-poison adventure.

Yes, its a massive PITA, when you first do it - but once you’ve got a fleet of VM’s, each at the appropriate version of MacOS for the task, with the requisite devtools in place, you’re beyond the PITA point and into development sanity. Its really the only way to maintain a hygienic, non-catastrophic build/development environment, and you probably should start get into segmenting the toolchains with this methodology, anyway. Things are getting thorny with Apple vis-a-vis tooling, so the sooner you do this the better prepared you will be, for their idiocy. (e.g. “Brand new M4 Macs can’t run older MacOS VM’s”, oh my!)

Mixing devtools with Apple and homebrew is a bigger PITA, however - especially when one or the other decides to pull the rug out from you with a change to framework policies or deprecating tools you’re relying on.

But, its a good practice, anyway, to not cram your development workstation with experimental tooling.

That said, you probably just want to get back to work … did you try the brew prefix hack, to get the System framework linking sorted again?

This is a big adventure, but you’re not alone. Those of us hanging back on the path a bit are going to learn from your battle… :wink:

EDIT:

you’d still need to install Xcode for the frameworks wouldn’t you?

Yes, but the point is that you don’t do this in your development machine, you do it in a VM that is there to isolate you from the hell you’ll be in when XCode decides to stop supporting the frameworks/system-versions you’re attempting to build for …

I know that my suggestion is a lot more work than you might be prepared for - but, having done it, I can tell you that my development workflow/sanity-levels have benefited greatly from being able to safepoint a VM and return to it when things go awry, backup-style …

FWIW I started my JUCE journey while also learning modern C++, and I used homebrew LLVM to try to work with the latest C++ features in my JUCE project. It started out ok with LLVM17, but by the time I upgraded to LLVM18 I was running into a lot of problems like this. I am not a C++ expert so I kept getting stuck and distracted with these sorts of problems. It was extremely frustrating and causing me to not make progress on my audio plugin project. I realized I had coupled learning JUCE to learning modern C++, but I didn’t actually use most of the newest C++ features in my JUCE project. So I went back to using the C++ compiler that comes with XCode for JUCE, and things have gone much smoother since then. I still use homebrew and LLVM to work my way through books on modern C++. This feels like the right balance to me.

Regarding VMs, another thing to consider is if you are planning to make a commercial product, I’d want the build system fully automated and decoupled from my personal computing devices. So, if I lost my MacBook or whatever, I could easily keep producing the product. My go-to for this sort of thing is GitHub Actions, and I regularly borrow ideas from this project to automate things: GitHub - sudara/pamplejuce: A JUCE audio plugin template. JUCE 8, Catch2, Pluginval, macOS notarization, Azure Trusted Signing, Github Actions

The reason I’m bringing that up is: if you can sort out how to get it all working on a “cloud build system” with LLVM19, then you should be in a pretty good position. Of course, if you can’t build locally, that’s definitely going to be a major pain point, so you’ll ultimately have to figure out both (if you want an automated build system). It’s something else to keep in mind. Maybe something like Docker could help?

I haven’t looked into this at all yet, but might be worth a look: GitHub - eyalamirmusic/JuceDocker: Compile JUCE using Docker

Now I’m thinking: it sure would be nice if JUCE provided official VM images for building projects, which worked out-of-the-box with the very modern C++ toolchains on every supported platform. Like some publicly published Docker images that you could pull for use locally and/or on a cloud build system to build JUCE apps for Windows, macOS, and Linux. We (the JUCE developer community) could maintain such things too, which I guess is what I just linked to.

So I went back to using the C++ compiler that comes with XCode for JUCE, and things have gone much smoother since then.

Yes, I think this is the crux of it. Most common compiler, for the platform, kind of has to be maintained in a stasis.

A UTM image of MacOS Ventura/Sonoma/Sequoia is how I approach this tooling issue - but I don’t, at the moment, have need for LLVM19, personally.

Github Actions … official out-of-the-box VM’s …

Well, I just have a box for each platform, in a VM. A cross-platform toolchain can share code between the VM’s, to do builds, notarizations, etc.

This includes Windows, Linux, MacOS builds.

Actually I think this thread is diverging into a “lets use great new C++ feature” and “strategies for deployment” conundrum.

To get back to the subject: its an interesting question, why use llvm19 (/not-AppleClang), are there fun things to do with it? ")

Yeah, I’m curious what OP wants to use it for.

The main reason I did it is I bought recently published books to learn C++, and they used a lot of newer features that won’t compile with Apple Clang. I had much better luck with LLVM.

Coming from other languages, I found std::println() and the new string formatting features much more pleasant to deal with than cout, especially just playing around and trying out language features. I still can’t get this to work in the latest version of macOS and XCode.

IIRC, I encountered features with ranges and views and filters that can make data transformation algorithms very succinct, which wasn’t working at all with Apple Clang. Maybe it was this kind of stuff: std::ranges::views::transform, std::ranges::transform_view - cppreference.com

For doing multithreaded programming, jthread is pretty nice, but last time I checked this only worked on the newer Microsoft C++ compiler and wasn’t supported in LLVM either. I think they’ve made some progress since then.

At this time, LLVM Clang has made a lot of progress on core C++26 features: C++ compiler support - cppreference.com

I would probably get good use out of “placeholder variables with no name”.

It was actually a bug report from a Tracktion Engine user who was using LLVM 19. I tried to replicate but could never get it to work.

Although I’m keen to always use the latest language features, I can live without most of them for a bit.

I was looking forward a bit to LLVM 20 when it gains RTSan. That will probably miss Apple Clang 2025.

And looking forward, it would be really nice to use some of C++26 such as std::execution and reflection. The latter will definitely be a game changer.

2 Likes

Ah, all very good points.

Given Apple’s devotion to their silicon, it seems incongruous to me that they would not at least have plans to get C++26’s std::execution features into CLang at some point - this is definitely something to keep an eye on, so thanks for pointing this out - since this has the potential for making it easier to leverage modern hardware and optimize performance, particularly for multi-core processors or GPUs.

I’d also like not-AppleClang support for JUCE, because I want to use RealtimeSanitizer — Clang 22.0.0git documentation

From what I can tell it’s basically impossible if you’re using any of Apple’s frameworks. They’re pretty heavily stitched in to AppleClang at this point I think.

Happy to be proven wrong though but I gave up a long time ago.

1 Like

For what it’s worth, I discovered a way to use RTSan on macOS: Improved developer experience and where to put the precompiled runtime library · Issue #47 · realtime-sanitizer/rtsan · GitHub