From b81cba3b0f12ad8cc6f1fa781b2c82b725a1ca1c Mon Sep 17 00:00:00 2001 From: "Addisu Z. Taddese" Date: Mon, 23 Mar 2026 16:21:57 -0500 Subject: [PATCH] Make Whole Program Optimization (WPO) optional on MSVC (#532) * Add GZ_MSVC_WPO option to toggle Whole Program Optimization This adds a \GZ_MSVC_WPO\ option (default ON) that controls the injection of \/GL\ and \/LTCG\ on MSVC. It also fixes a bug where \/LTCG\ was only applied to RelWithDebInfo shared linker flags, and not to Release or other target types. \/INCREMENTAL:NO\ is appropriately restricted to RelWithDebInfo. Generated-By: Gemini 3.1 Pro Signed-off-by: Addisu Z. Taddese * Add /bigobj flag to MSVC_MINIMAL_FLAGS Increases the number of sections in an object file to prevent C1128 errors when building complex templated code with Whole Program Optimization (/GL) enabled. Generated-By: Gemini 3.0 Pro --------- Signed-off-by: Addisu Z. Taddese Co-authored-by: Addisu Z. Taddese (cherry picked from commit a3c8e291c882f89d79b241fe968107ca50a94631) Signed-off-by: Addisu Z. Taddese --- cmake/IgnSetCompilerFlags.cmake | 39 +++++++++++++++++++++++---------- 1 file changed, 28 insertions(+), 11 deletions(-) diff --git a/cmake/IgnSetCompilerFlags.cmake b/cmake/IgnSetCompilerFlags.cmake index acb72c2f..b15ca5a9 100644 --- a/cmake/IgnSetCompilerFlags.cmake +++ b/cmake/IgnSetCompilerFlags.cmake @@ -294,23 +294,35 @@ macro(ign_setup_msvc) # W2: Warning level 2: significant warnings. # TODO: Recommend Wall in the future. # Note: MSVC /Wall generates tons of warnings on gtest code. - set(MSVC_MINIMAL_FLAGS "/Gy /W2") + # bigobj: Increase the number of sections in an object file, which is often needed + # for complex templated code or when using Whole Program Optimization (/GL). + set(MSVC_MINIMAL_FLAGS "/Gy /W2 /bigobj") # Zi: Produce complete debug information # Note: We provide Zi to ordinary release mode because it does not impact # performance and can be helpful for debugging. set(MSVC_DEBUG_FLAGS "${MSVC_MINIMAL_FLAGS} /Zi") - # GL: Enable Whole Program Optimization - set(MSVC_RELEASE_FLAGS "${MSVC_DEBUG_FLAGS} /GL") - - # UNDEBUG: Undefine NDEBUG so that assertions can be triggered - set(MSVC_RELWITHDEBINFO_FLAGS "${MSVC_RELEASE_FLAGS} /UNDEBUG") - - # INCREMENTAL:NO fix LNK4075 warning - # LTCG: need when using /GL above - # see https://docs.microsoft.com/en-us/cpp/build/reference/gl-whole-program-optimization - set(MSVC_RELWITHDEBINFO_LINKER_FLAGS "/INCREMENTAL:NO /LTCG") + option(GZ_MSVC_WPO "Enable Whole Program Optimization on MSVC" ON) + if(GZ_MSVC_WPO) + # GL: Enable Whole Program Optimization + set(MSVC_RELEASE_FLAGS "${MSVC_DEBUG_FLAGS} /GL") + + # UNDEBUG: Undefine NDEBUG so that assertions can be triggered + set(MSVC_RELWITHDEBINFO_FLAGS "${MSVC_RELEASE_FLAGS} /UNDEBUG") + + # LTCG: need when using /GL above + set(MSVC_RELEASE_LINKER_FLAGS "/LTCG") + + # INCREMENTAL:NO fix LNK4075 warning + # see https://docs.microsoft.com/en-us/cpp/build/reference/gl-whole-program-optimization + set(MSVC_RELWITHDEBINFO_LINKER_FLAGS "/INCREMENTAL:NO /LTCG") + else() + set(MSVC_RELEASE_FLAGS "${MSVC_DEBUG_FLAGS}") + set(MSVC_RELWITHDEBINFO_FLAGS "${MSVC_RELEASE_FLAGS} /UNDEBUG") + set(MSVC_RELEASE_LINKER_FLAGS "") + set(MSVC_RELWITHDEBINFO_LINKER_FLAGS "/INCREMENTAL:NO") + endif() # cmake automatically provides /Zi /Ob0 /Od /RTC1 set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${MSVC_DEBUG_FLAGS}") @@ -319,11 +331,16 @@ macro(ign_setup_msvc) # cmake automatically provides /O2 /Ob2 /DNDEBUG set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} ${MSVC_RELEASE_FLAGS}") set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${MSVC_RELEASE_FLAGS}") + set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} ${MSVC_RELEASE_LINKER_FLAGS}") + set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} ${MSVC_RELEASE_LINKER_FLAGS}") + set(CMAKE_STATIC_LINKER_FLAGS_RELEASE "${CMAKE_STATIC_LINKER_FLAGS_RELEASE} ${MSVC_RELEASE_LINKER_FLAGS}") # cmake automatically provides /Zi /O2 /Ob1 /DNDEBUG set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} ${MSVC_RELWITHDEBINFO_FLAGS}") set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} ${MSVC_RELWITHDEBINFO_FLAGS}") set(CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO} ${MSVC_RELWITHDEBINFO_LINKER_FLAGS}") + set(CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO} ${MSVC_RELWITHDEBINFO_LINKER_FLAGS}") + set(CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO} ${MSVC_RELWITHDEBINFO_LINKER_FLAGS}") # cmake automatically provides /O1 /Ob1 /DNDEBUG set(CMAKE_C_FLAGS_MINSIZEREL "${CMAKE_C_FLAGS_MINSIZEREL} ${MSVC_MINIMAL_FLAGS}")