CheckIPOSupported: New module to check for compiler/cmake IPO support
This commit is contained in:
parent
0b2438118a
commit
fdb2ba2521
@ -27,6 +27,7 @@ All Modules
|
||||
/module/CheckFortranFunctionExists
|
||||
/module/CheckFortranSourceCompiles
|
||||
/module/CheckFunctionExists
|
||||
/module/CheckIPOSupported
|
||||
/module/CheckIncludeFileCXX
|
||||
/module/CheckIncludeFile
|
||||
/module/CheckIncludeFiles
|
||||
|
1
Help/module/CheckIPOSupported.rst
Normal file
1
Help/module/CheckIPOSupported.rst
Normal file
@ -0,0 +1 @@
|
||||
.. cmake-module:: ../../Modules/CheckIPOSupported.cmake
|
6
Help/release/dev/CheckIPOSupported.rst
Normal file
6
Help/release/dev/CheckIPOSupported.rst
Normal file
@ -0,0 +1,6 @@
|
||||
CheckIPOSupported
|
||||
-----------------
|
||||
|
||||
* A :module:`CheckIPOSupported` module was added to help projects
|
||||
check whether interprocedural optimization (IPO) is supported by
|
||||
the current toolchain and CMake version.
|
215
Modules/CheckIPOSupported.cmake
Normal file
215
Modules/CheckIPOSupported.cmake
Normal file
@ -0,0 +1,215 @@
|
||||
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
# file Copyright.txt or https://cmake.org/licensing for details.
|
||||
|
||||
#[=======================================================================[.rst:
|
||||
CheckIPOSupported
|
||||
-----------------
|
||||
|
||||
Check whether the compiler supports an interprocedural optimization (IPO/LTO).
|
||||
Use this before enabling the :prop_tgt:`INTERPROCEDURAL_OPTIMIZATION` target
|
||||
property.
|
||||
|
||||
.. command:: check_ipo_supported
|
||||
|
||||
::
|
||||
|
||||
check_ipo_supported([RESULT <result>] [OUTPUT <output>]
|
||||
[LANGUAGES <lang>...])
|
||||
|
||||
Options are:
|
||||
|
||||
``RESULT <result>``
|
||||
Set ``<result>`` variable to ``YES`` if IPO is supported by the
|
||||
compiler and ``NO`` otherwise. If this option is not given then
|
||||
the command will issue a fatal error if IPO is not supported.
|
||||
``OUTPUT <output>``
|
||||
Set ``<output>`` variable with details about any error.
|
||||
``LANGUAGES <lang>...``
|
||||
Specify languages whose compilers to check.
|
||||
Languages ``C`` and ``CXX`` are supported.
|
||||
|
||||
Examples
|
||||
^^^^^^^^
|
||||
|
||||
.. code-block:: cmake
|
||||
|
||||
check_ipo_supported() # fatal error if IPO is not supported
|
||||
set_property(TARGET foo PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE)
|
||||
|
||||
.. code-block:: cmake
|
||||
|
||||
# Optional IPO. Do not use IPO if it's not supported by compiler.
|
||||
check_ipo_supported(RESULT result OUTPUT output)
|
||||
if(result)
|
||||
set_property(TARGET foo PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE)
|
||||
else()
|
||||
message(WARNING "IPO is not supported: ${output}")
|
||||
endif()
|
||||
|
||||
#]=======================================================================]
|
||||
|
||||
include(CMakeParseArguments) # cmake_parse_arguments
|
||||
|
||||
# X_RESULT - name of the final result variable
|
||||
# X_OUTPUT - name of the variable with information about error
|
||||
macro(_ipo_not_supported output)
|
||||
string(COMPARE EQUAL "${X_RESULT}" "" is_empty)
|
||||
if(is_empty)
|
||||
message(FATAL_ERROR "IPO is not supported (${output}).")
|
||||
endif()
|
||||
|
||||
set("${X_RESULT}" NO PARENT_SCOPE)
|
||||
set("${X_OUTPUT}" "${output}" PARENT_SCOPE)
|
||||
endmacro()
|
||||
|
||||
# Run IPO/LTO test
|
||||
macro(_ipo_run_language_check language)
|
||||
set(testdir "${CMAKE_CURRENT_BINARY_DIR}/_CMakeLTOTest-${language}")
|
||||
|
||||
file(REMOVE_RECURSE "${testdir}")
|
||||
file(MAKE_DIRECTORY "${testdir}")
|
||||
|
||||
set(bindir "${testdir}/bin")
|
||||
set(srcdir "${testdir}/src")
|
||||
|
||||
file(MAKE_DIRECTORY "${bindir}")
|
||||
file(MAKE_DIRECTORY "${srcdir}")
|
||||
|
||||
set(TRY_COMPILE_PROJECT_NAME "lto-test")
|
||||
|
||||
set(try_compile_src "${CMAKE_ROOT}/Modules/CheckIPOSupported")
|
||||
|
||||
# Use:
|
||||
# * TRY_COMPILE_PROJECT_NAME
|
||||
# * CMAKE_VERSION
|
||||
configure_file(
|
||||
"${try_compile_src}/CMakeLists-${language}.txt.in"
|
||||
"${srcdir}/CMakeLists.txt"
|
||||
@ONLY
|
||||
)
|
||||
|
||||
string(COMPARE EQUAL "${language}" "C" is_c)
|
||||
string(COMPARE EQUAL "${language}" "CXX" is_cxx)
|
||||
|
||||
if(is_c)
|
||||
set(copy_sources foo.c main.c)
|
||||
elseif(is_cxx)
|
||||
set(copy_sources foo.cpp main.cpp)
|
||||
else()
|
||||
message(FATAL_ERROR "Language not supported")
|
||||
endif()
|
||||
|
||||
foreach(x ${copy_sources})
|
||||
configure_file(
|
||||
"${try_compile_src}/${x}"
|
||||
"${srcdir}/${x}"
|
||||
COPYONLY
|
||||
)
|
||||
endforeach()
|
||||
|
||||
try_compile(
|
||||
result
|
||||
"${bindir}"
|
||||
"${srcdir}"
|
||||
"${TRY_COMPILE_PROJECT_NAME}"
|
||||
CMAKE_FLAGS
|
||||
"-DCMAKE_VERBOSE_MAKEFILE=ON"
|
||||
"-DCMAKE_INTERPROCEDURAL_OPTIMIZATION=ON"
|
||||
OUTPUT_VARIABLE output
|
||||
)
|
||||
|
||||
if(NOT result)
|
||||
_ipo_not_supported("${output}")
|
||||
return()
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
function(check_ipo_supported)
|
||||
# TODO: IPO policy
|
||||
|
||||
set(optional)
|
||||
set(one RESULT OUTPUT)
|
||||
set(multiple LANGUAGES)
|
||||
|
||||
# Introduce:
|
||||
# * X_RESULT
|
||||
# * X_OUTPUT
|
||||
# * X_LANGUAGES
|
||||
cmake_parse_arguments(X "${optional}" "${one}" "${multiple}" "${ARGV}")
|
||||
|
||||
string(COMPARE NOTEQUAL "${X_UNPARSED_ARGUMENTS}" "" has_unparsed)
|
||||
if(has_unparsed)
|
||||
message(FATAL_ERROR "Unparsed arguments: ${X_UNPARSED_ARGUMENTS}")
|
||||
endif()
|
||||
|
||||
string(COMPARE EQUAL "${X_LANGUAGES}" "" no_languages)
|
||||
if(no_languages)
|
||||
# User did not set any languages, use defaults
|
||||
get_property(enabled_languages GLOBAL PROPERTY ENABLED_LANGUAGES)
|
||||
string(COMPARE EQUAL "${enabled_languages}" "" no_languages)
|
||||
if(no_languages)
|
||||
_ipo_not_supported(
|
||||
"no languages found in ENABLED_LANGUAGES global property"
|
||||
)
|
||||
return()
|
||||
endif()
|
||||
|
||||
set(languages "")
|
||||
list(FIND enabled_languages "CXX" result)
|
||||
if(NOT result EQUAL -1)
|
||||
list(APPEND languages "CXX")
|
||||
endif()
|
||||
|
||||
list(FIND enabled_languages "C" result)
|
||||
if(NOT result EQUAL -1)
|
||||
list(APPEND languages "C")
|
||||
endif()
|
||||
|
||||
list(FIND enabled_languages "Fortran" result)
|
||||
if(NOT result EQUAL -1)
|
||||
list(APPEND languages "Fortran")
|
||||
endif()
|
||||
|
||||
string(COMPARE EQUAL "${languages}" "" no_languages)
|
||||
if(no_languages)
|
||||
_ipo_not_supported(
|
||||
"no C/CXX/Fortran languages found in ENABLED_LANGUAGES global property"
|
||||
)
|
||||
return()
|
||||
endif()
|
||||
else()
|
||||
set(languages "${X_LANGUAGES}")
|
||||
|
||||
set(unsupported_languages "${languages}")
|
||||
list(REMOVE_ITEM unsupported_languages "C" "CXX" "Fortran")
|
||||
string(COMPARE NOTEQUAL "${unsupported_languages}" "" has_unsupported)
|
||||
if(has_unsupported)
|
||||
_ipo_not_supported(
|
||||
"language(s) '${unsupported_languages}' not supported"
|
||||
)
|
||||
return()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
list(FIND languages "Fortran" result)
|
||||
if(NOT result EQUAL -1)
|
||||
_ipo_not_supported("Fortran is not supported")
|
||||
return()
|
||||
endif()
|
||||
|
||||
if(NOT _CMAKE_IPO_SUPPORTED_BY_CMAKE)
|
||||
_ipo_not_supported("CMake doesn't support IPO for current compiler")
|
||||
return()
|
||||
endif()
|
||||
|
||||
if(NOT _CMAKE_IPO_MAY_BE_SUPPORTED_BY_COMPILER)
|
||||
_ipo_not_supported("compiler doesn't support IPO")
|
||||
return()
|
||||
endif()
|
||||
|
||||
foreach(x ${languages})
|
||||
_ipo_run_language_check(${x})
|
||||
endforeach()
|
||||
|
||||
set("${X_RESULT}" YES PARENT_SCOPE)
|
||||
endfunction()
|
8
Modules/CheckIPOSupported/CMakeLists-C.txt.in
Normal file
8
Modules/CheckIPOSupported/CMakeLists-C.txt.in
Normal file
@ -0,0 +1,8 @@
|
||||
cmake_minimum_required(VERSION "@CMAKE_VERSION@")
|
||||
project("@TRY_COMPILE_PROJECT_NAME@" LANGUAGES C)
|
||||
|
||||
# TODO: IPO policy
|
||||
|
||||
add_library(foo foo.c)
|
||||
add_executable(boo main.c)
|
||||
target_link_libraries(boo PUBLIC foo)
|
8
Modules/CheckIPOSupported/CMakeLists-CXX.txt.in
Normal file
8
Modules/CheckIPOSupported/CMakeLists-CXX.txt.in
Normal file
@ -0,0 +1,8 @@
|
||||
cmake_minimum_required(VERSION "@CMAKE_VERSION@")
|
||||
project("@TRY_COMPILE_PROJECT_NAME@" LANGUAGES CXX)
|
||||
|
||||
# TODO: IPO policy
|
||||
|
||||
add_library(foo foo.cpp)
|
||||
add_executable(boo main.cpp)
|
||||
target_link_libraries(boo PUBLIC foo)
|
4
Modules/CheckIPOSupported/foo.c
Normal file
4
Modules/CheckIPOSupported/foo.c
Normal file
@ -0,0 +1,4 @@
|
||||
int foo()
|
||||
{
|
||||
return 0x42;
|
||||
}
|
4
Modules/CheckIPOSupported/foo.cpp
Normal file
4
Modules/CheckIPOSupported/foo.cpp
Normal file
@ -0,0 +1,4 @@
|
||||
int foo()
|
||||
{
|
||||
return 0x42;
|
||||
}
|
6
Modules/CheckIPOSupported/main.c
Normal file
6
Modules/CheckIPOSupported/main.c
Normal file
@ -0,0 +1,6 @@
|
||||
int foo();
|
||||
|
||||
int main()
|
||||
{
|
||||
return foo();
|
||||
}
|
6
Modules/CheckIPOSupported/main.cpp
Normal file
6
Modules/CheckIPOSupported/main.cpp
Normal file
@ -0,0 +1,6 @@
|
||||
int foo();
|
||||
|
||||
int main()
|
||||
{
|
||||
return foo();
|
||||
}
|
@ -30,12 +30,17 @@ macro(__linux_compiler_intel lang)
|
||||
# executables that use dlopen but do not set ENABLE_EXPORTS.
|
||||
set(CMAKE_SHARED_LIBRARY_LINK_${lang}_FLAGS "-rdynamic")
|
||||
|
||||
set(_CMAKE_IPO_SUPPORTED_BY_CMAKE YES)
|
||||
|
||||
if(XIAR)
|
||||
# INTERPROCEDURAL_OPTIMIZATION
|
||||
set(CMAKE_${lang}_COMPILE_OPTIONS_IPO -ipo)
|
||||
set(CMAKE_${lang}_CREATE_STATIC_LIBRARY_IPO
|
||||
"${XIAR} cr <TARGET> <LINK_FLAGS> <OBJECTS> "
|
||||
"${XIAR} -s <TARGET> ")
|
||||
set(_CMAKE_IPO_MAY_BE_SUPPORTED_BY_COMPILER YES)
|
||||
else()
|
||||
set(_CMAKE_IPO_MAY_BE_SUPPORTED_BY_COMPILER NO)
|
||||
endif()
|
||||
|
||||
if(NOT CMAKE_${lang}_COMPILER_VERSION VERSION_LESS 12.0)
|
||||
|
Loading…
Reference in New Issue
Block a user