Merge topic 'cxx-checks-tolerate-unused-arguments'
[kiteware-cmake.git] / Modules / CMakeDetermineCXXCompiler.cmake
blob891ba6e759094c1654315890d4c9eeaa56a2c71e
1 # Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
2 # file Copyright.txt or https://cmake.org/licensing for details.
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.)
14 # Sets the following variables:
15 #   CMAKE_CXX_COMPILER
16 #   CMAKE_COMPILER_IS_GNUCXX
17 #   CMAKE_AR
18 #   CMAKE_RANLIB
20 # If not already set before, it also sets
21 #   _CMAKE_TOOLCHAIN_PREFIX
23 include(${CMAKE_ROOT}/Modules/CMakeDetermineCompiler.cmake)
25 # Load system-specific compiler preferences for this language.
26 include(Platform/${CMAKE_SYSTEM_NAME}-Determine-CXX OPTIONAL)
27 include(Platform/${CMAKE_SYSTEM_NAME}-CXX OPTIONAL)
28 if(NOT CMAKE_CXX_COMPILER_NAMES)
29   set(CMAKE_CXX_COMPILER_NAMES CC)
30 endif()
32 if(${CMAKE_GENERATOR} MATCHES "Visual Studio")
33 elseif("${CMAKE_GENERATOR}" MATCHES "Green Hills MULTI")
34 elseif("${CMAKE_GENERATOR}" MATCHES "Xcode")
35   set(CMAKE_CXX_COMPILER_XCODE_TYPE sourcecode.cpp.cpp)
36   _cmake_find_compiler_path(CXX)
37 else()
38   if(NOT CMAKE_CXX_COMPILER)
39     set(CMAKE_CXX_COMPILER_INIT NOTFOUND)
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()
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()
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)
62       if(NOT CMAKE_HOST_WIN32)
63         # FIXME(#24314): Add support for the GNU-like icpx compiler driver
64         # on Windows, first introduced by Intel oneAPI 2023.0.
65         list(APPEND CMAKE_CXX_COMPILER_LIST icpx)
66       endif()
67       list(APPEND CMAKE_CXX_COMPILER_LIST icx clang++)
68     endif()
70     _cmake_find_compiler(CXX)
71   else()
72     _cmake_find_compiler_path(CXX)
73   endif()
74   mark_as_advanced(CMAKE_CXX_COMPILER)
76   # Each entry in this list is a set of extra flags to try
77   # adding to the compile line to see if it helps produce
78   # a valid identification file.
79   set(CMAKE_CXX_COMPILER_ID_TEST_FLAGS_FIRST)
80   set(CMAKE_CXX_COMPILER_ID_TEST_FLAGS
81     # Try compiling to an object file only.
82     "-c"
83     # IAR does not detect language automatically
84     "--c++"
85     "--ec++"
87     # ARMClang need target options
88     "--target=arm-arm-none-eabi -mcpu=cortex-m3"
90     # MSVC needs at least one include directory for __has_include to function,
91     # but custom toolchains may run MSVC with no INCLUDE env var and no -I flags.
92     # Also avoid linking so this works with no LIB env var.
93     "-c -I__does_not_exist__"
94     )
95 endif()
97 if(CMAKE_CXX_COMPILER_TARGET)
98   set(CMAKE_CXX_COMPILER_ID_TEST_FLAGS_FIRST "-c --target=${CMAKE_CXX_COMPILER_TARGET}")
99 endif()
101 # Build a small source file to identify the compiler.
102 if(NOT CMAKE_CXX_COMPILER_ID_RUN)
103   set(CMAKE_CXX_COMPILER_ID_RUN 1)
105   # Try to identify the compiler.
106   set(CMAKE_CXX_COMPILER_ID)
107   set(CMAKE_CXX_PLATFORM_ID)
108   file(READ ${CMAKE_ROOT}/Modules/CMakePlatformId.h.in
109     CMAKE_CXX_COMPILER_ID_PLATFORM_CONTENT)
111   # The IAR compiler produces weird output.
112   # See https://gitlab.kitware.com/cmake/cmake/-/issues/10176#note_153591
113   list(APPEND CMAKE_CXX_COMPILER_ID_VENDORS IAR)
114   set(CMAKE_CXX_COMPILER_ID_VENDOR_FLAGS_IAR )
115   set(CMAKE_CXX_COMPILER_ID_VENDOR_REGEX_IAR "IAR .+ Compiler")
117   # Match the link line from xcodebuild output of the form
118   #  Ld ...
119   #      ...
120   #      /path/to/cc ...CompilerIdCXX/...
121   # to extract the compiler front-end for the language.
122   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\\\"]")
123   set(CMAKE_CXX_COMPILER_ID_TOOL_MATCH_INDEX 2)
125   include(${CMAKE_ROOT}/Modules/CMakeDetermineCompilerId.cmake)
126   CMAKE_DETERMINE_COMPILER_ID(CXX CXXFLAGS CMakeCXXCompilerId.cpp)
128   _cmake_find_compiler_sysroot(CXX)
130   # Set old compiler and platform id variables.
131   if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
132     set(CMAKE_COMPILER_IS_GNUCXX 1)
133   endif()
134 else()
135   if(NOT DEFINED CMAKE_CXX_COMPILER_FRONTEND_VARIANT)
136     # Some toolchain files set our internal CMAKE_CXX_COMPILER_ID_RUN
137     # variable but are not aware of CMAKE_CXX_COMPILER_FRONTEND_VARIANT.
138     # They pre-date our support for the GNU-like variant targeting the
139     # MSVC ABI so we do not consider that here.
140     if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang"
141       OR "x${CMAKE_CXX_COMPILER_ID}" STREQUAL "xIntelLLVM")
142       if("x${CMAKE_CXX_SIMULATE_ID}" STREQUAL "xMSVC")
143         set(CMAKE_CXX_COMPILER_FRONTEND_VARIANT "MSVC")
144       else()
145         set(CMAKE_CXX_COMPILER_FRONTEND_VARIANT "GNU")
146       endif()
147     else()
148       set(CMAKE_CXX_COMPILER_FRONTEND_VARIANT "")
149     endif()
150   endif()
151 endif()
153 if (NOT _CMAKE_TOOLCHAIN_LOCATION)
154   get_filename_component(_CMAKE_TOOLCHAIN_LOCATION "${CMAKE_CXX_COMPILER}" PATH)
155 endif ()
157 # if we have a g++ cross compiler, they have usually some prefix, like
158 # e.g. powerpc-linux-g++, arm-elf-g++ or i586-mingw32msvc-g++ , optionally
159 # with a 3-component version number at the end (e.g. arm-eabi-gcc-4.5.2).
160 # The other tools of the toolchain usually have the same prefix
161 # NAME_WE cannot be used since then this test will fail for names like
162 # "arm-unknown-nto-qnx6.3.0-gcc.exe", where BASENAME would be
163 # "arm-unknown-nto-qnx6" instead of the correct "arm-unknown-nto-qnx6.3.0-"
166 if (NOT _CMAKE_TOOLCHAIN_PREFIX)
168   if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang|QCC|LCC")
169     get_filename_component(COMPILER_BASENAME "${CMAKE_CXX_COMPILER}" NAME)
170     if (COMPILER_BASENAME MATCHES "^(.+-)?(clang\\+\\+|[gc]\\+\\+|clang-cl)(-?[0-9]+(\\.[0-9]+)*)?(-[^.]+)?(\\.exe)?$")
171       set(_CMAKE_TOOLCHAIN_PREFIX ${CMAKE_MATCH_1})
172       set(_CMAKE_TOOLCHAIN_SUFFIX ${CMAKE_MATCH_3})
173       set(_CMAKE_COMPILER_SUFFIX ${CMAKE_MATCH_5})
174     elseif(CMAKE_CXX_COMPILER_ID MATCHES "TIClang")
175        if (COMPILER_BASENAME MATCHES "^(.+)?clang(\\.exe)?$")
176          set(_CMAKE_TOOLCHAIN_PREFIX "${CMAKE_MATCH_1}")
177          set(_CMAKE_TOOLCHAIN_SUFFIX "${CMAKE_MATCH_2}")
178        endif()
179     elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
180       if(CMAKE_CXX_COMPILER_TARGET)
181         set(_CMAKE_TOOLCHAIN_PREFIX ${CMAKE_CXX_COMPILER_TARGET}-)
182       endif()
183     elseif(COMPILER_BASENAME MATCHES "QCC(\\.exe)?$")
184       if(CMAKE_CXX_COMPILER_TARGET MATCHES "gcc_nto([a-z0-9]+_[0-9]+|[^_le]+)(le)")
185         set(_CMAKE_TOOLCHAIN_PREFIX nto${CMAKE_MATCH_1}-)
186       endif()
187     endif ()
189     # if "llvm-" is part of the prefix, remove it, since llvm doesn't have its own binutils
190     # but uses the regular ar, objcopy, etc. (instead of llvm-objcopy etc.)
191     if ("${_CMAKE_TOOLCHAIN_PREFIX}" MATCHES "(.+-)?llvm-$")
192       set(_CMAKE_TOOLCHAIN_PREFIX ${CMAKE_MATCH_1})
193     endif ()
194   elseif(CMAKE_CXX_COMPILER_ID MATCHES "TI")
195     # TI compilers are named e.g. cl6x, cl470 or armcl.exe
196     get_filename_component(COMPILER_BASENAME "${CMAKE_CXX_COMPILER}" NAME)
197     if (COMPILER_BASENAME MATCHES "^(.+)?cl([^.]+)?(\\.exe)?$")
198       set(_CMAKE_TOOLCHAIN_PREFIX "${CMAKE_MATCH_1}")
199       set(_CMAKE_TOOLCHAIN_SUFFIX "${CMAKE_MATCH_2}")
200     endif ()
202   endif()
204 endif ()
206 set(_CMAKE_PROCESSING_LANGUAGE "CXX")
207 include(CMakeFindBinUtils)
208 include(Compiler/${CMAKE_CXX_COMPILER_ID}-FindBinUtils OPTIONAL)
209 unset(_CMAKE_PROCESSING_LANGUAGE)
211 if(CMAKE_CXX_COMPILER_SYSROOT)
212   string(CONCAT _SET_CMAKE_CXX_COMPILER_SYSROOT
213     "set(CMAKE_CXX_COMPILER_SYSROOT \"${CMAKE_CXX_COMPILER_SYSROOT}\")\n"
214     "set(CMAKE_COMPILER_SYSROOT \"${CMAKE_CXX_COMPILER_SYSROOT}\")")
215 else()
216   set(_SET_CMAKE_CXX_COMPILER_SYSROOT "")
217 endif()
219 if(CMAKE_CXX_COMPILER_ARCHITECTURE_ID)
220   set(_SET_CMAKE_CXX_COMPILER_ARCHITECTURE_ID
221     "set(CMAKE_CXX_COMPILER_ARCHITECTURE_ID ${CMAKE_CXX_COMPILER_ARCHITECTURE_ID})")
222 else()
223   set(_SET_CMAKE_CXX_COMPILER_ARCHITECTURE_ID "")
224 endif()
226 if(MSVC_CXX_ARCHITECTURE_ID)
227   set(SET_MSVC_CXX_ARCHITECTURE_ID
228     "set(MSVC_CXX_ARCHITECTURE_ID ${MSVC_CXX_ARCHITECTURE_ID})")
229 endif()
231 if(CMAKE_CXX_XCODE_ARCHS)
232   set(SET_CMAKE_XCODE_ARCHS
233     "set(CMAKE_XCODE_ARCHS \"${CMAKE_CXX_XCODE_ARCHS}\")")
234 endif()
236 # configure all variables set in this file
237 configure_file(${CMAKE_ROOT}/Modules/CMakeCXXCompiler.cmake.in
238   ${CMAKE_PLATFORM_INFO_DIR}/CMakeCXXCompiler.cmake
239   @ONLY
240   )
242 set(CMAKE_CXX_COMPILER_ENV_VAR "CXX")