CMake unity builds support

Hi,

I’m looking to use CMake unity builds, but CMake by default includes all C++ source files in the unity builds and I want to exclude the JUCE CPPs to avoid build issues.

Now I’ve been able to do this using the following CMake

# Recursively finds all JUCE .cpp files and exclude them from Unity builds
        file(GLOB_RECURSE JUCE_MODULE_CPP_FILES "${JUCE_SOURCE_DIR}/modules/juce_*/*.cpp" "${JUCE_SOURCE_DIR}/modules/juce_*/*.mm" "${JUCE_SOURCE_DIR}/modules/juce_*/*.c")
        foreach(src IN LISTS JUCE_MODULE_CPP_FILES)
                set_source_files_properties(${src} PROPERTIES SKIP_UNITY_BUILD_INCLUSION ON)
        endforeach()

I was wondering whether something like this (or better) could be added to the JUCE CMake code so that CMake unity builds would work out of the box in new projects?

Why do you want to use CMake’s unity builds feature in a juce project? The Juce module system is basically a hand-rolled unity build anyway.

1 Like

I think it is a nice way to locally improve build speeds for large projects and to profile whether manually designed unity builds would provide a build speed improvement

IIRC trying to compile JUCE with unity builds results in lots of multiple definition errors and the like. The modules are designed to be compiled each into their own TU and so in CMake you typically want to exclude any JUCE sources from being wrangled with the CMake unity build system.

I would also caution against going straight to unity builds as a solution to improve build times and first look at things like sccache. If you’re able to cache compiled TU’s then you actually want more translation units and not fewer, which unity builds will give you.

Being a bit pedantic here, but one big advantage of CMake’s unity build are that you can specify how many source files are wrangled into a single TU. See UNITY_BUILD_BATCH_SIZE — CMake 4.3.2 Documentation. You can even set it to 0 to try to compile the whole project into a single TU.

Yes absolutely, I think it would’ve been way better to design the juce modules as “regular” C++ source code that’s less opinionated about the build process, and let the build system add logic like unity builds. But hindsight is 20/20 I guess.

2 Likes

Yes exactly, that is the reason my feature request, that JUCE would automatically set SKIP_UNITY_BUILD_INCLUSION for all linked JUCE modules.

Thanks for the suggestion. We’ve made this change on the juce9 preview branch to automatically exclude JUCE sources from CMake unity builds:

Source file properties are scoped to the current directory, so this functionality has to piggyback on other JUCE functions that tend to be called when creating JUCE-dependent targets, specifically the juce_add_* family of functions. If you’re not using juce_add_*, then you’ll still need to set the SKIP_UNITY_BUILD_INCLUSION source file property on the relevant files yourself.

4 Likes