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 Objective-C++ programs 6# NOTE, a generator may set CMAKE_OBJCXX_COMPILER before 7# loading this file to force a compiler. 8# use environment variable OBJCXX first if defined by user, next use 9# the cmake variable CMAKE_GENERATOR_OBJCXX 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_OBJCXX_COMPILER 16# CMAKE_COMPILER_IS_GNUOBJCXX 17# CMAKE_COMPILER_IS_CLANGOBJCXX 18# CMAKE_AR 19# CMAKE_RANLIB 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-OBJCXX OPTIONAL) 28include(Platform/${CMAKE_SYSTEM_NAME}-OBJCXX OPTIONAL) 29if(NOT CMAKE_OBJCXX_COMPILER_NAMES) 30 set(CMAKE_OBJCXX_COMPILER_NAMES clang++) 31endif() 32 33if("${CMAKE_GENERATOR}" MATCHES "Xcode") 34 set(CMAKE_OBJCXX_COMPILER_XCODE_TYPE sourcecode.cpp.objcpp) 35else() 36 if(NOT CMAKE_OBJCXX_COMPILER) 37 set(CMAKE_OBJCXX_COMPILER_INIT NOTFOUND) 38 39 # prefer the environment variable OBJCXX or CXX 40 foreach(var OBJCXX CXX) 41 if($ENV{${var}} MATCHES ".+") 42 get_filename_component(CMAKE_OBJCXX_COMPILER_INIT $ENV{${var}} PROGRAM PROGRAM_ARGS CMAKE_OBJCXX_FLAGS_ENV_INIT) 43 if(CMAKE_OBJCXX_FLAGS_ENV_INIT) 44 set(CMAKE_OBJCXX_COMPILER_ARG1 "${CMAKE_OBJCXX_FLAGS_ENV_INIT}" CACHE STRING "Arguments to Objective-C++ compiler") 45 endif() 46 if(NOT EXISTS ${CMAKE_OBJCXX_COMPILER_INIT}) 47 message(FATAL_ERROR "Could not find compiler set in environment variable ${var}:\n $ENV{${var}}") 48 endif() 49 break() 50 endif() 51 endforeach() 52 53 # next prefer the generator specified compiler 54 if(CMAKE_GENERATOR_OBJCXX) 55 if(NOT CMAKE_OBJCXX_COMPILER_INIT) 56 set(CMAKE_OBJCXX_COMPILER_INIT ${CMAKE_GENERATOR_OBJCXX}) 57 endif() 58 endif() 59 60 # finally list compilers to try 61 if(NOT CMAKE_OBJCXX_COMPILER_INIT) 62 set(CMAKE_OBJCXX_COMPILER_LIST ${_CMAKE_TOOLCHAIN_PREFIX}c++ ${_CMAKE_TOOLCHAIN_PREFIX}g++ clang++) 63 endif() 64 65 _cmake_find_compiler(OBJCXX) 66 67 else() 68 # we only get here if CMAKE_OBJCXX_COMPILER was specified using -D or a pre-made CMakeCache.txt 69 # (e.g. via ctest) or set in CMAKE_TOOLCHAIN_FILE 70 # if CMAKE_OBJCXX_COMPILER is a list, use the first item as 71 # CMAKE_OBJCXX_COMPILER and the rest as CMAKE_OBJCXX_COMPILER_ARG1 72 set(CMAKE_OBJCXX_COMPILER_ARG1 "${CMAKE_OBJCXX_COMPILER}") 73 list(POP_FRONT CMAKE_OBJCXX_COMPILER_ARG1 CMAKE_OBJCXX_COMPILER) 74 list(JOIN CMAKE_OBJCXX_COMPILER_ARG1 " " CMAKE_OBJCXX_COMPILER_ARG1) 75 76 # if a compiler was specified by the user but without path, 77 # now try to find it with the full path 78 # if it is found, force it into the cache, 79 # if not, don't overwrite the setting (which was given by the user) with "NOTFOUND" 80 # if the C compiler already had a path, reuse it for searching the CXX compiler 81 get_filename_component(_CMAKE_USER_OBJCXX_COMPILER_PATH "${CMAKE_OBJCXX_COMPILER}" PATH) 82 if(NOT _CMAKE_USER_OBJCXX_COMPILER_PATH) 83 find_program(CMAKE_OBJCXX_COMPILER_WITH_PATH NAMES ${CMAKE_OBJCXX_COMPILER}) 84 if(CMAKE_OBJCXX_COMPILER_WITH_PATH) 85 set(CMAKE_OBJCXX_COMPILER ${CMAKE_OBJCXX_COMPILER_WITH_PATH} CACHE STRING "Objective-C++ compiler" FORCE) 86 endif() 87 unset(CMAKE_OBJCXX_COMPILER_WITH_PATH CACHE) 88 endif() 89 90 endif() 91 mark_as_advanced(CMAKE_OBJCXX_COMPILER) 92 93 # Each entry in this list is a set of extra flags to try 94 # adding to the compile line to see if it helps produce 95 # a valid identification file. 96 set(CMAKE_OBJCXX_COMPILER_ID_TEST_FLAGS_FIRST) 97 set(CMAKE_OBJCXX_COMPILER_ID_TEST_FLAGS 98 # Try compiling to an object file only. 99 "-c" 100 101 # ARMClang need target options 102 "--target=arm-arm-none-eabi -mcpu=cortex-m3" 103 ) 104endif() 105 106# Build a small source file to identify the compiler. 107if(NOT CMAKE_OBJCXX_COMPILER_ID_RUN) 108 set(CMAKE_OBJCXX_COMPILER_ID_RUN 1) 109 110 # Try to identify the compiler. 111 set(CMAKE_OBJCXX_COMPILER_ID) 112 file(READ ${CMAKE_ROOT}/Modules/CMakePlatformId.h.in 113 CMAKE_OBJCXX_COMPILER_ID_PLATFORM_CONTENT) 114 115 # Match the link line from xcodebuild output of the form 116 # Ld ... 117 # ... 118 # /path/to/cc ...CompilerIdOBJCXX/... 119 # to extract the compiler front-end for the language. 120 set(CMAKE_OBJCXX_COMPILER_ID_TOOL_MATCH_REGEX "\nLd[^\n]*(\n[ \t]+[^\n]*)*\n[ \t]+([^ \t\r\n]+)[^\r\n]*-o[^\r\n]*CompilerIdOBJCXX/(\\./)?(CompilerIdOBJCXX.(framework|xctest|build/[^ \t\r\n]+)/)?CompilerIdOBJCXX[ \t\n\\\"]") 121 set(CMAKE_OBJCXX_COMPILER_ID_TOOL_MATCH_INDEX 2) 122 123 include(${CMAKE_ROOT}/Modules/CMakeDetermineCompilerId.cmake) 124 CMAKE_DETERMINE_COMPILER_ID(OBJCXX OBJCXXFLAGS CMakeOBJCXXCompilerId.mm) 125 126 # Set old compiler and platform id variables. 127 if(CMAKE_OBJCXX_COMPILER_ID MATCHES "GNU") 128 set(CMAKE_COMPILER_IS_GNUOBJCXX 1) 129 endif() 130 if(CMAKE_OBJCXX_COMPILER_ID MATCHES "Clang") 131 set(CMAKE_COMPILER_IS_CLANGOBJCXX 1) 132 endif() 133endif() 134 135if (NOT _CMAKE_TOOLCHAIN_LOCATION) 136 get_filename_component(_CMAKE_TOOLCHAIN_LOCATION "${CMAKE_OBJCXX_COMPILER}" PATH) 137endif () 138 139# if we have a g++ cross compiler, they have usually some prefix, like 140# e.g. powerpc-linux-g++, arm-elf-g++ or i586-mingw32msvc-g++ , optionally 141# with a 3-component version number at the end (e.g. arm-eabi-gcc-4.5.2). 142# The other tools of the toolchain usually have the same prefix 143# NAME_WE cannot be used since then this test will fail for names like 144# "arm-unknown-nto-qnx6.3.0-gcc.exe", where BASENAME would be 145# "arm-unknown-nto-qnx6" instead of the correct "arm-unknown-nto-qnx6.3.0-" 146 147 148if (NOT _CMAKE_TOOLCHAIN_PREFIX) 149 150 if("${CMAKE_OBJCXX_COMPILER_ID}" MATCHES "GNU|Clang|QCC") 151 get_filename_component(COMPILER_BASENAME "${CMAKE_OBJCXX_COMPILER}" NAME) 152 if (COMPILER_BASENAME MATCHES "^(.+-)(clan)?[gc]\\+\\+(-[0-9]+(\\.[0-9]+)*)?(-[^.]+)?(\\.exe)?$") 153 set(_CMAKE_TOOLCHAIN_PREFIX ${CMAKE_MATCH_1}) 154 set(_CMAKE_COMPILER_SUFFIX ${CMAKE_MATCH_5}) 155 elseif("${CMAKE_OBJCXX_COMPILER_ID}" MATCHES "Clang") 156 if(CMAKE_OBJCXX_COMPILER_TARGET) 157 set(_CMAKE_TOOLCHAIN_PREFIX ${CMAKE_OBJCXX_COMPILER_TARGET}-) 158 endif() 159 elseif(COMPILER_BASENAME MATCHES "QCC(\\.exe)?$") 160 if(CMAKE_OBJCXX_COMPILER_TARGET MATCHES "gcc_nto([a-z0-9]+_[0-9]+|[^_le]+)(le)") 161 set(_CMAKE_TOOLCHAIN_PREFIX nto${CMAKE_MATCH_1}-) 162 endif() 163 endif () 164 165 # if "llvm-" is part of the prefix, remove it, since llvm doesn't have its own binutils 166 # but uses the regular ar, objcopy, etc. (instead of llvm-objcopy etc.) 167 if ("${_CMAKE_TOOLCHAIN_PREFIX}" MATCHES "(.+-)?llvm-$") 168 set(_CMAKE_TOOLCHAIN_PREFIX ${CMAKE_MATCH_1}) 169 endif () 170 endif() 171 172endif () 173 174set(_CMAKE_PROCESSING_LANGUAGE "OBJCXX") 175include(CMakeFindBinUtils) 176include(Compiler/${CMAKE_OBJCXX_COMPILER_ID}-FindBinUtils OPTIONAL) 177unset(_CMAKE_PROCESSING_LANGUAGE) 178 179if(CMAKE_OBJCXX_COMPILER_ARCHITECTURE_ID) 180 set(_SET_CMAKE_OBJCXX_COMPILER_ARCHITECTURE_ID 181 "set(CMAKE_OBJCXX_COMPILER_ARCHITECTURE_ID ${CMAKE_OBJCXX_COMPILER_ARCHITECTURE_ID})") 182else() 183 set(_SET_CMAKE_OBJCXX_COMPILER_ARCHITECTURE_ID "") 184endif() 185 186if(CMAKE_OBJCXX_XCODE_ARCHS) 187 set(SET_CMAKE_XCODE_ARCHS 188 "set(CMAKE_XCODE_ARCHS \"${CMAKE_OBJCXX_XCODE_ARCHS}\")") 189endif() 190 191# configure all variables set in this file 192configure_file(${CMAKE_ROOT}/Modules/CMakeOBJCXXCompiler.cmake.in 193 ${CMAKE_PLATFORM_INFO_DIR}/CMakeOBJCXXCompiler.cmake 194 @ONLY 195 ) 196 197set(CMAKE_OBJCXX_COMPILER_ENV_VAR "OBJCXX") 198