5076: Add a CMake option to enable IPO r=def- a=Kaffeine

The main motivation is to reduce the size of binaries for release build (following #5074).
The feature is not enabled by default because it increases the build time and the effect should be valued case-by-case.

### Linux
Linux build time changed from 2:01 to 2:56 (with GNU gold) or 3:20 (default ld).

| Executable | Before  | After |
| ------------- | ---------|---- |
| config_retrieve | 886K | 43K |
| config_store | 890K | 51K |
| DDNet | 4.1M | 4.1M |
| DDNet-Server | 1.6M | 1.6M |
| dilate | 898K | 35K |
| map_convert_07 | 902K | 59K |
| map_diff | 890K | 47K  |
| map_extract | 898K | 47K  |

### macOS
macOS build time remained to be around 2:30.

The size of `.dmg` image without IPO is `47.6Mb`, the size with IPO enabled is `46.4Mb` which is 1.2Mb lighter. I didn't check the internals.

### Windows
Windows build time changed from 3:10 to 5:05

The binaries became even _bigger_ with IPO enabled. Nonsense, maybe IPO is messed up with some other project-specific compiler settings. I didn't investigate.

## Conclusion
It makes sense to (manually) enable IPO for macOS and Linux builds for production builds (probably update https://github.com/ddnet/ddnet-scripts/blob/master/release/build.sh for that).

Co-authored-by: Alexander Akulich <akulichalexander@gmail.com>
This commit is contained in:
bors[bot] 2022-05-15 12:03:02 +00:00 committed by GitHub
commit 8a65e8386b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 50 additions and 1 deletions

View file

@ -95,6 +95,19 @@ else()
endif()
set(AUTO_DEPENDENCIES_DEFAULT OFF)
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
set(AUTO_IPO OFF)
else()
set(AUTO_IPO ON)
endif()
if(MSVC)
# For some reason on MSVC platform the client and server binaries
# become even bigger with IPO enabled.
set(AUTO_IPO OFF)
endif()
set(AUTO_VULKAN_BACKEND ON)
if(TARGET_OS STREQUAL "windows")
set(AUTO_DEPENDENCIES_DEFAULT ON)
@ -126,6 +139,7 @@ option(DEV "Don't generate stuff necessary for packaging" OFF)
option(VULKAN "Enable the vulkan backend" ${AUTO_VULKAN_BACKEND})
option(EXCEPTION_HANDLING "Enable exception handling (only works with Windows as of now)" OFF)
option(IPO "Enable interprocedural optimizations" ${AUTO_IPO})
if(CMAKE_SYSTEM_NAME STREQUAL "Emscripten")
include(${PROJECT_SOURCE_DIR}/cmake/toolchains/Emscripten.toolchain)
@ -157,6 +171,21 @@ endif()
set(DBG $<OR:$<CONFIG:Debug>,$<CONFIG:RelWithDebInfo>>)
if(IPO)
if(CMAKE_VERSION VERSION_GREATER 3.9)
include(CheckIPOSupported)
check_ipo_supported(RESULT ipo_supported OUTPUT ipo_output)
if(ipo_supported)
message(STATUS "IPO is enabled")
set(ENABLE_IPO TRUE)
else()
message(WARNING "IPO is not supported: ${ipo_output}")
endif()
else()
message(WARNING "IPO enablement requires CMake 3.9+")
endif()
endif()
if(CMAKE_VERSION VERSION_LESS 3.0)
configure_file(src/game/version.h vd.h)
else()
@ -264,6 +293,23 @@ if(NOT MSVC AND NOT HAIKU)
# add_c_compiler_flag_if_supported(OUR_FLAGS_OWN -Wuseless-cast) # TODO: Enable for C++ code except gtest
endif()
if(UNIX AND NOT APPLE)
# This can be disabled by configuring with -DUSE_GOLD=FALSE
if(NOT DEFINED USE_GOLD)
execute_process(COMMAND ${CMAKE_C_COMPILER} -fuse-ld=gold -Wl,--version ERROR_QUIET OUTPUT_VARIABLE ld_version)
if("${ld_version}" MATCHES "GNU gold")
set(USE_GOLD TRUE CACHE BOOL "Use GNU gold linker")
else()
set(USE_GOLD FALSE CACHE BOOL "Use GNU gold linker")
endif()
endif()
message(STATUS "GNU gold linker enabled: ${USE_GOLD}")
if(USE_GOLD)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fuse-ld=gold -Wl,--disable-new-dtags")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -fuse-ld=gold -Wl,--disable-new-dtags")
endif()
endif()
if(MSVC)
if(EXCEPTION_HANDLING)
add_c_compiler_flag_if_supported(OUR_FLAGS /DCONF_EXCEPTION_HANDLING)
@ -2916,6 +2962,9 @@ foreach(target ${TARGETS})
target_compile_definitions(${target} PRIVATE $<$<NOT:$<CONFIG:Debug>>:_FORTIFY_SOURCE=2>) # Detect some buffer overflows.
endif()
endif()
if(ENABLE_IPO)
set_property(TARGET ${target} PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE)
endif()
endforeach()
foreach(target ${TARGETS_LINK})

View file

@ -21,7 +21,7 @@ if(NOT GLSLANG_VALIDATOR_PROGRAM)
endif()
endif()
if(${GLSLANG_VALIDATOR_PROGRAM_FOUND} EQUAL FALSE)
if(NOT GLSLANG_VALIDATOR_PROGRAM_FOUND)
message(FATAL_ERROR "glslangValidator binary was not found. Did you install the Vulkan SDK / packages ?")
endif()
endif()