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_OBJC_COMPILER before 7# loading this file to force a compiler. 8# use environment variable OBJC first if defined by user, next use 9# the cmake variable CMAKE_GENERATOR_OBJC which can be defined by a generator 10# as a default compiler 11# 12# Sets the following variables: 13# CMAKE_OBJC_COMPILER 14# CMAKE_AR 15# CMAKE_RANLIB 16# CMAKE_COMPILER_IS_GNUOBJC 17# CMAKE_COMPILER_IS_CLANGOBJC 18# 19# If not already set before, it also sets 20# _CMAKE_TOOLCHAIN_PREFIX 21 22include(${CMAKE_ROOT}/Modules/CMakeDetermineCompiler.cmake) 23 24# Load system-specific compiler preferences for this language. 25include(Platform/${CMAKE_SYSTEM_NAME}-Determine-OBJC OPTIONAL) 26include(Platform/${CMAKE_SYSTEM_NAME}-OBJC OPTIONAL) 27if(NOT CMAKE_OBJC_COMPILER_NAMES) 28 set(CMAKE_OBJC_COMPILER_NAMES clang) 29endif() 30 31if("${CMAKE_GENERATOR}" MATCHES "Xcode") 32 set(CMAKE_OBJC_COMPILER_XCODE_TYPE sourcecode.c.objc) 33else() 34 if(NOT CMAKE_OBJC_COMPILER) 35 set(CMAKE_OBJC_COMPILER_INIT NOTFOUND) 36 37 # prefer the environment variable OBJC or CC 38 foreach(var OBJC CC) 39 if($ENV{${var}} MATCHES ".+") 40 get_filename_component(CMAKE_OBJC_COMPILER_INIT $ENV{${var}} PROGRAM PROGRAM_ARGS CMAKE_OBJC_FLAGS_ENV_INIT) 41 if(CMAKE_OBJC_FLAGS_ENV_INIT) 42 set(CMAKE_OBJC_COMPILER_ARG1 "${CMAKE_OBJC_FLAGS_ENV_INIT}" CACHE STRING "Arguments to Objective-C compiler") 43 endif() 44 if(NOT EXISTS ${CMAKE_OBJC_COMPILER_INIT}) 45 message(FATAL_ERROR "Could not find compiler set in environment variable ${var}:\n $ENV{${var}}") 46 endif() 47 break() 48 endif() 49 endforeach() 50 51 # next try prefer the compiler specified by the generator 52 if(CMAKE_GENERATOR_OBJC) 53 if(NOT CMAKE_OBJC_COMPILER_INIT) 54 set(CMAKE_OBJC_COMPILER_INIT ${CMAKE_GENERATOR_OBJC}) 55 endif() 56 endif() 57 58 # finally list compilers to try 59 if(NOT CMAKE_OBJC_COMPILER_INIT) 60 set(CMAKE_OBJC_COMPILER_LIST ${_CMAKE_TOOLCHAIN_PREFIX}cc ${_CMAKE_TOOLCHAIN_PREFIX}gcc clang) 61 endif() 62 63 _cmake_find_compiler(OBJC) 64 65 else() 66 # we only get here if CMAKE_OBJC_COMPILER was specified using -D or a pre-made CMakeCache.txt 67 # (e.g. via ctest) or set in CMAKE_TOOLCHAIN_FILE 68 # if CMAKE_OBJC_COMPILER is a list, use the first item as 69 # CMAKE_OBJC_COMPILER and the rest as CMAKE_OBJC_COMPILER_ARG1 70 set(CMAKE_OBJC_COMPILER_ARG1 "${CMAKE_OBJC_COMPILER}") 71 list(POP_FRONT CMAKE_OBJC_COMPILER_ARG1 CMAKE_OBJC_COMPILER) 72 list(JOIN CMAKE_OBJC_COMPILER_ARG1 " " CMAKE_OBJC_COMPILER_ARG1) 73 74 # if a compiler was specified by the user but without path, 75 # now try to find it with the full path 76 # if it is found, force it into the cache, 77 # if not, don't overwrite the setting (which was given by the user) with "NOTFOUND" 78 # if the C compiler already had a path, reuse it for searching the CXX compiler 79 get_filename_component(_CMAKE_USER_OBJC_COMPILER_PATH "${CMAKE_OBJC_COMPILER}" PATH) 80 if(NOT _CMAKE_USER_OBJC_COMPILER_PATH) 81 find_program(CMAKE_OBJC_COMPILER_WITH_PATH NAMES ${CMAKE_OBJC_COMPILER}) 82 if(CMAKE_OBJC_COMPILER_WITH_PATH) 83 set(CMAKE_OBJC_COMPILER ${CMAKE_OBJC_COMPILER_WITH_PATH} CACHE STRING "Objective-C compiler" FORCE) 84 endif() 85 unset(CMAKE_OBJC_COMPILER_WITH_PATH CACHE) 86 endif() 87 endif() 88 mark_as_advanced(CMAKE_OBJC_COMPILER) 89 90 # Each entry in this list is a set of extra flags to try 91 # adding to the compile line to see if it helps produce 92 # a valid identification file. 93 set(CMAKE_OBJC_COMPILER_ID_TEST_FLAGS_FIRST) 94 set(CMAKE_OBJC_COMPILER_ID_TEST_FLAGS 95 # Try compiling to an object file only. 96 "-c" 97 98 ) 99endif() 100 101# Build a small source file to identify the compiler. 102if(NOT CMAKE_OBJC_COMPILER_ID_RUN) 103 set(CMAKE_OBJC_COMPILER_ID_RUN 1) 104 105 # Try to identify the compiler. 106 set(CMAKE_OBJC_COMPILER_ID) 107 file(READ ${CMAKE_ROOT}/Modules/CMakePlatformId.h.in 108 CMAKE_OBJC_COMPILER_ID_PLATFORM_CONTENT) 109 110 # Match the link line from xcodebuild output of the form 111 # Ld ... 112 # ... 113 # /path/to/cc ...CompilerIdOBJC/... 114 # to extract the compiler front-end for the language. 115 set(CMAKE_OBJC_COMPILER_ID_TOOL_MATCH_REGEX "\nLd[^\n]*(\n[ \t]+[^\n]*)*\n[ \t]+([^ \t\r\n]+)[^\r\n]*-o[^\r\n]*CompilerIdOBJC/(\\./)?(CompilerIdOBJC.(framework|xctest|build/[^ \t\r\n]+)/)?CompilerIdOBJC[ \t\n\\\"]") 116 set(CMAKE_OBJC_COMPILER_ID_TOOL_MATCH_INDEX 2) 117 118 include(${CMAKE_ROOT}/Modules/CMakeDetermineCompilerId.cmake) 119 CMAKE_DETERMINE_COMPILER_ID(OBJC OBJCCFLAGS CMakeOBJCCompilerId.m) 120 121 # Set old compiler and platform id variables. 122 if(CMAKE_OBJC_COMPILER_ID STREQUAL "GNU") 123 set(CMAKE_COMPILER_IS_GNUOBJC 1) 124 endif() 125 if(CMAKE_OBJC_COMPILER_ID STREQUAL "Clang") 126 set(CMAKE_COMPILER_IS_CLANGOBJC 1) 127 endif() 128endif() 129 130if (NOT _CMAKE_TOOLCHAIN_LOCATION) 131 get_filename_component(_CMAKE_TOOLCHAIN_LOCATION "${CMAKE_OBJC_COMPILER}" PATH) 132endif () 133 134# If we have a gcc cross compiler, they have usually some prefix, like 135# e.g. powerpc-linux-gcc, arm-elf-gcc or i586-mingw32msvc-gcc, optionally 136# with a 3-component version number at the end (e.g. arm-eabi-gcc-4.5.2). 137# The other tools of the toolchain usually have the same prefix 138# NAME_WE cannot be used since then this test will fail for names like 139# "arm-unknown-nto-qnx6.3.0-gcc.exe", where BASENAME would be 140# "arm-unknown-nto-qnx6" instead of the correct "arm-unknown-nto-qnx6.3.0-" 141if (CMAKE_CROSSCOMPILING AND NOT _CMAKE_TOOLCHAIN_PREFIX) 142 143 if(CMAKE_OBJC_COMPILER_ID MATCHES "GNU|Clang|QCC") 144 get_filename_component(COMPILER_BASENAME "${CMAKE_OBJC_COMPILER}" NAME) 145 if (COMPILER_BASENAME MATCHES "^(.+-)(clang|g?cc)(-[0-9]+(\\.[0-9]+)*)?(-[^.]+)?(\\.exe)?$") 146 set(_CMAKE_TOOLCHAIN_PREFIX ${CMAKE_MATCH_1}) 147 set(_CMAKE_COMPILER_SUFFIX ${CMAKE_MATCH_5}) 148 elseif(CMAKE_OBJC_COMPILER_ID MATCHES "Clang") 149 if(CMAKE_OBJC_COMPILER_TARGET) 150 set(_CMAKE_TOOLCHAIN_PREFIX ${CMAKE_OBJC_COMPILER_TARGET}-) 151 endif() 152 elseif(COMPILER_BASENAME MATCHES "qcc(\\.exe)?$") 153 if(CMAKE_OBJC_COMPILER_TARGET MATCHES "gcc_nto([a-z0-9]+_[0-9]+|[^_le]+)(le)?") 154 set(_CMAKE_TOOLCHAIN_PREFIX nto${CMAKE_MATCH_1}-) 155 endif() 156 endif () 157 158 # if "llvm-" is part of the prefix, remove it, since llvm doesn't have its own binutils 159 # but uses the regular ar, objcopy, etc. (instead of llvm-objcopy etc.) 160 if ("${_CMAKE_TOOLCHAIN_PREFIX}" MATCHES "(.+-)?llvm-$") 161 set(_CMAKE_TOOLCHAIN_PREFIX ${CMAKE_MATCH_1}) 162 endif () 163 endif() 164 165endif () 166 167set(_CMAKE_PROCESSING_LANGUAGE "OBJC") 168include(CMakeFindBinUtils) 169include(Compiler/${CMAKE_OBJC_COMPILER_ID}-FindBinUtils OPTIONAL) 170unset(_CMAKE_PROCESSING_LANGUAGE) 171 172if(CMAKE_OBJC_COMPILER_ARCHITECTURE_ID) 173 set(_SET_CMAKE_OBJC_COMPILER_ARCHITECTURE_ID 174 "set(CMAKE_OBJC_COMPILER_ARCHITECTURE_ID ${CMAKE_OBJC_COMPILER_ARCHITECTURE_ID})") 175else() 176 set(_SET_CMAKE_OBJC_COMPILER_ARCHITECTURE_ID "") 177endif() 178 179if(CMAKE_OBJC_XCODE_ARCHS) 180 set(SET_CMAKE_XCODE_ARCHS 181 "set(CMAKE_XCODE_ARCHS \"${CMAKE_OBJC_XCODE_ARCHS}\")") 182endif() 183 184# configure variables set in this file for fast reload later on 185configure_file(${CMAKE_ROOT}/Modules/CMakeOBJCCompiler.cmake.in 186 ${CMAKE_PLATFORM_INFO_DIR}/CMakeOBJCCompiler.cmake 187 @ONLY 188 ) 189set(CMAKE_OBJC_COMPILER_ENV_VAR "OBJC") 190