1# Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
2# file Copyright.txt or https://cmake.org/licensing for details.
3
4include_guard(GLOBAL)
5
6cmake_policy(PUSH)
7cmake_policy(SET CMP0054 NEW) # if() quoted variables not dereferenced
8cmake_policy(SET CMP0057 NEW) # if() supports IN_LIST
9
10function(CMAKE_CHECK_SOURCE_COMPILES _lang _source _var)
11  if(NOT DEFINED "${_var}")
12
13    if(_lang STREQUAL "C")
14      set(_lang_textual "C")
15      set(_lang_ext "c")
16    elseif(_lang STREQUAL "CXX")
17      set(_lang_textual "C++")
18      set(_lang_ext "cxx")
19    elseif(_lang STREQUAL "CUDA")
20      set(_lang_textual "CUDA")
21      set(_lang_ext "cu")
22    elseif(_lang STREQUAL "Fortran")
23      set(_lang_textual "Fortran")
24      set(_lang_ext "F90")
25    elseif(_lang STREQUAL "HIP")
26      set(_lang_textual "HIP")
27      set(_lang_ext "hip")
28    elseif(_lang STREQUAL "ISPC")
29      set(_lang_textual "ISPC")
30      set(_lang_ext "ispc")
31    elseif(_lang STREQUAL "OBJC")
32      set(_lang_textual "Objective-C")
33      set(_lang_ext "m")
34    elseif(_lang STREQUAL "OBJCXX")
35      set(_lang_textual "Objective-C++")
36      set(_lang_ext "mm")
37    else()
38      message (SEND_ERROR "check_source_compiles: ${_lang}: unknown language.")
39      return()
40    endif()
41
42    get_property (_supported_languages GLOBAL PROPERTY ENABLED_LANGUAGES)
43    if (NOT _lang IN_LIST _supported_languages)
44      message (SEND_ERROR "check_source_compiles: ${_lang}: needs to be enabled before use.")
45      return()
46    endif()
47
48    set(_FAIL_REGEX)
49    set(_SRC_EXT)
50    set(_key)
51    foreach(arg ${ARGN})
52      if("${arg}" MATCHES "^(FAIL_REGEX|SRC_EXT)$")
53        set(_key "${arg}")
54      elseif(_key STREQUAL "FAIL_REGEX")
55        list(APPEND _FAIL_REGEX "${arg}")
56      elseif(_key STREQUAL "SRC_EXT")
57        set(_SRC_EXT "${arg}")
58        set(_key "")
59      else()
60        message(FATAL_ERROR "Unknown argument:\n  ${arg}\n")
61      endif()
62    endforeach()
63
64    if(NOT _SRC_EXT)
65      set(_SRC_EXT ${_lang_ext})
66    endif()
67
68    if(CMAKE_REQUIRED_LINK_OPTIONS)
69      set(CHECK_${LANG}_SOURCE_COMPILES_ADD_LINK_OPTIONS
70        LINK_OPTIONS ${CMAKE_REQUIRED_LINK_OPTIONS})
71    else()
72      set(CHECK_${LANG}_SOURCE_COMPILES_ADD_LINK_OPTIONS)
73    endif()
74    if(CMAKE_REQUIRED_LIBRARIES)
75      set(CHECK_${LANG}_SOURCE_COMPILES_ADD_LIBRARIES
76        LINK_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES})
77    else()
78      set(CHECK_${LANG}_SOURCE_COMPILES_ADD_LIBRARIES)
79    endif()
80    if(CMAKE_REQUIRED_INCLUDES)
81      set(CHECK_${LANG}_SOURCE_COMPILES_ADD_INCLUDES
82        "-DINCLUDE_DIRECTORIES:STRING=${CMAKE_REQUIRED_INCLUDES}")
83    else()
84      set(CHECK_${LANG}_SOURCE_COMPILES_ADD_INCLUDES)
85    endif()
86    file(WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.${_SRC_EXT}"
87      "${_source}\n")
88
89    if(NOT CMAKE_REQUIRED_QUIET)
90      message(CHECK_START "Performing Test ${_var}")
91    endif()
92    try_compile(${_var}
93      ${CMAKE_BINARY_DIR}
94      ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.${_SRC_EXT}
95      COMPILE_DEFINITIONS -D${_var} ${CMAKE_REQUIRED_DEFINITIONS}
96      ${CHECK_${LANG}_SOURCE_COMPILES_ADD_LINK_OPTIONS}
97      ${CHECK_${LANG}_SOURCE_COMPILES_ADD_LIBRARIES}
98      CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${CMAKE_REQUIRED_FLAGS}
99      "${CHECK_${LANG}_SOURCE_COMPILES_ADD_INCLUDES}"
100      OUTPUT_VARIABLE OUTPUT)
101
102    foreach(_regex ${_FAIL_REGEX})
103      if("${OUTPUT}" MATCHES "${_regex}")
104        set(${_var} 0)
105      endif()
106    endforeach()
107
108    if(${_var})
109      set(${_var} 1 CACHE INTERNAL "Test ${_var}")
110      if(NOT CMAKE_REQUIRED_QUIET)
111        message(CHECK_PASS "Success")
112      endif()
113      file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
114        "Performing ${_lang_textual} SOURCE FILE Test ${_var} succeeded with the following output:\n"
115        "${OUTPUT}\n"
116        "Source file was:\n${_source}\n")
117    else()
118      if(NOT CMAKE_REQUIRED_QUIET)
119        message(CHECK_FAIL "Failed")
120      endif()
121      set(${_var} "" CACHE INTERNAL "Test ${_var}")
122      file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
123        "Performing ${_lang_textual} SOURCE FILE Test ${_var} failed with the following output:\n"
124        "${OUTPUT}\n"
125        "Source file was:\n${_source}\n")
126    endif()
127  endif()
128endfunction()
129
130cmake_policy(POP)
131