Merge topic 'cuda_add_12.8_new_sm_support'
[kiteware-cmake.git] / Modules / CheckPIESupported.cmake
blob4152c1b1c6754ad1bdc0208d13ed6c27056a110b
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:
5 CheckPIESupported
6 -----------------
8 .. versionadded:: 3.14
10 Check whether the linker supports Position Independent Code (PIE) or No
11 Position Independent Code (NO_PIE) for executables.
12 Use this to ensure that the :prop_tgt:`POSITION_INDEPENDENT_CODE` target
13 property for executables will be honored at link time.
15 .. command:: check_pie_supported
17   .. code-block:: cmake
19     check_pie_supported([OUTPUT_VARIABLE <output>]
20                         [LANGUAGES <lang>...])
22   Options are:
24   ``OUTPUT_VARIABLE <output>``
25     Set ``<output>`` variable with details about any error. If the check is
26     bypassed because it uses cached results from a previous call, the output
27     will be empty even if errors were present in the previous call.
29   ``LANGUAGES <lang>...``
30     Check the linkers used for each of the specified languages.
31     If this option is not provided, the command checks all enabled languages.
33     ``C``, ``CXX``, ``Fortran`` are supported.
35     .. versionadded:: 3.23
37       ``OBJC``, ``OBJCXX``, ``CUDA``, and ``HIP`` are supported.
39 It makes no sense to use this module when :policy:`CMP0083` is set to ``OLD``,
40 so the command will return an error in this case.  See policy :policy:`CMP0083`
41 for details.
43 Variables
44 ^^^^^^^^^
46 For each language checked, two boolean cache variables are defined.
48  ``CMAKE_<lang>_LINK_PIE_SUPPORTED``
49    Set to true if ``PIE`` is supported by the linker and false otherwise.
50  ``CMAKE_<lang>_LINK_NO_PIE_SUPPORTED``
51    Set to true if ``NO_PIE`` is supported by the linker and false otherwise.
53 Examples
54 ^^^^^^^^
56 .. code-block:: cmake
58   check_pie_supported()
59   set_property(TARGET foo PROPERTY POSITION_INDEPENDENT_CODE TRUE)
61 .. code-block:: cmake
63   # Retrieve any error message.
64   check_pie_supported(OUTPUT_VARIABLE output LANGUAGES C)
65   set_property(TARGET foo PROPERTY POSITION_INDEPENDENT_CODE TRUE)
66   if(NOT CMAKE_C_LINK_PIE_SUPPORTED)
67     message(WARNING "PIE is not supported at link time: ${output}.\n"
68                     "PIE link options will not be passed to linker.")
69   endif()
71 #]=======================================================================]
74 include (Internal/CheckLinkerFlag)
76 function (check_pie_supported)
77   cmake_policy(GET CMP0083 cmp0083)
79   if (NOT cmp0083)
80     message(FATAL_ERROR "check_pie_supported: Policy CMP0083 is not set")
81   endif()
83   if(cmp0083 STREQUAL "OLD")
84     message(FATAL_ERROR "check_pie_supported: Policy CMP0083 set to OLD")
85   endif()
87   set(optional)
88   set(one OUTPUT_VARIABLE)
89   set(multiple LANGUAGES)
91   cmake_parse_arguments(CHECK_PIE "${optional}" "${one}" "${multiple}" "${ARGN}")
92   if(CHECK_PIE_UNPARSED_ARGUMENTS)
93     message(FATAL_ERROR "check_pie_supported: Unparsed arguments: ${CHECK_PIE_UNPARSED_ARGUMENTS}")
94   endif()
96   if (CHECK_PIE_LANGUAGES)
97     set (unsupported_languages "${CHECK_PIE_LANGUAGES}")
98     list (REMOVE_ITEM unsupported_languages "C" "CXX" "OBJC" "OBJCXX" "Fortran" "CUDA" "HIP")
99     if(unsupported_languages)
100       message(FATAL_ERROR "check_pie_supported: language(s) '${unsupported_languages}' not supported")
101     endif()
102   else()
103     # User did not set any languages, use defaults
104     get_property (enabled_languages GLOBAL PROPERTY ENABLED_LANGUAGES)
105     if (NOT enabled_languages)
106       return()
107     endif()
109     list (FILTER enabled_languages INCLUDE REGEX "^(C|CXX|OBJC|OBJCXX|Fortran|CUDA|HIP)$")
110     if (NOT enabled_languages)
111       return()
112     endif()
114     set (CHECK_PIE_LANGUAGES ${enabled_languages})
115   endif()
117   set(CMAKE_REQUIRED_QUIET TRUE)
118   set (outputs)
120   foreach(lang IN LISTS CHECK_PIE_LANGUAGES)
121     if(_CMAKE_${lang}_PIE_MAY_BE_SUPPORTED_BY_LINKER)
122       if(NOT DEFINED CMAKE_${lang}_LINK_PIE_SUPPORTED)
123         # ensure PIE compile flags are also used
124         list(JOIN CMAKE_${lang}_COMPILE_OPTIONS_PIE " " CMAKE_REQUIRED_FLAGS)
125         cmake_check_linker_flag(${lang}
126                                 "${CMAKE_${lang}_LINK_OPTIONS_PIE}"
127                                 CMAKE_${lang}_LINK_PIE_SUPPORTED
128                                 OUTPUT_VARIABLE output)
129         if (NOT CMAKE_${lang}_LINK_PIE_SUPPORTED)
130           string (APPEND outputs "PIE (${lang}): ${output}\n")
131         endif()
132         unset(CMAKE_REQUIRED_FLAGS)
133       endif()
135       if(NOT DEFINED CMAKE_${lang}_LINK_NO_PIE_SUPPORTED)
136         cmake_check_linker_flag(${lang}
137                                 "${CMAKE_${lang}_LINK_OPTIONS_NO_PIE}"
138                                 CMAKE_${lang}_LINK_NO_PIE_SUPPORTED
139                                 OUTPUT_VARIABLE output)
140         if (NOT CMAKE_${lang}_LINK_NO_PIE_SUPPORTED)
141           string (APPEND outputs "NO_PIE (${lang}): ${output}\n")
142         endif()
143       endif()
144     else()
145       # no support at link time. Set cache variables to NO
146       set(CMAKE_${lang}_LINK_PIE_SUPPORTED NO CACHE INTERNAL "PIE (${lang})")
147       set(CMAKE_${lang}_LINK_NO_PIE_SUPPORTED NO CACHE INTERNAL "NO_PIE (${lang})")
148       string (APPEND outputs "PIE and NO_PIE are not supported by linker for ${lang}\n")
149     endif()
150   endforeach()
152   if (CHECK_PIE_OUTPUT_VARIABLE)
153     set (${CHECK_PIE_OUTPUT_VARIABLE} "${outputs}" PARENT_SCOPE)
154   endif()
155 endfunction()