|
| 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 | +#[=======================================================================[.rst: |
| 5 | +CheckSwiftSourceCompiles |
| 6 | +---------------------- |
| 7 | +
|
| 8 | +Check if given Swift source compiles and links into an executable. |
| 9 | +
|
| 10 | +.. command:: check_swift_source_compiles |
| 11 | +
|
| 12 | + .. code-block:: cmake |
| 13 | +
|
| 14 | + check_swift_source_compiles(<code> <resultVar> |
| 15 | + [FAIL_REGEX <regex1> [<regex2>...]]) |
| 16 | +
|
| 17 | + Check that the source supplied in ``<code>`` can be compiled as a Swift source |
| 18 | + file and linked as an executable. The result will be stored in the internal |
| 19 | + cache variable specified by ``<resultVar>``, with a boolean true value for |
| 20 | + success and boolean false for failure. If ``FAIL_REGEX`` is provided, then |
| 21 | + failure is determined by checking if anything in the output matches any of the |
| 22 | + specified regular expressions. |
| 23 | +
|
| 24 | + The underlying check is performed by the :command:`try_compile` command. The |
| 25 | + compile and link commands can be influenced by setting any of the following |
| 26 | + variables prior to calling ``check_swift_source_compiles()``: |
| 27 | +
|
| 28 | + ``CMAKE_REQUIRED_FLAGS`` |
| 29 | + Additional flags to pass to the compiler. Note that the contents of |
| 30 | + :variable:`CMAKE_Swift_FLAGS <CMAKE_<LANG>_FLAGS>` and its associated |
| 31 | + configuration-specific variable are automatically added to the compiler |
| 32 | + command before the contents of ``CMAKE_REQUIRED_FLAGS``. |
| 33 | +
|
| 34 | + ``CMAKE_REQUIRED_DEFINITIONS`` |
| 35 | + A :ref:`;-list <CMake Language Lists>` of compiler definitions of the form |
| 36 | + ``-DFOO`` or ``-DFOO=bar``. A definition for the name specified by |
| 37 | + ``<resultVar>`` will also be added automatically. |
| 38 | +
|
| 39 | + ``CMAKE_REQUIRED_INCLUDES`` |
| 40 | + A :ref:`;-list <CMake Language Lists>` of header search paths to pass to |
| 41 | + the compiler. These will be the only header search paths used by |
| 42 | + ``try_compile()``, i.e. the contents of the :prop_dir:`INCLUDE_DIRECTORIES` |
| 43 | + directory property will be ignored. |
| 44 | +
|
| 45 | + ``CMAKE_REQUIRED_LINK_OPTIONS`` |
| 46 | + A :ref:`;-list <CMake Language Lists>` of options to add to the link |
| 47 | + command (see :command:`try_compile` for further details). |
| 48 | +
|
| 49 | + ``CMAKE_REQUIRED_LIBRARIES`` |
| 50 | + A :ref:`;-list <CMake Language Lists>` of libraries to add to the link |
| 51 | + command. These can be the name of system libraries or they can be |
| 52 | + :ref:`Imported Targets <Imported Targets>` (see :command:`try_compile` for |
| 53 | + further details). |
| 54 | +
|
| 55 | + ``CMAKE_REQUIRED_QUIET`` |
| 56 | + If this variable evaluates to a boolean true value, all status messages |
| 57 | + associated with the check will be suppressed. |
| 58 | +
|
| 59 | + The check is only performed once, with the result cached in the variable |
| 60 | + named by ``<resultVar>``. Every subsequent CMake run will re-use this cached |
| 61 | + value rather than performing the check again, even if the ``<code>`` changes. |
| 62 | + In order to force the check to be re-evaluated, the variable named by |
| 63 | + ``<resultVar>`` must be manually removed from the cache. |
| 64 | +
|
| 65 | +#]=======================================================================] |
| 66 | + |
| 67 | +include_guard(GLOBAL) |
| 68 | + |
| 69 | +macro(CHECK_Swift_SOURCE_COMPILES SOURCE VAR) |
| 70 | + if(NOT DEFINED "${VAR}") |
| 71 | + set(_FAIL_REGEX) |
| 72 | + set(_key) |
| 73 | + foreach(arg ${ARGN}) |
| 74 | + if("${arg}" MATCHES "^(FAIL_REGEX)$") |
| 75 | + set(_key "${arg}") |
| 76 | + elseif(_key) |
| 77 | + list(APPEND _${_key} "${arg}") |
| 78 | + else() |
| 79 | + message(FATAL_ERROR "Unknown argument:\n ${arg}\n") |
| 80 | + endif() |
| 81 | + endforeach() |
| 82 | + |
| 83 | + set(MACRO_CHECK_FUNCTION_DEFINITIONS |
| 84 | + "-D${VAR} ${CMAKE_REQUIRED_FLAGS}") |
| 85 | + if(CMAKE_REQUIRED_LINK_OPTIONS) |
| 86 | + set(CHECK_Swift_SOURCE_COMPILES_ADD_LINK_OPTIONS |
| 87 | + LINK_OPTIONS ${CMAKE_REQUIRED_LINK_OPTIONS}) |
| 88 | + else() |
| 89 | + set(CHECK_Swift_SOURCE_COMPILES_ADD_LINK_OPTIONS) |
| 90 | + endif() |
| 91 | + if(CMAKE_REQUIRED_LIBRARIES) |
| 92 | + set(CHECK_Swift_SOURCE_COMPILES_ADD_LIBRARIES |
| 93 | + LINK_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES}) |
| 94 | + else() |
| 95 | + set(CHECK_Swift_SOURCE_COMPILES_ADD_LIBRARIES) |
| 96 | + endif() |
| 97 | + if(CMAKE_REQUIRED_INCLUDES) |
| 98 | + set(CHECK_Swift_SOURCE_COMPILES_ADD_INCLUDES |
| 99 | + "-DINCLUDE_DIRECTORIES:STRING=${CMAKE_REQUIRED_INCLUDES}") |
| 100 | + else() |
| 101 | + set(CHECK_Swift_SOURCE_COMPILES_ADD_INCLUDES) |
| 102 | + endif() |
| 103 | + file(WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.swift" |
| 104 | + "${SOURCE}\n") |
| 105 | + |
| 106 | + if(NOT CMAKE_REQUIRED_QUIET) |
| 107 | + message(CHECK_START "Performing Test ${VAR}") |
| 108 | + endif() |
| 109 | + try_compile(${VAR} |
| 110 | + ${CMAKE_BINARY_DIR} |
| 111 | + ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.swift |
| 112 | + COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS} |
| 113 | + ${CHECK_Swift_SOURCE_COMPILES_ADD_LINK_OPTIONS} |
| 114 | + ${CHECK_Swift_SOURCE_COMPILES_ADD_LIBRARIES} |
| 115 | + CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_FUNCTION_DEFINITIONS} |
| 116 | + "${CHECK_Swift_SOURCE_COMPILES_ADD_INCLUDES}" |
| 117 | + OUTPUT_VARIABLE OUTPUT) |
| 118 | + |
| 119 | + foreach(_regex ${_FAIL_REGEX}) |
| 120 | + if("${OUTPUT}" MATCHES "${_regex}") |
| 121 | + set(${VAR} 0) |
| 122 | + endif() |
| 123 | + endforeach() |
| 124 | + |
| 125 | + if(${VAR}) |
| 126 | + set(${VAR} 1 CACHE INTERNAL "Test ${VAR}") |
| 127 | + if(NOT CMAKE_REQUIRED_QUIET) |
| 128 | + message(CHECK_PASS "Success") |
| 129 | + endif() |
| 130 | + file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log |
| 131 | + "Performing Swift SOURCE FILE Test ${VAR} succeeded with the following output:\n" |
| 132 | + "${OUTPUT}\n" |
| 133 | + "Source file was:\n${SOURCE}\n") |
| 134 | + else() |
| 135 | + if(NOT CMAKE_REQUIRED_QUIET) |
| 136 | + message(CHECK_FAIL "Failed") |
| 137 | + endif() |
| 138 | + set(${VAR} "" CACHE INTERNAL "Test ${VAR}") |
| 139 | + file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log |
| 140 | + "Performing Swift SOURCE FILE Test ${VAR} failed with the following output:\n" |
| 141 | + "${OUTPUT}\n" |
| 142 | + "Source file was:\n${SOURCE}\n") |
| 143 | + endif() |
| 144 | + endif() |
| 145 | +endmacro() |
0 commit comments