Makefile for Mac OS X instead of XCode / integrating JUCE code with existing project

Hi everyone,

I’m trying to use JUCE as a module for an existing project written in C++. I basically want to use JUCE mainly for getting audio input / reading audio files and feeding it to the existing project. Using Projucer, however, makes it so that it sets up a new XCode project for the snippet of code I’m trying to write. This makes it a little challenging when trying to integrate these parts together without having to move the existing project to XCode.

I tried using the Linux Makefile Projucer generates to see if that would be easier, but the makefile has JUCE_CPPFLAGS that specify linux, which I believe causes it to not work on OS X (For example, it might say sys/prctrl.h isn’t available, since it’s only on linux).

Is there a way to compile JUCE code without xcode, or an easy way to use code written with JUCE in other applications? Thanks.

This thread might be interesting to you: How does the Audiounit/VST file actually get created on OSX?
The main takeaway is that you can see all compiler invocations directly in Xcode.

Another place where you can look is FRUT (I’m the author). It enables building JUCE projects using CMake, which then supports many build systems (including Unix Makefiles and Ninja on macOS). You can build one of the JUCE examples using FRUT and look at the Makefile generated by CMake (though it might not be super readable), or you can study the code of Reprojucer.cmake (the central part of FRUT) to understand what are the main settings.

Finally, feel free to ask me any questions about building JUCE, I’ve got a lot of experience now.

1 Like

Hi McMartin! Thanks for the reply.

I tried using FRUT on one of the JUCE demo files (ProcessingAudioInput). I followed the instructions on the readme, and ran it with -G “XCode”, but I’m getting the following error:

CMake Error at /Users/youngchk/FRUT/prefix/FRUT/cmake/Reprojucer.cmake:368 (message):

…/ProcessingAudioInputTutorial/juce_audio_basics/
is not a valid JUCE module
Call Stack (most recent call first):
CMakeLists.txt:43 (jucer_project_module)

It seems that it’s not able to properly recognize the module files, and I’m not sure why. Thanks for the help.

I guess the .jucer you converted has its modules configured with “Use global path”. When you ran Jucer2Reprojucer on that .jucer file you should have seen an output similar to:

error: The module juce_audio_basics requires a global path. You should pass the JUCE modules global path using --juce-modules.
warning: Couldn't a find module header for juce_audio_basics module at "C:\Users\Alain\Downloads\ZIPs\ProcessingAudioInputTutorial\juce_audio_basics\juce_audio_basics.h".

(11 times, once per module).

The error message tells you than you should pass --juce-modules when calling Jucer2Reprojucer, like this:

$ ~/dev/FRUT/prefix/FRUT/bin/Jucer2Reprojucer ProcessingAudioInputTutorial.jucer ~/dev/FRUT/prefix/FRUT/cmake/Reprojucer.cmake --juce-modules ~/dev/JUCE/modules/
C:\Users\Alain\Downloads\ZIPs\ProcessingAudioInputTutorial\CMakeLists.txt has been successfully generated.

And then you should be good to go!

Hey, McMartin. I’m the one who opened the AU/VST on OSX thread you linked to. I’ve since accomplished my similar goal of building JUCE plugins (but with bazel instead of cmake), but I figure if you went down the nasty road of figuring all of the same stuff out, I’d love to pick your brain a bit. I don’t know cmake at all, so forgive me if these questions are obvious after poking through your repo.

  1. How do you keep up with changes in JUCE/OSX? Or does your project only support recent versions of OSX that build JUCE somewhere near HEAD?

  2. For making audio plugins, how do you generate the resource files that are inside of the .au package? Do you also just mock the commands in the xcode project?

  3. Do you support windows? How different is that? I currently only have OSX and linux working and I found OSX to be sufficiently harder to figure out than Linux. Not having developed for Windows before, I’m likely to not even try.

Good to know there’s someone else that’s been down this road, I didn’t exactly enjoy the ride (though I like the destination provided it doesn’t take too much maintenance).

I definitely recommend reading a bit about CMake before diving into FRUT. FRUT does allow you to build JUCE projects without having to type any CMake code, but you at least need to understand the high level concepts (meta build system vs. build system, configure phase vs. generate phase vs. build phase, etc.).

