CMake macOS CommandlineTools support

Here is a little patch to make CMake build on macOS with just the CommandlineTools installed but no Xcode.

diff --git a/extras/Build/CMake/JUCEUtils.cmake b/extras/Build/CMake/JUCEUtils.cmake
index 4bf7206e5..0002899e4 100644
--- a/extras/Build/CMake/JUCEUtils.cmake
+++ b/extras/Build/CMake/JUCEUtils.cmake
@@ -413,8 +413,8 @@ function(_juce_add_au_resource_fork shared_code_target au_target)
             -I "${secret_au_resource_dir}"
             -I "/System/Library/Frameworks/CoreServices.framework/Frameworks/CarbonCore.framework/Versions/A/Headers"
             -I "/Applications/Xcode.app/Contents/Developer/Extras/CoreAudio/AudioUnits/AUPublic/AUBase"
-            -I "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks/AudioUnit.framework/Headers"
-            -isysroot "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk"
+            -I "${CMAKE_OSX_SYSROOT}/System/Library/Frameworks/AudioUnit.framework/Headers    "
+            -isysroot "${CMAKE_OSX_SYSROOT}"
             "${au_rez_sources}"
             -useDF
             -o "${au_rez_output}"

Best,
Andreas

1 Like

I made a similar change the other day which calls xcode-select -p to find the active developer directory. I think this may be a better solution than using the CMAKE_OSX_SYSROOT as we can locate the AUBase folder relative to the developer directory too (it looks like in your patch, the AUBase path still goes through Xcode.app).

Could you try checking out the current develop branch and see whether it works for you?

Sure, i will have a look

Your change does only work with Xcode installed still, unfortunately.

${CMAKE_OSX_SYSROOT} resolves to “/Library/Developer/CommandLineTools/SDKs/MacOSX11.1.sdk” when setting the dev path (via xcode-select) to /Library/Developer/CommandLineTools

and to

“/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.1.sdk” when setting it to “/Applications/Xcode.app/Contents/Developer”.

So the actual SDK sub path (after xcode-select -p) is different, and CMake does the logic.

Thanks for raising this. I’ve taken another look, and I think we can probably just remove the AUBase include path. I don’t think it’s doing anything at the moment (find /Applications/Xcode.app -name AUBase returns no results). Then, we can just use CMAKE_OSX_SYSROOT for the other two paths, which works properly for both commandline-only installs and full Xcode installs.

1 Like

I’ve been trying to upgrade from JUCE 6.0.5 to 6.1.2, but running into some issues. It appears that a variant of the patch suggested above has been applied since 6.0.5.

After upgrading I’m getting Rez AUResources.r lookup errors again. 6.0.5 appears to have worked, because it was still searching for things in the (manually installed) Extras/CoreAudio path. Those paths have been since been removed in favor for the CMAKE_OSX_SYSROOT-based path.

I’ve tried a few things such as re-installing command line utilities and Xcode, but I can’t seem to get a build to succeed. What sort of setup is everyone running where they are able to build AUs cleanly with CMake? Do I need to adjust the deployment target in some way?

Apologies for the silly questions. I’d be grateful for any suggestions.

What’s the actual error that you’re seeing? AUResources.r is provided in the JUCE repo itself, and is included by juce_audio_plugin_client_AU.r. I’d expect AUResources.r to be located automatically because it exists in the same directory as juce_audio_plugin_client_AU.r.

If AUResources.r cannot be found for some reason, perhaps its include directory needs to be specified explicitly. You could try adding -I /path/to/juce/modules/juce_audio_plugin_client to the rez command at JUCEUtils.cmake line 193 to see whether that helps. If it does, I’ll add that to the main repo.

Thanks for the reply, @reuk.

I’d expect the same thing, and this has always confused me why it’s not able to locate it. I’ve seen its inclusion in the project cited several times on the forums over the years, but I’ve always had to use the Extras way to get my builds to pass.

Here’s the error I’m getting after adding -I "/usr/local/include/JUCE-6.1.2/modules/juce_audio_plugin_client/" to the Rez command argument list. This is the same error I get without it, too:

