summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Maynard <robert.maynard@kitware.com>2020-09-14 13:17:42 -0400
committerRobert Maynard <robert.maynard@kitware.com>2020-09-23 12:28:37 -0400
commit10ae907de07c26820a765c6a516d1f4baa46161d (patch)
tree51550bfe24aa14db9bec91efc1e45a1d841fb939
parentf5c928f73cdb35b4cc0ea052f663071ec590624e (diff)
downloadcmake-10ae907de07c26820a765c6a516d1f4baa46161d.tar.gz
CheckSoureCompiles: Add a unified way to check if a source compiles
-rw-r--r--Help/manual/cmake-modules.7.rst1
-rw-r--r--Help/module/CheckSourceCompiles.rst1
-rw-r--r--Help/release/dev/check-source-modules.rst6
-rw-r--r--Modules/CheckCSourceCompiles.cmake76
-rw-r--r--Modules/CheckCXXSourceCompiles.cmake77
-rw-r--r--Modules/CheckFortranSourceCompiles.cmake78
-rw-r--r--Modules/CheckLinkerFlag.cmake4
-rw-r--r--Modules/CheckOBJCSourceCompiles.cmake76
-rw-r--r--Modules/CheckOBJCXXSourceCompiles.cmake77
-rw-r--r--Modules/CheckSourceCompiles.cmake192
-rw-r--r--Tests/RunCMake/CMakeLists.txt2
-rw-r--r--Tests/RunCMake/CheckSourceCompiles/CMakeLists.txt5
-rw-r--r--Tests/RunCMake/CheckSourceCompiles/CheckCSourceCompiles.cmake13
-rw-r--r--Tests/RunCMake/CheckSourceCompiles/CheckCXXSourceCompiles.cmake26
-rw-r--r--Tests/RunCMake/CheckSourceCompiles/CheckFortranSourceCompiles.cmake14
-rw-r--r--Tests/RunCMake/CheckSourceCompiles/CheckOBJCSourceCompiles.cmake14
-rw-r--r--Tests/RunCMake/CheckSourceCompiles/CheckOBJCXXSourceCompiles.cmake17
-rw-r--r--Tests/RunCMake/CheckSourceCompiles/NonExistentLanguage-result.txt1
-rw-r--r--Tests/RunCMake/CheckSourceCompiles/NonExistentLanguage-stderr.txt2
-rw-r--r--Tests/RunCMake/CheckSourceCompiles/NonExistentLanguage.cmake3
-rw-r--r--Tests/RunCMake/CheckSourceCompiles/NotEnabledLanguage-result.txt1
-rw-r--r--Tests/RunCMake/CheckSourceCompiles/NotEnabledLanguage-stderr.txt2
-rw-r--r--Tests/RunCMake/CheckSourceCompiles/NotEnabledLanguage.cmake3
-rw-r--r--Tests/RunCMake/CheckSourceCompiles/RunCMakeTest.cmake16
24 files changed, 331 insertions, 376 deletions
diff --git a/Help/manual/cmake-modules.7.rst b/Help/manual/cmake-modules.7.rst
index 50131e8fc4..d206193806 100644
--- a/Help/manual/cmake-modules.7.rst
+++ b/Help/manual/cmake-modules.7.rst
@@ -45,6 +45,7 @@ These modules are loaded using the :command:`include` command.
/module/CheckOBJCXXSourceRuns
/module/CheckPIESupported
/module/CheckPrototypeDefinition
+ /module/CheckSourceCompiles
/module/CheckStructHasMember
/module/CheckSymbolExists
/module/CheckTypeSize
diff --git a/Help/module/CheckSourceCompiles.rst b/Help/module/CheckSourceCompiles.rst
new file mode 100644
index 0000000000..906db0ab6d
--- /dev/null
+++ b/Help/module/CheckSourceCompiles.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/CheckSourceCompiles.cmake
diff --git a/Help/release/dev/check-source-modules.rst b/Help/release/dev/check-source-modules.rst
new file mode 100644
index 0000000000..a98ed03169
--- /dev/null
+++ b/Help/release/dev/check-source-modules.rst
@@ -0,0 +1,6 @@
+check-source-modules
+^^^^^^^^^^^^^^^^^^^^
+
+* The :module:`CheckSourceCompiles` module has been added to
+ generalize :module:`CheckCSourceCompiles` and
+ :module:`CheckCXXSourceCompiles` to more languages.
diff --git a/Modules/CheckCSourceCompiles.cmake b/Modules/CheckCSourceCompiles.cmake
index 67fc993be3..975e6537f0 100644
--- a/Modules/CheckCSourceCompiles.cmake
+++ b/Modules/CheckCSourceCompiles.cmake
@@ -66,80 +66,8 @@ Check if given C source compiles and links into an executable.
#]=======================================================================]
include_guard(GLOBAL)
+include(CheckSourceCompiles)
macro(CHECK_C_SOURCE_COMPILES SOURCE VAR)
- if(NOT DEFINED "${VAR}")
- set(_FAIL_REGEX)
- set(_key)
- foreach(arg ${ARGN})
- if("${arg}" MATCHES "^(FAIL_REGEX)$")
- set(_key "${arg}")
- elseif(_key)
- list(APPEND _${_key} "${arg}")
- else()
- message(FATAL_ERROR "Unknown argument:\n ${arg}\n")
- endif()
- endforeach()
- set(MACRO_CHECK_FUNCTION_DEFINITIONS
- "-D${VAR} ${CMAKE_REQUIRED_FLAGS}")
- if(CMAKE_REQUIRED_LINK_OPTIONS)
- set(CHECK_C_SOURCE_COMPILES_ADD_LINK_OPTIONS
- LINK_OPTIONS ${CMAKE_REQUIRED_LINK_OPTIONS})
- else()
- set(CHECK_C_SOURCE_COMPILES_ADD_LINK_OPTIONS)
- endif()
- if(CMAKE_REQUIRED_LIBRARIES)
- set(CHECK_C_SOURCE_COMPILES_ADD_LIBRARIES
- LINK_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES})
- else()
- set(CHECK_C_SOURCE_COMPILES_ADD_LIBRARIES)
- endif()
- if(CMAKE_REQUIRED_INCLUDES)
- set(CHECK_C_SOURCE_COMPILES_ADD_INCLUDES
- "-DINCLUDE_DIRECTORIES:STRING=${CMAKE_REQUIRED_INCLUDES}")
- else()
- set(CHECK_C_SOURCE_COMPILES_ADD_INCLUDES)
- endif()
- file(WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.c"
- "${SOURCE}\n")
-
- if(NOT CMAKE_REQUIRED_QUIET)
- message(CHECK_START "Performing Test ${VAR}")
- endif()
- try_compile(${VAR}
- ${CMAKE_BINARY_DIR}
- ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.c
- COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}
- ${CHECK_C_SOURCE_COMPILES_ADD_LINK_OPTIONS}
- ${CHECK_C_SOURCE_COMPILES_ADD_LIBRARIES}
- CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_FUNCTION_DEFINITIONS}
- "${CHECK_C_SOURCE_COMPILES_ADD_INCLUDES}"
- OUTPUT_VARIABLE OUTPUT)
-
- foreach(_regex ${_FAIL_REGEX})
- if("${OUTPUT}" MATCHES "${_regex}")
- set(${VAR} 0)
- endif()
- endforeach()
-
- if(${VAR})
- set(${VAR} 1 CACHE INTERNAL "Test ${VAR}")
- if(NOT CMAKE_REQUIRED_QUIET)
- message(CHECK_PASS "Success")
- endif()
- file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
- "Performing C SOURCE FILE Test ${VAR} succeeded with the following output:\n"
- "${OUTPUT}\n"
- "Source file was:\n${SOURCE}\n")
- else()
- if(NOT CMAKE_REQUIRED_QUIET)
- message(CHECK_FAIL "Failed")
- endif()
- set(${VAR} "" CACHE INTERNAL "Test ${VAR}")
- file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
- "Performing C SOURCE FILE Test ${VAR} failed with the following output:\n"
- "${OUTPUT}\n"
- "Source file was:\n${SOURCE}\n")
- endif()
- endif()
+ check_source_compiles(C "${SOURCE}" ${VAR} ${ARGN})
endmacro()
diff --git a/Modules/CheckCXXSourceCompiles.cmake b/Modules/CheckCXXSourceCompiles.cmake
index c693d32b3f..f7f9d0b1fa 100644
--- a/Modules/CheckCXXSourceCompiles.cmake
+++ b/Modules/CheckCXXSourceCompiles.cmake
@@ -66,81 +66,8 @@ Check if given C++ source compiles and links into an executable.
#]=======================================================================]
include_guard(GLOBAL)
+include(CheckSourceCompiles)
macro(CHECK_CXX_SOURCE_COMPILES SOURCE VAR)
- if(NOT DEFINED "${VAR}")
- set(_FAIL_REGEX)
- set(_key)
- foreach(arg ${ARGN})
- if("${arg}" MATCHES "^(FAIL_REGEX)$")
- set(_key "${arg}")
- elseif(_key)
- list(APPEND _${_key} "${arg}")
- else()
- message(FATAL_ERROR "Unknown argument:\n ${arg}\n")
- endif()
- endforeach()
-
- set(MACRO_CHECK_FUNCTION_DEFINITIONS
- "-D${VAR} ${CMAKE_REQUIRED_FLAGS}")
- if(CMAKE_REQUIRED_LINK_OPTIONS)
- set(CHECK_CXX_SOURCE_COMPILES_ADD_LINK_OPTIONS
- LINK_OPTIONS ${CMAKE_REQUIRED_LINK_OPTIONS})
- else()
- set(CHECK_CXX_SOURCE_COMPILES_ADD_LINK_OPTIONS)
- endif()
- if(CMAKE_REQUIRED_LIBRARIES)
- set(CHECK_CXX_SOURCE_COMPILES_ADD_LIBRARIES
- LINK_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES})
- else()
- set(CHECK_CXX_SOURCE_COMPILES_ADD_LIBRARIES)
- endif()
- if(CMAKE_REQUIRED_INCLUDES)
- set(CHECK_CXX_SOURCE_COMPILES_ADD_INCLUDES
- "-DINCLUDE_DIRECTORIES:STRING=${CMAKE_REQUIRED_INCLUDES}")
- else()
- set(CHECK_CXX_SOURCE_COMPILES_ADD_INCLUDES)
- endif()
- file(WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.cxx"
- "${SOURCE}\n")
-
- if(NOT CMAKE_REQUIRED_QUIET)
- message(CHECK_START "Performing Test ${VAR}")
- endif()
- try_compile(${VAR}
- ${CMAKE_BINARY_DIR}
- ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.cxx
- COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}
- ${CHECK_CXX_SOURCE_COMPILES_ADD_LINK_OPTIONS}
- ${CHECK_CXX_SOURCE_COMPILES_ADD_LIBRARIES}
- CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_FUNCTION_DEFINITIONS}
- "${CHECK_CXX_SOURCE_COMPILES_ADD_INCLUDES}"
- OUTPUT_VARIABLE OUTPUT)
-
- foreach(_regex ${_FAIL_REGEX})
- if("${OUTPUT}" MATCHES "${_regex}")
- set(${VAR} 0)
- endif()
- endforeach()
-
- if(${VAR})
- set(${VAR} 1 CACHE INTERNAL "Test ${VAR}")
- if(NOT CMAKE_REQUIRED_QUIET)
- message(CHECK_PASS "Success")
- endif()
- file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
- "Performing C++ SOURCE FILE Test ${VAR} succeeded with the following output:\n"
- "${OUTPUT}\n"
- "Source file was:\n${SOURCE}\n")
- else()
- if(NOT CMAKE_REQUIRED_QUIET)
- message(CHECK_FAIL "Failed")
- endif()
- set(${VAR} "" CACHE INTERNAL "Test ${VAR}")
- file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
- "Performing C++ SOURCE FILE Test ${VAR} failed with the following output:\n"
- "${OUTPUT}\n"
- "Source file was:\n${SOURCE}\n")
- endif()
- endif()
+ check_source_compiles(CXX "${SOURCE}" ${VAR} ${ARGN})
endmacro()
diff --git a/Modules/CheckFortranSourceCompiles.cmake b/Modules/CheckFortranSourceCompiles.cmake
index d776b0c13b..2bcc34310f 100644
--- a/Modules/CheckFortranSourceCompiles.cmake
+++ b/Modules/CheckFortranSourceCompiles.cmake
@@ -87,82 +87,8 @@ Check if given Fortran source compiles and links into an executable.
#]=======================================================================]
include_guard(GLOBAL)
+include(CheckSourceCompiles)
macro(CHECK_Fortran_SOURCE_COMPILES SOURCE VAR)
- if(NOT DEFINED "${VAR}")
- set(_FAIL_REGEX)
- set(_SRC_EXT)
- set(_key)
- foreach(arg ${ARGN})
- if("${arg}" MATCHES "^(FAIL_REGEX|SRC_EXT)$")
- set(_key "${arg}")
- elseif(_key)
- list(APPEND _${_key} "${arg}")
- else()
- message(FATAL_ERROR "Unknown argument:\n ${arg}\n")
- endif()
- endforeach()
- if(NOT _SRC_EXT)
- set(_SRC_EXT F)
- endif()
- if(CMAKE_REQUIRED_LINK_OPTIONS)
- set(CHECK_Fortran_SOURCE_COMPILES_ADD_LINK_OPTIONS
- LINK_OPTIONS ${CMAKE_REQUIRED_LINK_OPTIONS})
- else()
- set(CHECK_Fortran_SOURCE_COMPILES_ADD_LINK_OPTIONS)
- endif()
- if(CMAKE_REQUIRED_LIBRARIES)
- set(CHECK_Fortran_SOURCE_COMPILES_ADD_LIBRARIES
- LINK_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES})
- else()
- set(CHECK_Fortran_SOURCE_COMPILES_ADD_LIBRARIES)
- endif()
- if(CMAKE_REQUIRED_INCLUDES)
- set(CHECK_Fortran_SOURCE_COMPILES_ADD_INCLUDES
- "-DINCLUDE_DIRECTORIES:STRING=${CMAKE_REQUIRED_INCLUDES}")
- else()
- set(CHECK_Fortran_SOURCE_COMPILES_ADD_INCLUDES)
- endif()
- file(WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.${_SRC_EXT}"
- "${SOURCE}\n")
-
- if(NOT CMAKE_REQUIRED_QUIET)
- message(CHECK_START "Performing Test ${VAR}")
- endif()
- try_compile(${VAR}
- ${CMAKE_BINARY_DIR}
- ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.${_SRC_EXT}
- COMPILE_DEFINITIONS -D${VAR} ${CMAKE_REQUIRED_DEFINITIONS}
- ${CHECK_Fortran_SOURCE_COMPILES_ADD_LINK_OPTIONS}
- ${CHECK_Fortran_SOURCE_COMPILES_ADD_LIBRARIES}
- CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${CMAKE_REQUIRED_FLAGS}
- "${CHECK_Fortran_SOURCE_COMPILES_ADD_INCLUDES}"
- OUTPUT_VARIABLE OUTPUT)
-
- foreach(_regex ${_FAIL_REGEX})
- if("${OUTPUT}" MATCHES "${_regex}")
- set(${VAR} 0)
- endif()
- endforeach()
-
- if(${VAR})
- set(${VAR} 1 CACHE INTERNAL "Test ${VAR}")
- if(NOT CMAKE_REQUIRED_QUIET)
- message(CHECK_PASS "Success")
- endif()
- file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
- "Performing Fortran SOURCE FILE Test ${VAR} succeeded with the following output:\n"
- "${OUTPUT}\n"
- "Source file was:\n${SOURCE}\n")
- else()
- if(NOT CMAKE_REQUIRED_QUIET)
- message(CHECK_FAIL "Failed")
- endif()
- set(${VAR} "" CACHE INTERNAL "Test ${VAR}")
- file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
- "Performing Fortran SOURCE FILE Test ${VAR} failed with the following output:\n"
- "${OUTPUT}\n"
- "Source file was:\n${SOURCE}\n")
- endif()
- endif()
+ check_source_compiles(Fortran "${SOURCE}" ${VAR} ${ARGN})
endmacro()
diff --git a/Modules/CheckLinkerFlag.cmake b/Modules/CheckLinkerFlag.cmake
index cd7301f941..051e0bcf5c 100644
--- a/Modules/CheckLinkerFlag.cmake
+++ b/Modules/CheckLinkerFlag.cmake
@@ -51,7 +51,7 @@ function(CHECK_LINKER_FLAG _lang _flag _var)
return()
endif()
- include (Check${_lang}SourceCompiles)
+ include (CheckSourceCompiles)
set(CMAKE_REQUIRED_LINK_OPTIONS "${_flag}")
@@ -74,7 +74,7 @@ function(CHECK_LINKER_FLAG _lang _flag _var)
endif()
check_compiler_flag_common_patterns(_common_patterns)
- cmake_language (CALL check_${_lang}_source_compiles "${_source}" ${_var} ${_common_patterns})
+ check_source_compiles(${_lang} "${_source}" ${_var} ${_common_patterns})
foreach(v IN LISTS _locale_vars)
set(ENV{${v}} ${_locale_vars_saved_${v}})
diff --git a/Modules/CheckOBJCSourceCompiles.cmake b/Modules/CheckOBJCSourceCompiles.cmake
index 502ed74725..aad2bdce7a 100644
--- a/Modules/CheckOBJCSourceCompiles.cmake
+++ b/Modules/CheckOBJCSourceCompiles.cmake
@@ -68,80 +68,8 @@ Check if given Objective-C source compiles and links into an executable.
#]=======================================================================]
include_guard(GLOBAL)
+include(CheckSourceCompiles)
macro(CHECK_OBJC_SOURCE_COMPILES SOURCE VAR)
- if(NOT DEFINED "${VAR}")
- set(_FAIL_REGEX)
- set(_key)
- foreach(arg ${ARGN})
- if("${arg}" MATCHES "^(FAIL_REGEX)$")
- set(_key "${arg}")
- elseif(_key)
- list(APPEND _${_key} "${arg}")
- else()
- message(FATAL_ERROR "Unknown argument:\n ${arg}\n")
- endif()
- endforeach()
- set(MACRO_CHECK_FUNCTION_DEFINITIONS
- "-D${VAR} ${CMAKE_REQUIRED_FLAGS}")
- if(CMAKE_REQUIRED_LINK_OPTIONS)
- set(CHECK_OBJC_SOURCE_COMPILES_ADD_LINK_OPTIONS
- LINK_OPTIONS ${CMAKE_REQUIRED_LINK_OPTIONS})
- else()
- set(CHECK_OBJC_SOURCE_COMPILES_ADD_LINK_OPTIONS)
- endif()
- if(CMAKE_REQUIRED_LIBRARIES)
- set(CHECK_OBJC_SOURCE_COMPILES_ADD_LIBRARIES
- LINK_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES})
- else()
- set(CHECK_OBJC_SOURCE_COMPILES_ADD_LIBRARIES)
- endif()
- if(CMAKE_REQUIRED_INCLUDES)
- set(CHECK_OBJC_SOURCE_COMPILES_ADD_INCLUDES
- "-DINCLUDE_DIRECTORIES:STRING=${CMAKE_REQUIRED_INCLUDES}")
- else()
- set(CHECK_OBJC_SOURCE_COMPILES_ADD_INCLUDES)
- endif()
- file(WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.m"
- "${SOURCE}\n")
-
- if(NOT CMAKE_REQUIRED_QUIET)
- message(CHECK_START "Performing Test ${VAR}")
- endif()
- try_compile(${VAR}
- ${CMAKE_BINARY_DIR}
- ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.m
- COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}
- ${CHECK_OBJC_SOURCE_COMPILES_ADD_LINK_OPTIONS}
- ${CHECK_OBJC_SOURCE_COMPILES_ADD_LIBRARIES}
- CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_FUNCTION_DEFINITIONS}
- "${CHECK_OBJC_SOURCE_COMPILES_ADD_INCLUDES}"
- OUTPUT_VARIABLE OUTPUT)
-
- foreach(_regex ${_FAIL_REGEX})
- if("${OUTPUT}" MATCHES "${_regex}")
- set(${VAR} 0)
- endif()
- endforeach()
-
- if(${VAR})
- set(${VAR} 1 CACHE INTERNAL "Test ${VAR}")
- if(NOT CMAKE_REQUIRED_QUIET)
- message(CHECK_PASS "Success")
- endif()
- file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
- "Performing Objective-C SOURCE FILE Test ${VAR} succeeded with the following output:\n"
- "${OUTPUT}\n"
- "Source file was:\n${SOURCE}\n")
- else()
- if(NOT CMAKE_REQUIRED_QUIET)
- message(CHECK_FAIL "Failed")
- endif()
- set(${VAR} "" CACHE INTERNAL "Test ${VAR}")
- file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
- "Performing Objective-C SOURCE FILE Test ${VAR} failed with the following output:\n"
- "${OUTPUT}\n"
- "Source file was:\n${SOURCE}\n")
- endif()
- endif()
+ check_source_compiles(OBJC "${SOURCE}" ${VAR} ${ARGN})
endmacro()
diff --git a/Modules/CheckOBJCXXSourceCompiles.cmake b/Modules/CheckOBJCXXSourceCompiles.cmake
index 7b839e4cbf..37dabfe5ec 100644
--- a/Modules/CheckOBJCXXSourceCompiles.cmake
+++ b/Modules/CheckOBJCXXSourceCompiles.cmake
@@ -68,81 +68,8 @@ Check if given Objective-C++ source compiles and links into an executable.
#]=======================================================================]
include_guard(GLOBAL)
+include(CheckSourceCompiles)
macro(CHECK_OBJCXX_SOURCE_COMPILES SOURCE VAR)
- if(NOT DEFINED "${VAR}")
- set(_FAIL_REGEX)
- set(_key)
- foreach(arg ${ARGN})
- if("${arg}" MATCHES "^(FAIL_REGEX)$")
- set(_key "${arg}")
- elseif(_key)
- list(APPEND _${_key} "${arg}")
- else()
- message(FATAL_ERROR "Unknown argument:\n ${arg}\n")
- endif()
- endforeach()
-
- set(MACRO_CHECK_FUNCTION_DEFINITIONS
- "-D${VAR} ${CMAKE_REQUIRED_FLAGS}")
- if(CMAKE_REQUIRED_LINK_OPTIONS)
- set(CHECK_OBJCXX_SOURCE_COMPILES_ADD_LINK_OPTIONS
- LINK_OPTIONS ${CMAKE_REQUIRED_LINK_OPTIONS})
- else()
- set(CHECK_OBJCXX_SOURCE_COMPILES_ADD_LINK_OPTIONS)
- endif()
- if(CMAKE_REQUIRED_LIBRARIES)
- set(CHECK_OBJCXX_SOURCE_COMPILES_ADD_LIBRARIES
- LINK_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES})
- else()
- set(CHECK_OBJCXX_SOURCE_COMPILES_ADD_LIBRARIES)
- endif()
- if(CMAKE_REQUIRED_INCLUDES)
- set(CHECK_OBJCXX_SOURCE_COMPILES_ADD_INCLUDES
- "-DINCLUDE_DIRECTORIES:STRING=${CMAKE_REQUIRED_INCLUDES}")
- else()
- set(CHECK_OBJCXX_SOURCE_COMPILES_ADD_INCLUDES)
- endif()
- file(WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.mm"
- "${SOURCE}\n")
-
- if(NOT CMAKE_REQUIRED_QUIET)
- message(CHECK_START "Performing Test ${VAR}")
- endif()
- try_compile(${VAR}
- ${CMAKE_BINARY_DIR}
- ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.mm
- COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}
- ${CHECK_OBJCXX_SOURCE_COMPILES_ADD_LINK_OPTIONS}
- ${CHECK_OBJCXX_SOURCE_COMPILES_ADD_LIBRARIES}
- CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_FUNCTION_DEFINITIONS}
- "${CHECK_OBJCXX_SOURCE_COMPILES_ADD_INCLUDES}"
- OUTPUT_VARIABLE OUTPUT)
-
- foreach(_regex ${_FAIL_REGEX})
- if("${OUTPUT}" MATCHES "${_regex}")
- set(${VAR} 0)
- endif()
- endforeach()
-
- if(${VAR})
- set(${VAR} 1 CACHE INTERNAL "Test ${VAR}")
- if(NOT CMAKE_REQUIRED_QUIET)
- message(CHECK_PASS "Success")
- endif()
- file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
- "Performing Objective-C++ SOURCE FILE Test ${VAR} succeeded with the following output:\n"
- "${OUTPUT}\n"
- "Source file was:\n${SOURCE}\n")
- else()
- if(NOT CMAKE_REQUIRED_QUIET)
- message(CHECK_FAIL "Failed")
- endif()
- set(${VAR} "" CACHE INTERNAL "Test ${VAR}")
- file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
- "Performing Objective-C++ SOURCE FILE Test ${VAR} failed with the following output:\n"
- "${OUTPUT}\n"
- "Source file was:\n${SOURCE}\n")
- endif()
- endif()
+ check_source_compiles(OBJCXX "${SOURCE}" ${VAR} ${ARGN})
endmacro()
diff --git a/Modules/CheckSourceCompiles.cmake b/Modules/CheckSourceCompiles.cmake
new file mode 100644
index 0000000000..13ec9dba92
--- /dev/null
+++ b/Modules/CheckSourceCompiles.cmake
@@ -0,0 +1,192 @@
+# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+
+
+#[=======================================================================[.rst:
+CheckSourceCompiles
+----------------------
+
+.. versionadded:: 3.19
+
+Check if given source compiles and links into an executable.
+
+.. command:: check_source_compiles
+
+ .. code-block:: cmake
+
+ check_source_compiles(<lang> <code> <resultVar>
+ [FAIL_REGEX <regex1> [<regex2>...]]
+ [SRC_EXT <extension>])
+
+ Check that the source supplied in ``<code>`` can be compiled as a source
+ file for the requested language and linked as an executable (so it must
+ contain at least a ``main()`` function). The result will be stored in the
+ internal cache variable specified by ``<resultVar>``, with a boolean true
+ value for success and boolean false for failure. If ``FAIL_REGEX`` is
+ provided, then failure is determined by checking if anything in the output
+ matches any of the specified regular expressions.
+
+ By default, the test source file will be given a file extension that matches
+ the requested language. The ``SRC_EXT`` option can be used to override this
+ with ``.<extension>`` instead.
+
+ The underlying check is performed by the :command:`try_compile` command. The
+ compile and link commands can be influenced by setting any of the following
+ variables prior to calling ``check_source_compiles()``:
+
+ ``CMAKE_REQUIRED_FLAGS``
+ Additional flags to pass to the compiler. Note that the contents of
+ :variable:`CMAKE_<LANG>_FLAGS <CMAKE_<LANG>_FLAGS>` and its associated
+ configuration-specific variable are automatically added to the compiler
+ command before the contents of ``CMAKE_REQUIRED_FLAGS``.
+
+ ``CMAKE_REQUIRED_DEFINITIONS``
+ A :ref:`;-list <CMake Language Lists>` of compiler definitions of the form
+ ``-DFOO`` or ``-DFOO=bar``. A definition for the name specified by
+ ``<resultVar>`` will also be added automatically.
+
+ ``CMAKE_REQUIRED_INCLUDES``
+ A :ref:`;-list <CMake Language Lists>` of header search paths to pass to
+ the compiler. These will be the only header search paths used by
+ ``try_compile()``, i.e. the contents of the :prop_dir:`INCLUDE_DIRECTORIES`
+ directory property will be ignored.
+
+ ``CMAKE_REQUIRED_LINK_OPTIONS``
+ A :ref:`;-list <CMake Language Lists>` of options to add to the link
+ command (see :command:`try_compile` for further details).
+
+ ``CMAKE_REQUIRED_LIBRARIES``
+ A :ref:`;-list <CMake Language Lists>` of libraries to add to the link
+ command. These can be the name of system libraries or they can be
+ :ref:`Imported Targets <Imported Targets>` (see :command:`try_compile` for
+ further details).
+
+ ``CMAKE_REQUIRED_QUIET``
+ If this variable evaluates to a boolean true value, all status messages
+ associated with the check will be suppressed.
+
+ The check is only performed once, with the result cached in the variable
+ named by ``<resultVar>``. Every subsequent CMake run will re-use this cached
+ value rather than performing the check again, even if the ``<code>`` changes.
+ In order to force the check to be re-evaluated, the variable named by
+ ``<resultVar>`` must be manually removed from the cache.
+
+#]=======================================================================]
+
+
+include_guard(GLOBAL)
+
+cmake_policy(PUSH)
+cmake_policy(SET CMP0054 NEW) # if() quoted variables not dereferenced
+cmake_policy(SET CMP0057 NEW) # if() supports IN_LIST
+
+function(CHECK_SOURCE_COMPILES _lang _source _var)
+ if(NOT DEFINED "${_var}")
+
+ if(_lang STREQUAL C)
+ set(_lang_textual "C")
+ set(_lang_ext "c")
+ elseif(_lang STREQUAL CXX)
+ set(_lang_textual "C++")
+ set(_lang_ext "cxx")
+ elseif(_lang STREQUAL Fortran)
+ set(_lang_textual "Fortran")
+ set(_lang_ext "F")
+ elseif(_lang STREQUAL OBJC)
+ set(_lang_textual "Objective-C")
+ set(_lang_ext "m")
+ elseif(_lang STREQUAL OBJCXX)
+ set(_lang_textual "Objective-C++")
+ set(_lang_ext "mm")
+ else()
+ message (SEND_ERROR "check_source_compiles: ${_lang}: unknown language.")
+ return()
+ endif()
+
+ get_property (_supported_languages GLOBAL PROPERTY ENABLED_LANGUAGES)
+ if (NOT _lang IN_LIST _supported_languages)
+ message (SEND_ERROR "check_source_compiles: ${_lang}: needs to be enabled before use.")
+ return()
+ endif()
+
+ set(_FAIL_REGEX)
+ set(_SRC_EXT)
+ set(_key)
+ foreach(arg ${ARGN})
+ if("${arg}" MATCHES "^(FAIL_REGEX|SRC_EXT)$")
+ set(_key "${arg}")
+ elseif(_key)
+ list(APPEND _${_key} "${arg}")
+ else()
+ message(FATAL_ERROR "Unknown argument:\n ${arg}\n")
+ endif()
+ endforeach()
+
+ if(NOT _SRC_EXT)
+ set(_SRC_EXT ${_lang_ext})
+ endif()
+
+ if(CMAKE_REQUIRED_LINK_OPTIONS)
+ set(CHECK_${LANG}_SOURCE_COMPILES_ADD_LINK_OPTIONS
+ LINK_OPTIONS ${CMAKE_REQUIRED_LINK_OPTIONS})
+ else()
+ set(CHECK_${LANG}_SOURCE_COMPILES_ADD_LINK_OPTIONS)
+ endif()
+ if(CMAKE_REQUIRED_LIBRARIES)
+ set(CHECK_${LANG}_SOURCE_COMPILES_ADD_LIBRARIES
+ LINK_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES})
+ else()
+ set(CHECK_${LANG}_SOURCE_COMPILES_ADD_LIBRARIES)
+ endif()
+ if(CMAKE_REQUIRED_INCLUDES)
+ set(CHECK_${LANG}_SOURCE_COMPILES_ADD_INCLUDES
+ "-DINCLUDE_DIRECTORIES:STRING=${CMAKE_REQUIRED_INCLUDES}")
+ else()
+ set(CHECK_${LANG}_SOURCE_COMPILES_ADD_INCLUDES)
+ endif()
+ file(WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.${_SRC_EXT}"
+ "${_source}\n")
+
+ if(NOT CMAKE_REQUIRED_QUIET)
+ message(CHECK_START "Performing Test ${_var}")
+ endif()
+ try_compile(${_var}
+ ${CMAKE_BINARY_DIR}
+ ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.${_SRC_EXT}
+ COMPILE_DEFINITIONS -D${_var} ${CMAKE_REQUIRED_DEFINITIONS}
+ ${CHECK_${LANG}_SOURCE_COMPILES_ADD_LINK_OPTIONS}
+ ${CHECK_${LANG}_SOURCE_COMPILES_ADD_LIBRARIES}
+ CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${CMAKE_REQUIRED_FLAGS}
+ "${CHECK_${LANG}_SOURCE_COMPILES_ADD_INCLUDES}"
+ OUTPUT_VARIABLE OUTPUT)
+
+ foreach(_regex ${_FAIL_REGEX})
+ if("${OUTPUT}" MATCHES "${_regex}")
+ set(${_var} 0)
+ endif()
+ endforeach()
+
+ if(${_var})
+ set(${_var} 1 CACHE INTERNAL "Test ${_var}")
+ if(NOT CMAKE_REQUIRED_QUIET)
+ message(CHECK_PASS "Success")
+ endif()
+ file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+ "Performing ${_lang_textual} SOURCE FILE Test ${_var} succeeded with the following output:\n"
+ "${OUTPUT}\n"
+ "Source file was:\n${_source}\n")
+ else()
+ if(NOT CMAKE_REQUIRED_QUIET)
+ message(CHECK_FAIL "Failed")
+ endif()
+ set(${_var} "" CACHE INTERNAL "Test ${_var}")
+ file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+ "Performing ${_lang_textual} SOURCE FILE Test ${_var} failed with the following output:\n"
+ "${OUTPUT}\n"
+ "Source file was:\n${_source}\n")
+ endif()
+ endif()
+
+endfunction()
+
+cmake_policy(POP)
diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt
index ff0ae62a7e..a8b76b4e31 100644
--- a/Tests/RunCMake/CMakeLists.txt
+++ b/Tests/RunCMake/CMakeLists.txt
@@ -534,6 +534,7 @@ add_RunCMake_test(target_compile_features)
add_RunCMake_test(target_compile_options -DCMAKE_C_COMPILER_ID=${CMAKE_C_COMPILER_ID})
add_RunCMake_test(target_include_directories)
add_RunCMake_test(target_sources)
+add_RunCMake_test(CheckSourceCompiles)
add_RunCMake_test(CheckModules)
add_RunCMake_test(CheckIPOSupported)
if (CMAKE_SYSTEM_NAME MATCHES "(Linux|Darwin)"
@@ -542,6 +543,7 @@ if (CMAKE_SYSTEM_NAME MATCHES "(Linux|Darwin)"
-DCMAKE_Fortran_COMPILER_ID=${CMAKE_Fortran_COMPILER_ID})
endif()
+
add_RunCMake_test(CommandLine -DCMAKE_SYSTEM_NAME=${CMAKE_SYSTEM_NAME} -DCYGWIN=${CYGWIN} -DPYTHON_EXECUTABLE=${PYTHON_EXECUTABLE})
add_RunCMake_test(CommandLineTar)
diff --git a/Tests/RunCMake/CheckSourceCompiles/CMakeLists.txt b/Tests/RunCMake/CheckSourceCompiles/CMakeLists.txt
new file mode 100644
index 0000000000..0421e28036
--- /dev/null
+++ b/Tests/RunCMake/CheckSourceCompiles/CMakeLists.txt
@@ -0,0 +1,5 @@
+cmake_minimum_required(VERSION 3.13)
+
+project(${RunCMake_TEST} LANGUAGES NONE)
+
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/CheckSourceCompiles/CheckCSourceCompiles.cmake b/Tests/RunCMake/CheckSourceCompiles/CheckCSourceCompiles.cmake
new file mode 100644
index 0000000000..cf461893cd
--- /dev/null
+++ b/Tests/RunCMake/CheckSourceCompiles/CheckCSourceCompiles.cmake
@@ -0,0 +1,13 @@
+
+enable_language (C)
+include(CheckSourceCompiles)
+
+check_source_compiles(C "I don't build" SHOULD_FAIL)
+if(SHOULD_FAIL)
+ message(SEND_ERROR "invalid C source didn't fail.")
+endif()
+
+check_source_compiles(C "int main() {return 0;}" SHOULD_BUILD)
+if(NOT SHOULD_BUILD)
+ message(SEND_ERROR "Test fail for valid C source.")
+endif()
diff --git a/Tests/RunCMake/CheckSourceCompiles/CheckCXXSourceCompiles.cmake b/Tests/RunCMake/CheckSourceCompiles/CheckCXXSourceCompiles.cmake
new file mode 100644
index 0000000000..ec01d42f71
--- /dev/null
+++ b/Tests/RunCMake/CheckSourceCompiles/CheckCXXSourceCompiles.cmake
@@ -0,0 +1,26 @@
+
+enable_language (CXX)
+include(CheckSourceCompiles)
+
+check_source_compiles(CXX "I don't build" SHOULD_FAIL)
+if(SHOULD_FAIL)
+ message(SEND_ERROR "invalid CXX source didn't fail.")
+endif()
+
+check_source_compiles(CXX [=[
+ #include <vector>
+ int main() {
+ return 0;
+ }
+]=]
+ SHOULD_BUILD)
+if(NOT SHOULD_BUILD)
+ message(SEND_ERROR "Test fail for valid CXX source.")
+endif()
+
+check_source_compiles(CXX "void l(char const (&x)[2]){}; int main() { l(\"\\n\"); return 0;}"
+ SHOULD_BUILD_COMPLEX)
+
+if(NOT SHOULD_BUILD_COMPLEX)
+ message(SEND_ERROR "Test fail for valid CXX complex source.")
+endif()
diff --git a/Tests/RunCMake/CheckSourceCompiles/CheckFortranSourceCompiles.cmake b/Tests/RunCMake/CheckSourceCompiles/CheckFortranSourceCompiles.cmake
new file mode 100644
index 0000000000..1d4e16d45d
--- /dev/null
+++ b/Tests/RunCMake/CheckSourceCompiles/CheckFortranSourceCompiles.cmake
@@ -0,0 +1,14 @@
+
+
+enable_language (Fortran)
+include(CheckSourceCompiles)
+
+check_source_compiles(Fortran [=[
+ PROGRAM TEST_HAVE_PRINT
+ PRINT *, 'Hello'
+ END
+]=] SHOULD_BUILD)
+
+if(NOT SHOULD_BUILD)
+ message(SEND_ERROR "Test fail for valid Fortran source.")
+endif()
diff --git a/Tests/RunCMake/CheckSourceCompiles/CheckOBJCSourceCompiles.cmake b/Tests/RunCMake/CheckSourceCompiles/CheckOBJCSourceCompiles.cmake
new file mode 100644
index 0000000000..2f53cfc4f6
--- /dev/null
+++ b/Tests/RunCMake/CheckSourceCompiles/CheckOBJCSourceCompiles.cmake
@@ -0,0 +1,14 @@
+enable_language (OBJC)
+include(CheckSourceCompiles)
+
+check_source_compiles(OBJC [[
+ #import <Foundation/Foundation.h>
+ int main() {
+ NSObject *foo;
+ return 0;
+ }
+]] SHOULD_BUILD)
+
+if(NOT SHOULD_BUILD)
+ message(SEND_ERROR "Test fail for valid OBJC source.")
+endif()
diff --git a/Tests/RunCMake/CheckSourceCompiles/CheckOBJCXXSourceCompiles.cmake b/Tests/RunCMake/CheckSourceCompiles/CheckOBJCXXSourceCompiles.cmake
new file mode 100644
index 0000000000..805d5136cb
--- /dev/null
+++ b/Tests/RunCMake/CheckSourceCompiles/CheckOBJCXXSourceCompiles.cmake
@@ -0,0 +1,17 @@
+enable_language (OBJCXX)
+include(CheckSourceCompiles)
+
+check_source_compiles(OBJCXX [[
+ #include <vector>
+ #import <Foundation/Foundation.h>
+ int main() {
+ std::vector<int> v;
+ NSObject *foo;
+ return 0;
+ }
+]] SHOULD_BUILD)
+
+
+if(NOT SHOULD_BUILD)
+ message(SEND_ERROR "Test fail for OBJCXX source.")
+endif()
diff --git a/Tests/RunCMake/CheckSourceCompiles/NonExistentLanguage-result.txt b/Tests/RunCMake/CheckSourceCompiles/NonExistentLanguage-result.txt
new file mode 100644
index 0000000000..d00491fd7e
--- /dev/null
+++ b/Tests/RunCMake/CheckSourceCompiles/NonExistentLanguage-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CheckSourceCompiles/NonExistentLanguage-stderr.txt b/Tests/RunCMake/CheckSourceCompiles/NonExistentLanguage-stderr.txt
new file mode 100644
index 0000000000..bf2ea8233a
--- /dev/null
+++ b/Tests/RunCMake/CheckSourceCompiles/NonExistentLanguage-stderr.txt
@@ -0,0 +1,2 @@
+CMake Error at .*CheckSourceCompiles\.cmake:[0-9]+ \(message\):
+ check_source_compiles: FAKE_LANG: unknown language.
diff --git a/Tests/RunCMake/CheckSourceCompiles/NonExistentLanguage.cmake b/Tests/RunCMake/CheckSourceCompiles/NonExistentLanguage.cmake
new file mode 100644
index 0000000000..fc7de06979
--- /dev/null
+++ b/Tests/RunCMake/CheckSourceCompiles/NonExistentLanguage.cmake
@@ -0,0 +1,3 @@
+
+include(CheckSourceCompiles)
+check_source_compiles(FAKE_LANG "int main() {return 0;}" SHOULD_BUILD)
diff --git a/Tests/RunCMake/CheckSourceCompiles/NotEnabledLanguage-result.txt b/Tests/RunCMake/CheckSourceCompiles/NotEnabledLanguage-result.txt
new file mode 100644
index 0000000000..d00491fd7e
--- /dev/null
+++ b/Tests/RunCMake/CheckSourceCompiles/NotEnabledLanguage-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CheckSourceCompiles/NotEnabledLanguage-stderr.txt b/Tests/RunCMake/CheckSourceCompiles/NotEnabledLanguage-stderr.txt
new file mode 100644
index 0000000000..ebc983ae32
--- /dev/null
+++ b/Tests/RunCMake/CheckSourceCompiles/NotEnabledLanguage-stderr.txt
@@ -0,0 +1,2 @@
+CMake Error at .*CheckSourceCompiles\.cmake:[0-9]+ \(message\):
+ check_source_compiles: C: needs to be enabled before use.
diff --git a/Tests/RunCMake/CheckSourceCompiles/NotEnabledLanguage.cmake b/Tests/RunCMake/CheckSourceCompiles/NotEnabledLanguage.cmake
new file mode 100644
index 0000000000..dec0db363d
--- /dev/null
+++ b/Tests/RunCMake/CheckSourceCompiles/NotEnabledLanguage.cmake
@@ -0,0 +1,3 @@
+
+include(CheckSourceCompiles)
+check_source_compiles(C "int main() {return 0;}" SHOULD_BUILD)
diff --git a/Tests/RunCMake/CheckSourceCompiles/RunCMakeTest.cmake b/Tests/RunCMake/CheckSourceCompiles/RunCMakeTest.cmake
new file mode 100644
index 0000000000..bf32828609
--- /dev/null
+++ b/Tests/RunCMake/CheckSourceCompiles/RunCMakeTest.cmake
@@ -0,0 +1,16 @@
+include(RunCMake)
+
+run_cmake(NotEnabledLanguage)
+run_cmake(NonExistentLanguage)
+
+run_cmake(CheckCSourceCompiles)
+run_cmake(CheckCXXSourceCompiles)
+
+if (APPLE)
+ run_cmake(CheckOBJCSourceCompiles)
+ run_cmake(CheckOBJCXXSourceCompiles)
+endif()
+
+if (CMAKE_Fortran_COMPILER_ID)
+ run_cmake(CheckFortranSourceCompiles)
+endif()