Skip to content

Commit

Permalink
Enable Link Time Optimization (#2742)
Browse files Browse the repository at this point in the history
* Add MAMBA_LTO option to CMake

* Handle no CMAKE_BUILD_TYPE in LTO
  • Loading branch information
AntoinePrv authored Aug 25, 2023
1 parent 20b477f commit da70542
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 1 deletion.
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,10 @@ option(BUILD_LIBMAMBA_TESTS "Build libmamba C++ tests" OFF)
option(BUILD_MICROMAMBA "Build micromamba" OFF)
option(BUILD_MAMBA_PACKAGE "Build mamba package utility" OFF)
option(MAMBA_WARNING_AS_ERROR "Treat compiler warnings as errors" OFF)
set(MAMBA_LTO "Default" CACHE STRING "Apply Link Time Optimization to targets")

include("cmake/CompilerWarnings.cmake")
include("cmake/LinkTimeOptimization.cmake")

if (MSVC)
# NOMINMAX : prevent tons of code to be included when having to `#include <windows.h>`
Expand Down
2 changes: 1 addition & 1 deletion cmake/CompilerWarnings.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ function(mamba_target_add_compile_warnings target)
# Names of named parameters with a multiple arguments
set(multiValueArgs)
cmake_parse_arguments(ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})

# Extra arguments not accounted for
if(ARG_UNPARSED_ARGUMENTS)
message(
AUTHOR_WARNING
Expand Down
87 changes: 87 additions & 0 deletions cmake/LinkTimeOptimization.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
# Module to set Link Time Optimization flags

include(CheckIPOSupported)


# Detect is setting Link Time Optimization is recommended.
#
# Currenlty checks if LTO is supported and if the build is a release.
function(mamba_should_lto)
# Names of option parameters (without arguments)
set(options)
# Names of named parameters with a single argument
set(oneValueArgs RESULT OUTPUT)
# Names of named parameters with a multiple arguments
set(multiValueArgs)
cmake_parse_arguments(arg "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
# Extra arguments not accounted for
if(arg_UNPARSED_ARGUMENTS)
message(
AUTHOR_WARNING
"Unrecoginzed options passed to ${CMAKE_CURRENT_FUNCTION}: "
"${ARG_UNPARSED_ARGUMENTS}"
)
endif()

# Check if we are building in a release-like build
string(TOLOWER "${CMAKE_BUILD_TYPE}" build_type_lower)
set(valid_release_names "release" "relwithdebinfo")
if(NOT ${build_type_lower} IN_LIST valid_release_names)
set(${arg_RESULT} FALSE PARENT_SCOPE)
set(${arg_OUTPUT} "the build type is not a release" PARENT_SCOPE)
return()
endif()

# Check if LTO is supported by compiler
check_ipo_supported(RESULT lto_is_supported OUTPUT lto_not_supported_reason)
if(NOT lto_is_supported)
set(${arg_RESULT} FALSE PARENT_SCOPE)
set(${arg_OUTPUT} "${lto_not_supported_reason}" PARENT_SCOPE)
endif()

set(${arg_RESULT} TRUE PARENT_SCOPE)
endfunction()


# Set Link Time Optimization on a given target.
#
# MODE parameter takes the possible values
# - A false constant: deactivate LTO
# - A true constant: activate LTO, fails if this is not supported by the compiler
# - "Default" or "Auto": set LTO if supported and the build type is a release.
function(mamba_target_set_lto target)
# Names of option parameters (without arguments)
set(options)
# Names of named parameters with a single argument
set(oneValueArgs MODE)
# Names of named parameters with a multiple arguments
set(multiValueArgs)
cmake_parse_arguments(arg "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
# Extra arguments not accounted for
if(arg_UNPARSED_ARGUMENTS)
message(
AUTHOR_WARNING
"Unrecoginzed parameter passed to ${CMAKE_CURRENT_FUNCTION}: "
"'${arg_UNPARSED_ARGUMENTS}'"
)
return()
endif()

mamba_should_lto(RESULT should_lto OUTPUT lto_message)
string(TOLOWER ${arg_MODE} arg_MODE_lower)
set(valid_default_names "default" "auto" "")
if(arg_MODE_lower IN_LIST valid_default_names)
set(is_default TRUE)
endif()

if("${arg_MODE}" OR (is_default AND should_lto))
message(STATUS "Setting LTO for target ${PROJECT_NAME}::${target}")
set_property(TARGET ${arg_TARGET} PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE)
else()
if(is_default)
message(STATUS "Skipping LTO for target ${PROJECT_NAME}::${target}, ${lto_message}")
else()
message(STATUS "Skipping LTO for target ${PROJECT_NAME}::${target}")
endif()
endif()
endfunction()
1 change: 1 addition & 0 deletions libmamba/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,7 @@ macro(libmamba_create_target target_name linkage output_name)
${target_name}
WARNING_AS_ERROR ${MAMBA_WARNING_AS_ERROR}
)
mamba_target_set_lto(${target_name} MODE ${MAMBA_LTO})

if (${linkage_upper} STREQUAL "STATIC")
message(" -> Statically linking against libmamba (static) dependencies")
Expand Down
1 change: 1 addition & 0 deletions micromamba/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ endif()
add_executable(micromamba ${MICROMAMBA_SRCS} ${MICROMAMBA_HEADERS})

mamba_target_add_compile_warnings(micromamba WARNING_AS_ERROR ${MAMBA_WARNING_AS_ERROR})
mamba_target_set_lto(micromamba MODE ${MAMBA_LTO})

if(NOT (TARGET libmamba OR TARGET libmamba-static))
find_package(libmamba REQUIRED)
Expand Down

0 comments on commit da70542

Please sign in to comment.