CheckLanguage.cmake 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  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. CheckLanguage
  5. -------------
  6. Check whether a language can be enabled by the :command:`enable_language`
  7. or :command:`project` commands:
  8. .. command:: check_language
  9. .. code-block:: cmake
  10. check_language(<lang>)
  11. Try enabling language ``<lang>`` in a test project and record results
  12. in the cache:
  13. :variable:`CMAKE_<LANG>_COMPILER`
  14. If the language can be enabled, this variable is set to the compiler
  15. that was found. If the language cannot be enabled, this variable is
  16. set to ``NOTFOUND``.
  17. If this variable is already set, either explicitly or cached by
  18. a previous call, the check is skipped.
  19. :variable:`CMAKE_<LANG>_HOST_COMPILER`
  20. This variable is set when ``<lang>`` is ``CUDA`` or ``HIP``.
  21. If the check detects an explicit host compiler that is required for
  22. compilation, this variable will be set to that compiler.
  23. If the check detects that no explicit host compiler is needed,
  24. this variable will be cleared.
  25. If this variable is already set, its value is preserved only if
  26. :variable:`CMAKE_<LANG>_COMPILER` is also set.
  27. Otherwise, the check runs and overwrites
  28. :variable:`CMAKE_<LANG>_HOST_COMPILER` with a new result.
  29. Note that :variable:`CMAKE_<LANG>_HOST_COMPILER` documents it should
  30. not be set without also setting
  31. :variable:`CMAKE_<LANG>_COMPILER` to a NVCC compiler.
  32. :variable:`CMAKE_<LANG>_PLATFORM <CMAKE_HIP_PLATFORM>`
  33. This variable is set to the detected GPU platform when ``<lang>`` is ``HIP``.
  34. If the variable is already set its value is always preserved. Only compatible values
  35. will be considered for :variable:`CMAKE_<LANG>_COMPILER`.
  36. For example:
  37. .. code-block:: cmake
  38. check_language(Fortran)
  39. if(CMAKE_Fortran_COMPILER)
  40. enable_language(Fortran)
  41. else()
  42. message(STATUS "No Fortran support")
  43. endif()
  44. #]=======================================================================]
  45. include_guard(GLOBAL)
  46. block(SCOPE_FOR POLICIES)
  47. cmake_policy(SET CMP0126 NEW)
  48. macro(check_language lang)
  49. if(NOT DEFINED CMAKE_${lang}_COMPILER)
  50. set(_desc "Looking for a ${lang} compiler")
  51. message(CHECK_START "${_desc}")
  52. file(REMOVE_RECURSE ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/Check${lang})
  53. set(extra_compiler_variables)
  54. if("${lang}" MATCHES "^(CUDA|HIP)$" AND NOT CMAKE_GENERATOR MATCHES "Visual Studio")
  55. set(extra_compiler_variables "set(CMAKE_${lang}_HOST_COMPILER \\\"\${CMAKE_${lang}_HOST_COMPILER}\\\")")
  56. endif()
  57. if("${lang}" STREQUAL "HIP")
  58. list(APPEND extra_compiler_variables "set(CMAKE_${lang}_PLATFORM \\\"\${CMAKE_${lang}_PLATFORM}\\\")")
  59. endif()
  60. list(TRANSFORM extra_compiler_variables PREPEND "\"")
  61. list(TRANSFORM extra_compiler_variables APPEND "\\n\"")
  62. list(JOIN extra_compiler_variables "\n " extra_compiler_variables)
  63. set(_cl_content
  64. "cmake_minimum_required(VERSION ${CMAKE_VERSION})
  65. set(CMAKE_MODULE_PATH \"${CMAKE_MODULE_PATH}\")
  66. project(Check${lang} ${lang})
  67. file(WRITE \"\${CMAKE_CURRENT_BINARY_DIR}/result.cmake\"
  68. \"set(CMAKE_${lang}_COMPILER \\\"\${CMAKE_${lang}_COMPILER}\\\")\\n\"
  69. ${extra_compiler_variables}
  70. )"
  71. )
  72. file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/Check${lang}/CMakeLists.txt"
  73. "${_cl_content}")
  74. if(CMAKE_GENERATOR_INSTANCE)
  75. set(_D_CMAKE_GENERATOR_INSTANCE "-DCMAKE_GENERATOR_INSTANCE:INTERNAL=${CMAKE_GENERATOR_INSTANCE}")
  76. else()
  77. set(_D_CMAKE_GENERATOR_INSTANCE "")
  78. endif()
  79. if(CMAKE_GENERATOR MATCHES "^(Xcode$|Green Hills MULTI$|Visual Studio)")
  80. set(_D_CMAKE_MAKE_PROGRAM "")
  81. else()
  82. set(_D_CMAKE_MAKE_PROGRAM "-DCMAKE_MAKE_PROGRAM:FILEPATH=${CMAKE_MAKE_PROGRAM}")
  83. endif()
  84. if(CMAKE_TOOLCHAIN_FILE)
  85. set(_D_CMAKE_TOOLCHAIN_FILE "-DCMAKE_TOOLCHAIN_FILE:FILEPATH=${CMAKE_TOOLCHAIN_FILE}")
  86. else()
  87. set(_D_CMAKE_TOOLCHAIN_FILE "")
  88. endif()
  89. if(CMAKE_${lang}_PLATFORM)
  90. set(_D_CMAKE_LANG_PLATFORM "-DCMAKE_${lang}_PLATFORM:STRING=${CMAKE_${lang}_PLATFORM}")
  91. else()
  92. set(_D_CMAKE_LANG_PLATFORM "")
  93. endif()
  94. execute_process(
  95. WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/Check${lang}
  96. COMMAND ${CMAKE_COMMAND} . -G ${CMAKE_GENERATOR}
  97. -A "${CMAKE_GENERATOR_PLATFORM}"
  98. -T "${CMAKE_GENERATOR_TOOLSET}"
  99. ${_D_CMAKE_GENERATOR_INSTANCE}
  100. ${_D_CMAKE_MAKE_PROGRAM}
  101. ${_D_CMAKE_TOOLCHAIN_FILE}
  102. ${_D_CMAKE_LANG_PLATFORM}
  103. OUTPUT_VARIABLE _cl_output
  104. ERROR_VARIABLE _cl_output
  105. RESULT_VARIABLE _cl_result
  106. )
  107. include(${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/Check${lang}/result.cmake OPTIONAL)
  108. if(CMAKE_${lang}_COMPILER AND "${_cl_result}" STREQUAL "0")
  109. message(CONFIGURE_LOG
  110. "${_desc} passed with the following output:\n"
  111. "${_cl_output}\n")
  112. set(_CHECK_COMPILER_STATUS CHECK_PASS)
  113. else()
  114. set(CMAKE_${lang}_COMPILER NOTFOUND)
  115. set(_CHECK_COMPILER_STATUS CHECK_FAIL)
  116. message(CONFIGURE_LOG
  117. "${_desc} failed with the following output:\n"
  118. "${_cl_output}\n")
  119. endif()
  120. message(${_CHECK_COMPILER_STATUS} "${CMAKE_${lang}_COMPILER}")
  121. set(CMAKE_${lang}_COMPILER "${CMAKE_${lang}_COMPILER}" CACHE FILEPATH "${lang} compiler")
  122. mark_as_advanced(CMAKE_${lang}_COMPILER)
  123. if(CMAKE_${lang}_HOST_COMPILER)
  124. message(STATUS "Looking for a ${lang} host compiler - ${CMAKE_${lang}_HOST_COMPILER}")
  125. set(CMAKE_${lang}_HOST_COMPILER "${CMAKE_${lang}_HOST_COMPILER}" CACHE FILEPATH "${lang} host compiler")
  126. mark_as_advanced(CMAKE_${lang}_HOST_COMPILER)
  127. endif()
  128. if(CMAKE_${lang}_PLATFORM)
  129. set(CMAKE_${lang}_PLATFORM "${CMAKE_${lang}_PLATFORM}" CACHE STRING "${lang} platform")
  130. mark_as_advanced(CMAKE_${lang}_PLATFORM)
  131. endif()
  132. endif()
  133. endmacro()
  134. endblock()