Default MSVC flags for release configurations are suboptimal
Default MSVC flags for Release, MinSizeRel and RelWithDebInfo are suboptimal. None of them are suitable for actual release builds.
Problems with Release and MinSizeRel:
- Neither genrates debug symbols. PDBs are vital for debugging crashes and other issues post-release, it's a very good practice to have them available. Note that Visual Studio projects always generate PDBs by default. (See also #19549 (closed))
- Neither uses function-level linking (
/Gy
), which reduces binary size without affecting performance.
Problems with RelWithDebInfo:
- It includes
/INCREMENTAL
. Incremental linking is a development feature. It pads every function to allow in-place changes, which is cache-unfriendly and bloats the binaries by about 33%. (See also #16720, #20766). - It includes
/Ob1
, which disables automatic inlining. (See also #13496)
CMake should align its defaults with Visual Stuio defaults, which is what users like me expect.
Expected settings for a release build. I'm not sure whether it should be called RelWithDebInfo or Release.
- CFLAGS:
/O2 /DNDEBUG /Zi /Gy
(default optimizations, disable assert, generate PDB, enable function-level linking) - LDFLAGS:
/DEBUG /INCREMENTAL:NO /OPT:REF /OPT:ICF
(generate PDB, disable incremental linking, remove unreferenced sections, merge identical sections).
Long term, CMake might want to rethink the semantics of default configurations. Builds without symbols shouldn't be the norm, regardless of compiler or platform.