JUCE CMake Linux Configuration Clarification

When I use JUCE CMake with macOS or Windows it generates multiple configurations for debug/release/debwithrelinfo etc. that I can switch between, build and run.

Am I right in thinking that these aren’t handled the same way in Makefiles and that you have to generate the makefile with the desired configuration and then simply build the makefile with make?


$ cmake -B <build_dir> -DCMAKE_BUILD_TYPE=RelWithDebInfo
$ cd <build_dir>
$ make

I don’t think my Linux builds are being optimised correctly and I’m not sure what magic JUCE is doing behind the scenes.
I think I have to add

    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=sandybridge")
endif ()

in my CMakeLists.txt file to enable decent codegen (I think this enables sse and avx instructions) and then make sure I generate either Release or RelWithDebInfo via cmake to turn on optimsation.

Does this sound about right?

I’m using following on linux (exact the same command i’m also using on OSX):

cmake -B cmake-build -DCMAKE_PREFIX_PATH=../juce/install -DCMAKE_BUILD_TYPE=Release

cmake --build cmake-build --config Release

I would expect that it geberates an optimized release build. Isn’t that the case?

If my understanding is correct using -DCMAKE_BUILD_TYPE=Release will create an optimised build.
(I was using RelWithDebInfo as I’m profiling with VTune).

If using Release/RelWithDebInfo though, I’m not sure what architecture gets used. If you don’t manually specify sse/avx flags, the architecture will determine which instructions to use.

On x86_64, I think sandybridge enables sse1-4.2 and avx.
Using haswell will also get you avx2.

So I just want to know the canonical way of doing this really and if JUCE sets the architecture in juceaide at all (the generated makefiles are a bit of a maze and don’t correlate to the PJ generated ones at all really)?

CMake’s makefile generator is single-configuration rather than multi-configuration. The desired config should be specified with CMAKE_BUILD_TYPE when initially invoking CMake.

By default, JUCE’s CMake support doesn’t mess with the default optimisation flags that CMake picks. Configuring in “Release” mode will use whatever flags CMake would normally use for a Release build. If you link your target with juce_recommended_config_flags, then the target will build with -O3 in “Release” mode, and -g -O0 in “Debug” mode. Linking with juce_recommended_lto_flags will enable LTO on the target.

You can build with cmake --build cmake-build-folder --target mytarget --verbose to see the actual commands that CMake ends up running. This might help to verify that the build is using the expected flags.

No, JUCE’s CMake support doesn’t pass any arch-specific flags. I don’t think “plain” CMake will do this either. To enable specific optimisations, setting CMAKE_CXX_FLAGS or target_compile_options is probably the way to go.

Looking at some Projucer-generated makefiles, it doesn’t look like any arch-specific optimisation flags are used there either. Were you previously specifying these flags manually in your Projucer project?

No, I don’t think so, it’s probably why our Linux build hasn’t been as good as the other platforms.
I’ve only just dug in to what’s happening on Linux as the new tracktion_graph engine relies heavily on choc::buffer::add and it doesn’t looks like that’s getting inlined or auto-vectorised. Fiddling with these flags gives a huge performance boost.

I wasn’t doing this in my example and also not specifying the configuration to use so thanks for this info.

I’ll try and report back what sort of change this makes to my benchmarks.