No Projucer Required!
Over the past few months, we’ve been working to add standalone, idiomatic CMake support to JUCE. This idea has been around for a while (see this forum post from 2017), and was a popular suggestion in the 2019 JUCE User Survey, especially amongst our Pro users. This new native CMake support will effectively deprecate the beta CLion exporter in the Projucer.
Building with CMake can provide a few advantages over the current Projucer-based approach, including:
- wider IDE/tooling integration, as most tools now have some kind of CMake support,
- more flexible options for modularising code, beyond the JUCE module format,
- simpler CI configuration, as the Projucer no longer needs to be built at the beginning of each pipeline,
- easier integration with other projects that already build with CMake, and
- allowing distribution of JUCE through CMake-based package managers, like Vcpkg and Hunter, making it faster to get started on new projects. (Coming soon; we’ll author packages once we’re happy that the CMake API is stable after a bit of real-world usage. Please don’t submit packages on our behalf!)
The predominant design goal of JUCE’s CMake support is to allow users to write build configs that looks like ‘normal’ CMake. Modules, executables, plugins, and binary data are just normal CMake targets, and including JUCE in a project is as simple as find_package(juce CONFIG REQUIRED)
or add_subdirectory(JUCE)
. All of the example projects in the JUCE repo have been given new CMakeLists that you can browse to see how the support looks in practice. In order to support a completely Projucerless workflow, we’ve also added some CMake-based project templates to the repo at examples/CMake
that you can copy, modify, and build immediately.
One side-effect of trying to make our CMake support idiomatic is that we require some very recent CMake features in order to seamlessly handle the complexities of a JUCE project. At the moment we require version 3.12 for apps, and 3.15 for plugins. If your system package manager doesn’t include a sufficiently recent CMake, you should be able to get the most recent version from the official downloads page.
Adding a whole new build system to JUCE gave us a chance to reevaluate the structure of a JUCE project; in particular, the role of the AppConfig.h and JuceHeader.h. The AppConfig.h was originally designed to hold global compile definitions for a project, but CMake allows us to specify compile definitions on a target very easily, even on a per-configuration basis. This build-system-level support obviates the need for a dedicated AppConfig.h, so this file is not generated when using CMake-based builds. Similarly, the role of the JuceHeader.h is to include the AppConfig.h before all of a target’s module headers, but this becomes less useful in the absence of the AppConfig. For this reason, we’ve made the JuceHeader ‘opt-in’, and it can be enabled using juce_generate_juce_header(<target>)
. Finally, it should go without saying that all intermediate build files have been moved to the CMake build tree, so there’s no more need for the JuceLibraryCode
folder in the source tree.
CMake support is not limited to juce modules; you can also build your personal modules with CMake by registering them with juce_add_modules
. We’ve also added a helper to generate a static library containing binary assets, juce_add_binary_data
. One request from the community was to make it easier to package binary assets alongside code in a custom module. Using this new CMake support, it should be possible to add a binary data target with juce_add_binary_data(module_data SOURCES foo.txt bar.wav ...)
, and to introduce a dependency between the module and its binary data using target_link_libraries(my_module INTERFACE module_data)
.
Replicating all of the Projucer’s functionality is a massive undertaking, and we wanted to share our work with you now to check that we’re heading in the right direction. For this reason, the initial release doesn’t include full support for Android targets. We may look at adding better mobile support in the future, depending on the priorities of our CMake users. In the meantime, the Projucer isn’t going anywhere, and we will continue to support mobile projects in that way.
This being a very early release, it’s likely that our documentation might lack a little detail, and there may be certain use-cases that we didn’t manage to test thoroughly. If you find something missing that you’d like to see, please let us know and we’ll try to add it. Also, if you find any neat tricks that you can accomplish with CMake, please don’t hesitate to post them on the forum so that the community can benefit.
We hope you enjoy using this feature, and look forward to seeing what you create with it!