Now let’s answer your questions:

  1. FRUT supports all JUCE versions from 4.2.0 to the latest develop branch. There are some features from newer versions of Projucer that FRUT doesn’t support, so you could argue that some older versions of JUCE are “better supported” than newer ones. If you want to get the same behavior as Projucer version X.Y.Z, you can simply specify it (see https://github.com/McMartin/FRUT/blob/master/generated/JUCE-5.2.1/examples/HelloWorld/CMakeLists.txt#L23 for instance), otherwise FRUT will reproduce the behavior of the latest Projucer. This allows using an older version of the JUCE code (for instance 5.2.1), while using more recent features from Projucer (for instance, specifying Extra Custom Frameworks on macOS, which was added in Projucer 5.4.0).

  2. FRUT makes the build system (make, Ninja, etc.) call the Rez compiler “manually”. See https://github.com/McMartin/FRUT/blob/master/cmake/Reprojucer.cmake#L4528.

  3. FRUT supports Linux, macOS and Windows. For users of FRUT, it roughly works the same on all 3 platforms. For me, it means dealing with a lot of if/elseif in the code of FRUT. I’m mainly working on Windows, so feel free to ask any question.

I hope this helps. If you have more questions about FRUT, I invite you to create issues on the GitHub repository (https://github.com/McMartin/FRUT/issues) or to send me direct messages.

HI @McMartin,

Do you know whats causing this error?

FRUTerror

=====================================================================

[cmake] CMake Error at FRUT/prefix/FRUT/cmake/Reprojucer.cmake:1654 (message):
[cmake] You must call jucer_export_target(“Visual Studio 2019”) before calling
[cmake] jucer_project_end().
[cmake] Call Stack (most recent call first):
[cmake] CMakeLists.txt:170 (jucer_project_end)
[cmake]
[cmake]
[cmake] CMake Error at FRUT/prefix/FRUT/cmake/Reprojucer.cmake:1654 (message):
[cmake] You must call jucer_export_target(“Visual Studio 2019”) before calling
[cmake] jucer_project_end().
[cmake] Call Stack (most recent call first):
[cmake] CMakeLists.txt:170 (jucer_project_end)
[cmake]
[cmake]
[cmake] Configuring incomplete, errors occurred!
[cmake] See also “C:/Users/George Phillips/Desktop/testproj/build/CMakeFiles/CMakeOutput.log”.
[cmake] Configuring incomplete, errors occurred!
[cmake] See also “C:/Users/George Phillips/Desktop/testproj/build/CMakeFiles/CMakeOutput.log”.
[cms-driver] Error during CMake configure: [cmake-server] Configuration failed.

Hi @GeorgePhillips
Thanks for giving a try to FRUT!

I think you are getting this error because you are using Visual Studio 2019, but your project is not configured to support the “Visual Studio 2019” exporter.

Reprojucer.cmake is based on the same concept of “exporter” (also known as “export target”) as Projucer. There are currently 10 exporters and Reprojucer.cmake supports 8 of them (see FRUT’s README for a bit more information). Projucer is capable of generating IDE and build system files for all configured exporters at the same time, but Reprojucer.cmake can’t do that, since that’s not how CMake works. When configuring your project with CMake, Reprojucer.cmake figures out which exporter should be used, based on the toolchain.

In the example you showed, Reprojucer.cmake figured out that the exporter to use is “Visual Studio 2019”, however your project doesn’t seem to be configured to use that exporter.

In your CMakeLists.txt file, there is a call to the juce_project_end function (around the end of the file normally). Before that call, you must have a call to the jucer_export_target function for each exporter that you want to support in your project. For instance, if you want to support “Xcode (MacOSX)”, “Visual Studio 2017”, “Visual Studio 2019”, and “Linux Makefile”, then you need exactly 4 calls to jucer_export_target. You also need to call jucer_export_target_configuration for each exporter and for each build configuration (usually Debug and Release) that you want to use in your project.

I hope it’s a bit clearer to you now. I will try to make the error message easier to understand, especially by mentioning that the issue is coming from the user’s CMakeLists.txt file.

Maybe I will also add the possibility to select the exporter to use when calling CMake (something like cmake -DJUCER_EXPORTER="Visual Studio 2017") instead of letting Reprojucer.cmake figuring it out.

1 Like