CheckPIESupported.cmake 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. # Distributed under the OSI-approved BSD 3-Clause License. See accompanying
  2. # file Copyright.txt or https://cmake.org/licensing for details.
  3. #[=======================================================================[.rst:
  4. CheckPIESupported
  5. -----------------
  6. Check whether the linker supports Position Independent Code (PIE) or No
  7. Position Independent Code (NO_PIE) for executables.
  8. Use this to ensure that the :prop_tgt:`POSITION_INDEPENDENT_CODE` target
  9. property for executables will be honored at link time.
  10. .. command:: check_pie_supported
  11. ::
  12. check_pie_supported([OUTPUT_VARIABLE <output>]
  13. [LANGUAGES <lang>...])
  14. Options are:
  15. ``OUTPUT_VARIABLE <output>``
  16. Set ``<output>`` variable with details about any error.
  17. ``LANGUAGES <lang>...``
  18. Check the linkers used for each of the specified languages.
  19. Supported languages are ``C``, ``CXX``, and ``Fortran``.
  20. It makes no sense to use this module when :policy:`CMP0083` is set to ``OLD``,
  21. so the command will return an error in this case. See policy :policy:`CMP0083`
  22. for details.
  23. Variables
  24. ^^^^^^^^^
  25. For each language checked, two boolean cache variables are defined.
  26. ``CMAKE_<lang>_LINK_PIE_SUPPORTED``
  27. Set to ``YES`` if ``PIE`` is supported by the linker and ``NO`` otherwise.
  28. ``CMAKE_<lang>_LINK_NO_PIE_SUPPORTED``
  29. Set to ``YES`` if ``NO_PIE`` is supported by the linker and ``NO`` otherwise.
  30. Examples
  31. ^^^^^^^^
  32. .. code-block:: cmake
  33. check_pie_supported()
  34. set_property(TARGET foo PROPERTY POSITION_INDEPENDENT_CODE TRUE)
  35. .. code-block:: cmake
  36. # Retrieve any error message.
  37. check_pie_supported(OUTPUT_VARIABLE output LANGUAGES C)
  38. set_property(TARGET foo PROPERTY POSITION_INDEPENDENT_CODE TRUE)
  39. if(NOT CMAKE_C_LINK_PIE_SUPPORTED)
  40. message(WARNING "PIE is not supported at link time: ${output}.\n"
  41. "PIE link options will not be passed to linker.")
  42. endif()
  43. #]=======================================================================]
  44. include (Internal/CMakeCheckCompilerFlag)
  45. function (check_pie_supported)
  46. cmake_policy(GET CMP0083 cmp0083)
  47. if (NOT cmp0083)
  48. message(FATAL_ERROR "check_pie_supported: Policy CMP0083 is not set")
  49. endif()
  50. if(cmp0083 STREQUAL "OLD")
  51. message(FATAL_ERROR "check_pie_supported: Policy CMP0083 set to OLD")
  52. endif()
  53. set(optional)
  54. set(one OUTPUT_VARIABLE)
  55. set(multiple LANGUAGES)
  56. cmake_parse_arguments(CHECK_PIE "${optional}" "${one}" "${multiple}" "${ARGN}")
  57. if(CHECK_PIE_UNPARSED_ARGUMENTS)
  58. message(FATAL_ERROR "check_pie_supported: Unparsed arguments: ${CHECK_PIE_UNPARSED_ARGUMENTS}")
  59. endif()
  60. if (CHECK_PIE_LANGUAGES)
  61. set (unsupported_languages "${CHECK_PIE_LANGUAGES}")
  62. list (REMOVE_ITEM unsupported_languages "C" "CXX" "Fortran")
  63. if(unsupported_languages)
  64. message(FATAL_ERROR "check_pie_supported: language(s) '${unsupported_languages}' not supported")
  65. endif()
  66. else()
  67. # User did not set any languages, use defaults
  68. get_property (enabled_languages GLOBAL PROPERTY ENABLED_LANGUAGES)
  69. if (NOT enabled_languages)
  70. return()
  71. endif()
  72. list (FILTER enabled_languages INCLUDE REGEX "^(C|CXX|Fortran)$")
  73. if (NOT enabled_languages)
  74. return()
  75. endif()
  76. set (CHECK_PIE_LANGUAGES ${enabled_languages})
  77. endif()
  78. set (outputs)
  79. foreach(lang IN LISTS CHECK_PIE_LANGUAGES)
  80. if(_CMAKE_${lang}_PIE_MAY_BE_SUPPORTED_BY_LINKER)
  81. cmake_check_compiler_flag(${lang} "${CMAKE_${lang}_LINK_OPTIONS_PIE}"
  82. CMAKE_${lang}_LINK_PIE_SUPPORTED
  83. OUTPUT_VARIABLE output)
  84. if (NOT CMAKE_${lang}_LINK_PIE_SUPPORTED)
  85. string (APPEND outputs "PIE (${lang}): ${output}\n")
  86. endif()
  87. cmake_check_compiler_flag(${lang} "${CMAKE_${lang}_LINK_OPTIONS_NO_PIE}"
  88. CMAKE_${lang}_LINK_NO_PIE_SUPPORTED
  89. OUTPUT_VARIABLE output)
  90. if (NOT CMAKE_${lang}_LINK_NO_PIE_SUPPORTED)
  91. string (APPEND outputs "NO_PIE (${lang}): ${output}\n")
  92. endif()
  93. else()
  94. # no support at link time. Set cache variables to NO
  95. set(CMAKE_${lang}_LINK_PIE_SUPPORTED NO CACHE INTERNAL "PIE (${lang})")
  96. set(CMAKE_${lang}_LINK_NO_PIE_SUPPORTED NO CACHE INTERNAL "NO_PIE (${lang})")
  97. string (APPEND outputs "PIE and NO_PIE are not supported by linker for ${lang}")
  98. endif()
  99. endforeach()
  100. if (CHECK_PIE_OUTPUT_VARIABLE)
  101. set (${CHECK_PIE_OUTPUT_VARIABLE} "${outputs}" PARENT_SCOPE)
  102. endif()
  103. endfunction()