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