75e98960f3d4333dcc29eba71b2cf6959a4a6d6a
[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     file(WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.${_SRC_EXT}"
89       "${_source}\n")
90
91     if(NOT CMAKE_REQUIRED_QUIET)
92       message(CHECK_START "Performing Test ${_var}")
93     endif()
94     try_run(${_var}_EXITCODE ${_var}_COMPILED
95       ${CMAKE_BINARY_DIR}
96       ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.${_SRC_EXT}
97       COMPILE_DEFINITIONS -D${_var} ${CMAKE_REQUIRED_DEFINITIONS}
98       ${CHECK_${_lang}_SOURCE_COMPILES_ADD_LINK_OPTIONS}
99       ${CHECK_${_lang}_SOURCE_COMPILES_ADD_LIBRARIES}
100       CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${CMAKE_REQUIRED_FLAGS}
101       -DCMAKE_SKIP_RPATH:BOOL=${CMAKE_SKIP_RPATH}
102       "${CHECK_${_lang}_SOURCE_COMPILES_ADD_INCLUDES}"
103       COMPILE_OUTPUT_VARIABLE OUTPUT
104       RUN_OUTPUT_VARIABLE RUN_OUTPUT)
105     # if it did not compile make the return value fail code of 1
106     if(NOT ${_var}_COMPILED)
107       set(${_var}_EXITCODE 1)
108       set(${_var}_EXITCODE 1 PARENT_SCOPE)
109     endif()
110     # if the return value was 0 then it worked
111     if("${${_var}_EXITCODE}" EQUAL 0)
112       set(${_var} 1 CACHE INTERNAL "Test ${_var}")
113       if(NOT CMAKE_REQUIRED_QUIET)
114         message(CHECK_PASS "Success")
115       endif()
116       file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
117         "Performing ${_lang_textual} SOURCE FILE Test ${_var} succeeded with the following compile output:\n"
118         "${OUTPUT}\n"
119         "...and run output:\n"
120         "${RUN_OUTPUT}\n"
121         "Return value: ${${_var}}\n"
122         "Source file was:\n${_source}\n")
123     else()
124       if(CMAKE_CROSSCOMPILING AND "${${_var}_EXITCODE}" MATCHES  "FAILED_TO_RUN")
125         set(${_var} "${${_var}_EXITCODE}" PARENT_SCOPE)
126       else()
127         set(${_var} "" CACHE INTERNAL "Test ${_var}")
128       endif()
129
130       if(NOT CMAKE_REQUIRED_QUIET)
131         message(CHECK_FAIL "Failed")
132       endif()
133       file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
134         "Performing ${_lang_textual} SOURCE FILE Test ${_var} failed with the following compile output:\n"
135         "${OUTPUT}\n"
136         "...and run output:\n"
137         "${RUN_OUTPUT}\n"
138         "Return value: ${${_var}_EXITCODE}\n"
139         "Source file was:\n${_source}\n")
140
141     endif()
142   endif()
143 endfunction()
144
145 cmake_policy(POP)