failed to find AUResources/AUResources.r
/usr/local/include/JUCE-6.1.2/modules/juce_audio_plugin_client/juce_audio_plugin_client_AU.r:50: ### Rez - noErr (0) during open of "AUResources.r".
Fatal Error!
/usr/local/include/JUCE-6.1.2/modules/juce_audio_plugin_client/juce_audio_plugin_client_AU.r:50: ### Rez - Fatal Error, can't recover.
AUResources.r: ### Rez - Since errors occurred, /Users/bbuddin/Code/quark/build/darwin/QUARK/QUARK_artefacts/JuceLibraryCode/QUARK_AU/secret/QUARK.rsrc's resource fork was not completely updated.
gmake[3]: *** [QUARK/CMakeFiles/QUARK_AU.dir/build.make:78: QUARK/QUARK_artefacts/JuceLibraryCode/QUARK_AU/secret/QUARK.rsrc] Error 3
gmake[3]: *** Deleting file 'QUARK/QUARK_artefacts/JuceLibraryCode/QUARK_AU/secret/QUARK.rsrc'

I’m going to keep poking around here to see if other adjustments can get things to pass.

Here’s the full invocation there, just in case:

cd /Users/bbuddin/Code/quark/build/darwin/QUARK && /usr/bin/xcrun Rez -d "ppc_\$ppc" -d "i386_\$i386" -d "ppc64_\$ppc64" -d "x86_64_\$x86_64" -d "arm64_\$arm64" -I /Users/bbuddin/Code/quark/build/darwin/QUARK/QUARK_artefacts/JuceLibraryCode/QUARK_AU/secret -I /System/Library/Frameworks/CoreServices.framework/Frameworks/CarbonCore.framework/Versions/A/Headers -I /usr/local/include/JUCE-6.1.2/modules/juce_audio_plugin_client -I /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX12.0.sdk/System/Library/Frameworks/AudioUnit.framework/Headers -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX12.0.sdk /usr/local/include/JUCE-6.1.2/modules/juce_audio_plugin_client/juce_audio_plugin_client_AU.r -useDF -o /Users/bbuddin/Code/quark/build/darwin/QUARK/QUARK_artefacts/JuceLibraryCode/QUARK_AU/secret/QUARK.rsrc

Annoyingly I can’t reproduce the issue here so I can’t do much to track down the issue.

Some thoughts/suggestions:

  • Perhaps using <> rather than "" will cause Rez to use different include-searching rules. You could try surrounding the AUResources.r include with <> instead of "" and see whether that changes anything.
  • juce_audio_plugin_client_AU.r currently uses dos line-endings, although the AUResources.r uses unix line endings. It’s a stretch, but perhaps some versions of Rez don’t like dos endings… You could try converting this file to use unix endings instead and see whether that helps.
    vim +':wq ++ff=unix' modules/juce_audio_plugin_client/juce_audio_plugin_client_AU.r
    
  • I find it strange that Rez is complaining about being unable to find AUResources/AUResources.r, when the include path in the juce .r file just mentions the filename directly. I’m not sure where the outer directory name is coming from. If you search your copy of the repo (maybe your build tree too), can you find AUResources/AUResources.r mentioned anywhere?

Okay, this is wild: I replaced the names of the two includes of AUResources.r in that file with AUResources_A.r and AUResources_B.r and here’s the new error:

failed to find AUResources_A/AUResources_A.r
/usr/local/include/JUCE-6.1.2/modules/juce_audio_plugin_client/juce_audio_plugin_client_AU.r:50: ### Rez - noErr (0) during open of "AUResources_A.r".
Fatal Error!

So I guess it’s not coming from some other part of the build-tree. It’s something in my setup that’s causing that prefixing to happen. I’ve referenced other file types like “.h” and it doesn’t seem to do the prefixing—only for the “.r” files.

:exploding_head:

That’s interesting. What file does it try to look for if you explicitly include AUResources/AUResources.r in the juce .r? If you put the include path back to just AUResources.r but then move the AUResources.r file into a nested directory named AUResources, does the call to Rez succeed?

No luck there. However, I did manage to get it to compile by switching #include "AUResources.r" with #include <AudioUnit.r>. I took a look at how iPlug2 handles things and found that they include that instead of AUResources.r over there:

The AU builds and loads just fine with this change.

Looking back through the forums I found someone doing something similar a few years back:

Figured it out. It was a permissions issue. I wasn’t installing the CMake library to a place in my user directory. Instead I was just accepting the default installation prefix which was /usr/local. Unfortunately this caused everything to be installed as root. I was never running my builds as root so I guess Rez couldn’t open the file.

I’m installing JUCE to someplace in my user directory now, defining JUCE_DIR for CMake and everything is humming along with 6.1.2!

Thanks so much for your time and effort in helping me out, @reuk.

2 Likes

Nice, that’s good to know. Thanks for explaining how you fixed the issue!