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 5# determine the compiler to use for C programs 6# NOTE, a generator may set CMAKE_C_COMPILER before 7# loading this file to force a compiler. 8# use environment variable CC first if defined by user, next use 9# the cmake variable CMAKE_GENERATOR_CC which can be defined by a generator 10# as a default compiler 11# If the internal cmake variable _CMAKE_TOOLCHAIN_PREFIX is set, this is used 12# as prefix for the tools (e.g. arm-elf-gcc, arm-elf-ar etc.). This works 13# currently with the GNU crosscompilers. 14# 15# Sets the following variables: 16# CMAKE_C_COMPILER 17# CMAKE_AR 18# CMAKE_RANLIB 19# CMAKE_COMPILER_IS_GNUCC 20# 21# If not already set before, it also sets 22# _CMAKE_TOOLCHAIN_PREFIX 23 24include(${CMAKE_ROOT}/Modules/CMakeDetermineCompiler.cmake) 25 26# Load system-specific compiler preferences for this language. 27include(Platform/${CMAKE_SYSTEM_NAME}-Determine-C OPTIONAL) 28include(Platform/${CMAKE_SYSTEM_NAME}-C OPTIONAL) 29if(NOT CMAKE_C_COMPILER_NAMES) 30 set(CMAKE_C_COMPILER_NAMES cc) 31endif() 32 33if(${CMAKE_GENERATOR} MATCHES "Visual Studio") 34elseif("${CMAKE_GENERATOR}" MATCHES "Green Hills MULTI") 35elseif("${CMAKE_GENERATOR}" MATCHES "Xcode") 36 set(CMAKE_C_COMPILER_XCODE_TYPE sourcecode.c.c) 37 _cmake_find_compiler_path(C) 38else() 39 if(NOT CMAKE_C_COMPILER) 40 set(CMAKE_C_COMPILER_INIT NOTFOUND) 41 42 # prefer the environment variable CC 43 if(NOT $ENV{CC} STREQUAL "") 44 get_filename_component(CMAKE_C_COMPILER_INIT $ENV{CC} PROGRAM PROGRAM_ARGS CMAKE_C_FLAGS_ENV_INIT) 45 if(CMAKE_C_FLAGS_ENV_INIT) 46 set(CMAKE_C_COMPILER_ARG1 "${CMAKE_C_FLAGS_ENV_INIT}" CACHE STRING "Arguments to C compiler") 47 endif() 48 if(NOT EXISTS ${CMAKE_C_COMPILER_INIT}) 49 message(FATAL_ERROR "Could not find compiler set in environment variable CC:\n$ENV{CC}.") 50 endif() 51 endif() 52 53 # next try prefer the compiler specified by the generator 54 if(CMAKE_GENERATOR_CC) 55 if(NOT CMAKE_C_COMPILER_INIT) 56 set(CMAKE_C_COMPILER_INIT ${CMAKE_GENERATOR_CC}) 57 endif() 58 endif() 59 60 # finally list compilers to try 61 if(NOT CMAKE_C_COMPILER_INIT) 62 set(CMAKE_C_COMPILER_LIST ${_CMAKE_TOOLCHAIN_PREFIX}cc ${_CMAKE_TOOLCHAIN_PREFIX}gcc cl bcc xlc icx clang) 63 endif() 64 65 _cmake_find_compiler(C) 66 67 else() 68 _cmake_find_compiler_path(C) 69 endif() 70 mark_as_advanced(CMAKE_C_COMPILER) 71 72 # Each entry in this list is a set of extra flags to try 73 # adding to the compile line to see if it helps produce 74 # a valid identification file. 75 set(CMAKE_C_COMPILER_ID_TEST_FLAGS_FIRST) 76 set(CMAKE_C_COMPILER_ID_TEST_FLAGS 77 # Try compiling to an object file only. 78 "-c" 79 80 # Try enabling ANSI mode on HP. 81 "-Aa" 82 83 # Try compiling K&R-compatible code (needed by Bruce C Compiler). 84 "-D__CLASSIC_C__" 85 86 # ARMClang need target options 87 "--target=arm-arm-none-eabi -mcpu=cortex-m3" 88 89 # MSVC needs at least one include directory for __has_include to function, 90 # but custom toolchains may run MSVC with no INCLUDE env var and no -I flags. 91 # Also avoid linking so this works with no LIB env var. 92 "-c -I__does_not_exist__" 93 ) 94endif() 95if(CMAKE_C_COMPILER_TARGET) 96 set(CMAKE_C_COMPILER_ID_TEST_FLAGS_FIRST "-c --target=${CMAKE_C_COMPILER_TARGET}") 97endif() 98# Build a small source file to identify the compiler. 99if(NOT CMAKE_C_COMPILER_ID_RUN) 100 set(CMAKE_C_COMPILER_ID_RUN 1) 101 102 # Try to identify the compiler. 103 set(CMAKE_C_COMPILER_ID) 104 set(CMAKE_C_PLATFORM_ID) 105 file(READ ${CMAKE_ROOT}/Modules/CMakePlatformId.h.in 106 CMAKE_C_COMPILER_ID_PLATFORM_CONTENT) 107 108 # The IAR compiler produces weird output. 109 # See https://gitlab.kitware.com/cmake/cmake/-/issues/10176#note_153591 110 list(APPEND CMAKE_C_COMPILER_ID_VENDORS IAR) 111 set(CMAKE_C_COMPILER_ID_VENDOR_FLAGS_IAR ) 112 set(CMAKE_C_COMPILER_ID_VENDOR_REGEX_IAR "IAR .+ Compiler") 113 114 # Match the link line from xcodebuild output of the form 115 # Ld ... 116 # ... 117 # /path/to/cc ...CompilerIdC/... 118 # to extract the compiler front-end for the language. 119 set(CMAKE_C_COMPILER_ID_TOOL_MATCH_REGEX "\nLd[^\n]*(\n[ \t]+[^\n]*)*\n[ \t]+([^ \t\r\n]+)[^\r\n]*-o[^\r\n]*CompilerIdC/(\\./)?(CompilerIdC.(framework|xctest|build/[^ \t\r\n]+)/)?CompilerIdC[ \t\n\\\"]") 120 set(CMAKE_C_COMPILER_ID_TOOL_MATCH_INDEX 2) 121 122 include(${CMAKE_ROOT}/Modules/CMakeDetermineCompilerId.cmake) 123 CMAKE_DETERMINE_COMPILER_ID(C CFLAGS CMakeCCompilerId.c) 124 125 _cmake_find_compiler_sysroot(C) 126 127 # Set old compiler and platform id variables. 128 if(CMAKE_C_COMPILER_ID STREQUAL "GNU") 129 set(CMAKE_COMPILER_IS_GNUCC 1) 130 endif() 131else() 132 if(NOT DEFINED CMAKE_C_COMPILER_FRONTEND_VARIANT) 133 # Some toolchain files set our internal CMAKE_C_COMPILER_ID_RUN 134 # variable but are not aware of CMAKE_C_COMPILER_FRONTEND_VARIANT. 135 # They pre-date our support for the GNU-like variant targeting the 136 # MSVC ABI so we do not consider that here. 137 if(CMAKE_C_COMPILER_ID STREQUAL "Clang" 138 OR "x${CMAKE_C_COMPILER_ID}" STREQUAL "xIntelLLVM") 139 if("x${CMAKE_C_SIMULATE_ID}" STREQUAL "xMSVC") 140 set(CMAKE_C_COMPILER_FRONTEND_VARIANT "MSVC") 141 else() 142 set(CMAKE_C_COMPILER_FRONTEND_VARIANT "GNU") 143 endif() 144 else() 145 set(CMAKE_C_COMPILER_FRONTEND_VARIANT "") 146 endif() 147 endif() 148endif() 149 150if (NOT _CMAKE_TOOLCHAIN_LOCATION) 151 get_filename_component(_CMAKE_TOOLCHAIN_LOCATION "${CMAKE_C_COMPILER}" PATH) 152endif () 153 154# If we have a gcc cross compiler, they have usually some prefix, like 155# e.g. powerpc-linux-gcc, arm-elf-gcc or i586-mingw32msvc-gcc, optionally 156# with a 3-component version number at the end (e.g. arm-eabi-gcc-4.5.2). 157# The other tools of the toolchain usually have the same prefix 158# NAME_WE cannot be used since then this test will fail for names like 159# "arm-unknown-nto-qnx6.3.0-gcc.exe", where BASENAME would be 160# "arm-unknown-nto-qnx6" instead of the correct "arm-unknown-nto-qnx6.3.0-" 161if (NOT _CMAKE_TOOLCHAIN_PREFIX) 162 163 if(CMAKE_C_COMPILER_ID MATCHES "GNU|Clang|QCC") 164 get_filename_component(COMPILER_BASENAME "${CMAKE_C_COMPILER}" NAME) 165 if (COMPILER_BASENAME MATCHES "^(.+-)?(clang|g?cc)(-cl)?(-[0-9]+(\\.[0-9]+)*)?(-[^.]+)?(\\.exe)?$") 166 set(_CMAKE_TOOLCHAIN_PREFIX ${CMAKE_MATCH_1}) 167 set(_CMAKE_TOOLCHAIN_SUFFIX ${CMAKE_MATCH_4}) 168 set(_CMAKE_COMPILER_SUFFIX ${CMAKE_MATCH_6}) 169 elseif(CMAKE_C_COMPILER_ID MATCHES "Clang") 170 if(CMAKE_C_COMPILER_TARGET) 171 set(_CMAKE_TOOLCHAIN_PREFIX ${CMAKE_C_COMPILER_TARGET}-) 172 endif() 173 elseif(COMPILER_BASENAME MATCHES "qcc(\\.exe)?$") 174 if(CMAKE_C_COMPILER_TARGET MATCHES "gcc_nto([a-z0-9]+_[0-9]+|[^_le]+)(le)?") 175 set(_CMAKE_TOOLCHAIN_PREFIX nto${CMAKE_MATCH_1}-) 176 endif() 177 endif () 178 179 # if "llvm-" is part of the prefix, remove it, since llvm doesn't have its own binutils 180 # but uses the regular ar, objcopy, etc. (instead of llvm-objcopy etc.) 181 if ("${_CMAKE_TOOLCHAIN_PREFIX}" MATCHES "(.+-)?llvm-$") 182 set(_CMAKE_TOOLCHAIN_PREFIX ${CMAKE_MATCH_1}) 183 endif () 184 elseif(CMAKE_C_COMPILER_ID MATCHES "TI") 185 # TI compilers are named e.g. cl6x, cl470 or armcl.exe 186 get_filename_component(COMPILER_BASENAME "${CMAKE_C_COMPILER}" NAME) 187 if (COMPILER_BASENAME MATCHES "^(.+)?cl([^.]+)?(\\.exe)?$") 188 set(_CMAKE_TOOLCHAIN_PREFIX "${CMAKE_MATCH_1}") 189 set(_CMAKE_TOOLCHAIN_SUFFIX "${CMAKE_MATCH_2}") 190 endif () 191 endif() 192 193endif () 194 195set(_CMAKE_PROCESSING_LANGUAGE "C") 196include(CMakeFindBinUtils) 197include(Compiler/${CMAKE_C_COMPILER_ID}-FindBinUtils OPTIONAL) 198unset(_CMAKE_PROCESSING_LANGUAGE) 199 200if(CMAKE_C_COMPILER_SYSROOT) 201 string(CONCAT _SET_CMAKE_C_COMPILER_SYSROOT 202 "set(CMAKE_C_COMPILER_SYSROOT \"${CMAKE_C_COMPILER_SYSROOT}\")\n" 203 "set(CMAKE_COMPILER_SYSROOT \"${CMAKE_C_COMPILER_SYSROOT}\")") 204else() 205 set(_SET_CMAKE_C_COMPILER_SYSROOT "") 206endif() 207 208if(CMAKE_C_COMPILER_ARCHITECTURE_ID) 209 set(_SET_CMAKE_C_COMPILER_ARCHITECTURE_ID 210 "set(CMAKE_C_COMPILER_ARCHITECTURE_ID ${CMAKE_C_COMPILER_ARCHITECTURE_ID})") 211else() 212 set(_SET_CMAKE_C_COMPILER_ARCHITECTURE_ID "") 213endif() 214 215if(MSVC_C_ARCHITECTURE_ID) 216 set(SET_MSVC_C_ARCHITECTURE_ID 217 "set(MSVC_C_ARCHITECTURE_ID ${MSVC_C_ARCHITECTURE_ID})") 218endif() 219 220if(CMAKE_C_XCODE_ARCHS) 221 set(SET_CMAKE_XCODE_ARCHS 222 "set(CMAKE_XCODE_ARCHS \"${CMAKE_C_XCODE_ARCHS}\")") 223endif() 224 225# configure variables set in this file for fast reload later on 226configure_file(${CMAKE_ROOT}/Modules/CMakeCCompiler.cmake.in 227 ${CMAKE_PLATFORM_INFO_DIR}/CMakeCCompiler.cmake 228 @ONLY 229 ) 230set(CMAKE_C_COMPILER_ENV_VAR "CC") 231