1 # Distributed under the OSI-approved BSD 3-Clause License. See accompanying
2 # file Copyright.txt or https://cmake.org/licensing for details.
4 #[=======================================================================[.rst:
8 Check whether the compiler supports an interprocedural optimization (IPO/LTO).
9 Use this before enabling the :prop_tgt:`INTERPROCEDURAL_OPTIMIZATION` target
12 .. command:: check_ipo_supported
16 check_ipo_supported([RESULT <result>] [OUTPUT <output>]
17 [LANGUAGES <lang>...])
22 Set ``<result>`` variable to ``YES`` if IPO is supported by the
23 compiler and ``NO`` otherwise. If this option is not given then
24 the command will issue a fatal error if IPO is not supported.
26 Set ``<output>`` variable with details about any error.
27 ``LANGUAGES <lang>...``
28 Specify languages whose compilers to check.
29 Languages ``C``, ``CXX``, and ``Fortran`` are supported.
31 It makes no sense to use this module when :policy:`CMP0069` is set to ``OLD`` so
32 module will return error in this case. See policy :policy:`CMP0069` for details.
39 check_ipo_supported() # fatal error if IPO is not supported
40 set_property(TARGET foo PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE)
44 # Optional IPO. Do not use IPO if it's not supported by compiler.
45 check_ipo_supported(RESULT result OUTPUT output)
47 set_property(TARGET foo PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE)
49 message(WARNING "IPO is not supported: ${output}")
52 #]=======================================================================]
54 # X_RESULT - name of the final result variable
55 # X_OUTPUT - name of the variable with information about error
56 macro(_ipo_not_supported output)
58 message(FATAL_ERROR "IPO is not supported (${output}).")
61 set("${X_RESULT}" NO PARENT_SCOPE)
63 set("${X_OUTPUT}" "${output}" PARENT_SCOPE)
68 macro(_ipo_run_language_check language)
69 set(testdir "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/_CMakeLTOTest-${language}")
71 file(REMOVE_RECURSE "${testdir}")
72 file(MAKE_DIRECTORY "${testdir}")
74 set(bindir "${testdir}/bin")
75 set(srcdir "${testdir}/src")
77 file(MAKE_DIRECTORY "${bindir}")
78 file(MAKE_DIRECTORY "${srcdir}")
80 set(TRY_COMPILE_PROJECT_NAME "lto-test")
82 set(try_compile_src "${CMAKE_ROOT}/Modules/CheckIPOSupported")
85 # * TRY_COMPILE_PROJECT_NAME
88 "${try_compile_src}/CMakeLists-${language}.txt.in"
89 "${srcdir}/CMakeLists.txt"
93 string(COMPARE EQUAL "${language}" "C" is_c)
94 string(COMPARE EQUAL "${language}" "CXX" is_cxx)
95 string(COMPARE EQUAL "${language}" "Fortran" is_fortran)
98 set(copy_sources foo.c main.c)
100 set(copy_sources foo.cpp main.cpp)
102 set(copy_sources foo.f main.f)
104 message(FATAL_ERROR "Language not supported")
107 foreach(x ${copy_sources})
109 "${try_compile_src}/${x}"
116 _IPO_LANGUAGE_CHECK_RESULT
119 "${TRY_COMPILE_PROJECT_NAME}"
121 "-DCMAKE_VERBOSE_MAKEFILE=ON"
122 "-DCMAKE_INTERPROCEDURAL_OPTIMIZATION=ON"
123 OUTPUT_VARIABLE output
125 set(_IPO_LANGUAGE_CHECK_RESULT "${_IPO_LANGUAGE_CHECK_RESULT}")
126 unset(_IPO_LANGUAGE_CHECK_RESULT CACHE)
128 if(NOT _IPO_LANGUAGE_CHECK_RESULT)
129 file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
130 "${language} compiler IPO check failed with the following output:\n"
132 _ipo_not_supported("check failed to compile")
134 set("${X_OUTPUT}" "${output}" PARENT_SCOPE)
140 function(check_ipo_supported)
141 cmake_policy(GET CMP0069 x)
143 string(COMPARE EQUAL "${x}" "" not_set)
145 message(FATAL_ERROR "Policy CMP0069 is not set")
148 string(COMPARE EQUAL "${x}" "OLD" is_old)
150 message(FATAL_ERROR "Policy CMP0069 set to OLD")
154 set(one RESULT OUTPUT)
155 set(multiple LANGUAGES)
161 cmake_parse_arguments(X "${optional}" "${one}" "${multiple}" "${ARGV}")
163 string(COMPARE NOTEQUAL "${X_UNPARSED_ARGUMENTS}" "" has_unparsed)
165 message(FATAL_ERROR "Unparsed arguments: ${X_UNPARSED_ARGUMENTS}")
168 string(COMPARE EQUAL "${X_LANGUAGES}" "" no_languages)
170 # User did not set any languages, use defaults
171 get_property(enabled_languages GLOBAL PROPERTY ENABLED_LANGUAGES)
172 string(COMPARE EQUAL "${enabled_languages}" "" no_languages)
175 "no languages found in ENABLED_LANGUAGES global property"
181 list(FIND enabled_languages "CXX" result)
182 if(NOT result EQUAL -1)
183 list(APPEND languages "CXX")
186 list(FIND enabled_languages "C" result)
187 if(NOT result EQUAL -1)
188 list(APPEND languages "C")
191 list(FIND enabled_languages "Fortran" result)
192 if(NOT result EQUAL -1)
193 list(APPEND languages "Fortran")
196 string(COMPARE EQUAL "${languages}" "" no_languages)
199 "no C/CXX/Fortran languages found in ENABLED_LANGUAGES global property"
204 set(languages "${X_LANGUAGES}")
206 set(unsupported_languages "${languages}")
207 list(REMOVE_ITEM unsupported_languages "C" "CXX" "Fortran")
208 string(COMPARE NOTEQUAL "${unsupported_languages}" "" has_unsupported)
211 "language(s) '${unsupported_languages}' not supported"
217 foreach(lang ${languages})
218 if(NOT _CMAKE_${lang}_IPO_SUPPORTED_BY_CMAKE)
219 _ipo_not_supported("CMake doesn't support IPO for current ${lang} compiler")
223 if(NOT _CMAKE_${lang}_IPO_MAY_BE_SUPPORTED_BY_COMPILER)
224 _ipo_not_supported("${lang} compiler doesn't support IPO")
229 if(CMAKE_GENERATOR MATCHES "^Visual Studio 9 ")
230 _ipo_not_supported("CMake doesn't support IPO for current generator")
234 foreach(x ${languages})
235 _ipo_run_language_check(${x})
238 set("${X_RESULT}" YES PARENT_SCOPE)