Why are CMake executables so much bigger?

I grab the latest juce and type:

cmake -G Xcode . -DJUCE_BUILD_EXTRAS=ON -DJUCE_BUILD_EXAMPLES=ON -DCMAKE_OSX_ARCHITECTURES="arm64;x86_64"

Then I open Xcode, switch to release and build Projucer. It’s 22 MB.

Then I open Projucer, run it on projucer.jucer, open that in Xcode and build and it’s 18.5 MB.

Both are building with -O3. I don’t see any other compiler / linker settings that would cause the difference, so why are the projects configured with CMake making so much bigger executables? This isn’t just Projucer, it will happen with any juce project you convert to CMake.

Maybe it’s because you built a universal binary with CMake? Is the Projucer-generated build also a universal binary?

They are both Universal Binary. We are seeing the same on Windows as well.

Looks like the CMake build enables LTO, the Projucer build doesn’t. The Projucer build enables dead code stripping, the CMake build doesn’t. If I avoid linking the lto_flags target, and set the XCODE_ATTRIBUTE_DEAD_CODE_STRIPPING YES property on the Projucer target, the size of the CMake build drops considerably.

I haven’t tested in MSVC, but I see that OptimizeReferences is set in the link settings in the vcxproj, which I think functions similarly to dead_strip on macOS. I’m not sure if there’s a nice pure-cmake way of setting that option, but you could try adding /OPT:REF to target_link_options and see whether that helps.

If you’re seeing differences in builds, a good place to start is to run both builds in verbose mode and to check for differences in the compiler flags.

3 Likes

Thanks, that made a big difference.