Imported Upstream version 3.25.0
[platform/upstream/cmake.git] / Modules / Internal / CheckSourceRuns.cmake
1 # Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
2 # file Copyright.txt or https://cmake.org/licensing for details.
3
4 include_guard(GLOBAL)
5
6 cmake_policy(PUSH)
7 cmake_policy(SET CMP0054 NEW) # if() quoted variables not dereferenced
8 cmake_policy(SET CMP0057 NEW) # if() supports IN_LIST
9
10 function(CMAKE_CHECK_SOURCE_RUNS _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 "OBJC")
29       set(_lang_textual "Objective-C")
30       set(_lang_ext "m")
31     elseif(_lang STREQUAL "OBJCXX")
32       set(_lang_textual "Objective-C++")
33       set(_lang_ext "mm")
34     else()
35       message (SEND_ERROR "check_source_runs: ${_lang}: unknown language.")
36       return()
37     endif()
38
39     get_property (_supported_languages GLOBAL PROPERTY ENABLED_LANGUAGES)
40     if (NOT _lang IN_LIST _supported_languages)
41       message (SEND_ERROR "check_source_runs: ${_lang}: needs to be enabled before use.")
42       return()
43     endif()
44
45     set(_FAIL_REGEX)
46     set(_SRC_EXT)
47     set(_key)
48     foreach(arg ${ARGN})
49       if("${arg}" MATCHES "^(FAIL_REGEX|SRC_EXT)$")
50         set(_key "${arg}")
51       elseif(_key STREQUAL "FAIL_REGEX")
52         list(APPEND _FAIL_REGEX "${arg}")
53       elseif(_key STREQUAL "SRC_EXT")
54         set(_SRC_EXT "${arg}")
55         set(_key "")
56       else()
57         set(message_type FATAL_ERROR)
58         if (_CheckSourceRuns_old_signature)
59           set(message_type AUTHOR_WARNING)
60         endif ()
61         message("${message_type}" "Unknown argument:\n  ${arg}\n")
62         unset(message_type)
63       endif()
64     endforeach()
65
66     if(NOT _SRC_EXT)
67       set(_SRC_EXT ${_lang_ext})
68     endif()
69
70     if(CMAKE_REQUIRED_LINK_OPTIONS)
71       set(CHECK_${_lang}_SOURCE_COMPILES_ADD_LINK_OPTIONS
72         LINK_OPTIONS ${CMAKE_REQUIRED_LINK_OPTIONS})
73     else()
74       set(CHECK_${_lang}_SOURCE_COMPILES_ADD_LINK_OPTIONS)
75     endif()
76     if(CMAKE_REQUIRED_LIBRARIES)
77       set(CHECK_${_lang}_SOURCE_COMPILES_ADD_LIBRARIES
78         LINK_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES})
79     else()
80       set(CHECK_${_lang}_SOURCE_COMPILES_ADD_LIBRARIES)
81     endif()
82     if(CMAKE_REQUIRED_INCLUDES)
83       set(CHECK_${_lang}_SOURCE_COMPILES_ADD_INCLUDES
84         "-DINCLUDE_DIRECTORIES:STRING=${CMAKE_REQUIRED_INCLUDES}")
85     else()
86       set(CHECK_${_lang}_SOURCE_COMPILES_ADD_INCLUDES)
87     endif()
88
89     if(NOT CMAKE_REQUIRED_QUIET)
90       message(CHECK_START "Performing Test ${_var}")
91     endif()
92     string(APPEND _source "\n")
93     try_run(${_var}_EXITCODE ${_var}_COMPILED
94       SOURCE_FROM_VAR "src.${_SRC_EXT}" _source
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       -DCMAKE_SKIP_RPATH:BOOL=${CMAKE_SKIP_RPATH}
100       "${CHECK_${_lang}_SOURCE_COMPILES_ADD_INCLUDES}"
101       COMPILE_OUTPUT_VARIABLE OUTPUT
102       RUN_OUTPUT_VARIABLE RUN_OUTPUT)
103     # if it did not compile make the return value fail code of 1
104     if(NOT ${_var}_COMPILED)
105       set(${_var}_EXITCODE 1)
106       set(${_var}_EXITCODE 1 PARENT_SCOPE)
107     endif()
108     # if the return value was 0 then it worked
109     if("${${_var}_EXITCODE}" EQUAL 0)
110       set(${_var} 1 CACHE INTERNAL "Test ${_var}")
111       if(NOT CMAKE_REQUIRED_QUIET)
112         message(CHECK_PASS "Success")
113       endif()
114       file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
115         "Performing ${_lang_textual} SOURCE FILE Test ${_var} succeeded with the following compile output:\n"
116         "${OUTPUT}\n"
117         "...and run output:\n"
118         "${RUN_OUTPUT}\n"
119         "Return value: ${${_var}}\n"
120         "Source file was:\n${_source}\n")
121     else()
122       if(CMAKE_CROSSCOMPILING AND "${${_var}_EXITCODE}" MATCHES  "FAILED_TO_RUN")
123         set(${_var} "${${_var}_EXITCODE}" PARENT_SCOPE)
124       else()
125         set(${_var} "" CACHE INTERNAL "Test ${_var}")
126       endif()
127
128       if(NOT CMAKE_REQUIRED_QUIET)
129         message(CHECK_FAIL "Failed")
130       endif()
131       file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
132         "Performing ${_lang_textual} SOURCE FILE Test ${_var} failed with the following compile output:\n"
133         "${OUTPUT}\n"
134         "...and run output:\n"
135         "${RUN_OUTPUT}\n"
136         "Return value: ${${_var}_EXITCODE}\n"
137         "Source file was:\n${_source}\n")
138
139     endif()
140   endif()
141 endfunction()
142
143 cmake_policy(POP)