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# search for additional tools required for C/C++ (and other languages ?) 6# 7# If the internal cmake variable _CMAKE_TOOLCHAIN_PREFIX is set, this is used 8# as prefix for the tools (e.g. arm-elf-gcc etc.) 9# If the cmake variable _CMAKE_TOOLCHAIN_LOCATION is set, the compiler is 10# searched only there. The other tools are at first searched there, then 11# also in the default locations. 12# 13# Sets the following variables: 14# CMAKE_AR 15# CMAKE_RANLIB 16# CMAKE_LINKER 17# CMAKE_MT 18# CMAKE_STRIP 19# CMAKE_INSTALL_NAME_TOOL 20 21# on UNIX, cygwin and mingw 22 23cmake_policy(PUSH) 24cmake_policy(SET CMP0057 NEW) # if IN_LIST 25 26# Resolve full path of CMAKE_TOOL from user-defined name and SEARCH_PATH. 27function(__resolve_tool_path CMAKE_TOOL SEARCH_PATH DOCSTRING) 28 29 if(${CMAKE_TOOL}) 30 # We only get here if CMAKE_TOOL was 31 # specified using -D or a pre-made CMakeCache.txt (e.g. via ctest) 32 # or set in CMAKE_TOOLCHAIN_FILE. 33 34 get_filename_component(_CMAKE_USER_TOOL_PATH "${${CMAKE_TOOL}}" DIRECTORY) 35 # Is CMAKE_TOOL a user-defined name instead of a full path? 36 if(NOT _CMAKE_USER_TOOL_PATH) 37 38 # Find CMAKE_TOOL in the SEARCH_PATH directory by user-defined name. 39 find_program(_CMAKE_TOOL_WITH_PATH NAMES ${${CMAKE_TOOL}} HINTS ${SEARCH_PATH} NO_CMAKE_PATH NO_CMAKE_ENVIRONMENT_PATH) 40 if(_CMAKE_TOOL_WITH_PATH) 41 42 # Overwrite CMAKE_TOOL with full path found in SEARCH_PATH. 43 set(${CMAKE_TOOL} ${_CMAKE_TOOL_WITH_PATH} PARENT_SCOPE) 44 45 get_property(_CMAKE_TOOL_CACHED CACHE ${CMAKE_TOOL} PROPERTY TYPE) 46 # If CMAKE_TOOL is present in the CMake Cache, then overwrit it as well. 47 if(_CMAKE_TOOL_CACHED) 48 set(${CMAKE_TOOL} "${_CMAKE_TOOL_WITH_PATH}" CACHE STRING ${DOCSTRING} FORCE) 49 endif() 50 51 endif() 52 unset(_CMAKE_TOOL_WITH_PATH CACHE) 53 54 endif() 55 56 endif() 57 58endfunction() 59 60__resolve_tool_path(CMAKE_LINKER "${_CMAKE_TOOLCHAIN_LOCATION}" "Default Linker") 61__resolve_tool_path(CMAKE_MT "${_CMAKE_TOOLCHAIN_LOCATION}" "Default Manifest Tool") 62 63set(_CMAKE_TOOL_VARS "") 64 65# if it's the MS C/CXX compiler, search for link 66if(("x${CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_SIMULATE_ID}" STREQUAL "xMSVC" AND 67 ("x${CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_FRONTEND_VARIANT}" STREQUAL "xMSVC" 68 OR NOT "x${CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_ID}" STREQUAL "xClang")) 69 OR "x${CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_ID}" STREQUAL "xMSVC" 70 OR (CMAKE_HOST_WIN32 AND "x${CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_ID}" STREQUAL "xPGI") 71 OR (CMAKE_HOST_WIN32 AND "x${CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_ID}" STREQUAL "xNVIDIA") 72 OR (CMAKE_HOST_WIN32 AND "x${_CMAKE_PROCESSING_LANGUAGE}" STREQUAL "xISPC") 73 OR (CMAKE_GENERATOR MATCHES "Visual Studio" 74 AND NOT CMAKE_VS_PLATFORM_NAME STREQUAL "Tegra-Android")) 75 76 # Start with the canonical names. 77 set(_CMAKE_LINKER_NAMES "link") 78 set(_CMAKE_AR_NAMES "lib") 79 set(_CMAKE_MT_NAMES "mt") 80 81 # Prepend toolchain-specific names. 82 if("x${CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_ID}" STREQUAL "xClang") 83 set(_CMAKE_NM_NAMES "llvm-nm" "nm") 84 list(PREPEND _CMAKE_AR_NAMES "llvm-lib") 85 list(PREPEND _CMAKE_MT_NAMES "llvm-mt") 86 list(PREPEND _CMAKE_LINKER_NAMES "lld-link") 87 list(APPEND _CMAKE_TOOL_VARS NM) 88 elseif("x${CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_ID}" STREQUAL "xIntel") 89 list(PREPEND _CMAKE_AR_NAMES "xilib") 90 list(PREPEND _CMAKE_LINKER_NAMES "xilink") 91 endif() 92 93 list(APPEND _CMAKE_TOOL_VARS LINKER MT AR) 94 95elseif("x${CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_ID}" MATCHES "^x(Open)?Watcom$") 96 set(_CMAKE_LINKER_NAMES "wlink") 97 set(_CMAKE_AR_NAMES "wlib") 98 list(APPEND _CMAKE_TOOL_VARS LINKER AR) 99 100elseif("x${CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_ID}" MATCHES "^xIAR$") 101 # Small helper declaring an IAR tool (e.g. linker) to avoid repeating the same idiom every time 102 macro(__append_IAR_tool TOOL_VAR NAME) 103 set(_CMAKE_${TOOL_VAR}_NAMES "${NAME}" "${NAME}.exe") 104 list(APPEND _CMAKE_TOOL_VARS ${TOOL_VAR}) 105 endmacro() 106 107 # Resolve hint path from an IAR compiler 108 function(__resolve_IAR_hints COMPILER RESULT) 109 get_filename_component(_CMAKE_IAR_HINT "${COMPILER}" REALPATH) 110 get_filename_component(_CMAKE_IAR_HINT "${_CMAKE_IAR_HINT}" DIRECTORY) 111 list(APPEND _IAR_HINTS "${_CMAKE_IAR_HINT}") 112 113 get_filename_component(_CMAKE_IAR_HINT "${COMPILER}" DIRECTORY) 114 list(APPEND _IAR_HINTS "${_CMAKE_IAR_HINT}") 115 116 set(${RESULT} "${_IAR_HINTS}" PARENT_SCOPE) 117 endfunction() 118 119 __resolve_IAR_hints("${CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER}" _CMAKE_TOOLCHAIN_LOCATION) 120 set(_CMAKE_IAR_ITOOLS "ARM" "RX" "RH850" "RL78" "RISCV" "RISC-V" "STM8") 121 set(_CMAKE_IAR_XTOOLS "AVR" "MSP430" "V850" "8051") 122 123 if("${CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_ARCHITECTURE_ID}" IN_LIST _CMAKE_IAR_ITOOLS) 124 string(TOLOWER "${CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_ARCHITECTURE_ID}" _CMAKE_IAR_LOWER_ARCHITECTURE_ID) 125 126 __append_IAR_tool(AR "iarchive") 127 __append_IAR_tool(LINKER "ilink${_CMAKE_IAR_LOWER_ARCHITECTURE_ID}") 128 129 __append_IAR_tool(IAR_ELFDUMP "ielfdump${_CMAKE_IAR_LOWER_ARCHITECTURE_ID}") 130 __append_IAR_tool(IAR_ELFTOOL "ielftool") 131 __append_IAR_tool(IAR_OBJMANIP "iobjmanip") 132 __append_IAR_tool(IAR_SYMEXPORT "isymexport") 133 134 unset(_CMAKE_IAR_LOWER_ARCHITECTURE_ID) 135 136 elseif("${CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_ARCHITECTURE_ID}" IN_LIST _CMAKE_IAR_XTOOLS) 137 __append_IAR_tool(AR "xar") 138 __append_IAR_tool(LINKER "xlink") 139 140 else() 141 message(FATAL_ERROR "Failed to find linker and librarian for ${CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_ID} on ${CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_ARCHITECTURE_ID}.") 142 endif() 143 144 unset(_CMAKE_IAR_ITOOLS) 145 unset(_CMAKE_IAR_XTOOLS) 146 147# in all other cases search for ar, ranlib, etc. 148else() 149 if(CMAKE_C_COMPILER_EXTERNAL_TOOLCHAIN) 150 set(_CMAKE_TOOLCHAIN_LOCATION ${_CMAKE_TOOLCHAIN_LOCATION} ${CMAKE_C_COMPILER_EXTERNAL_TOOLCHAIN}/bin) 151 endif() 152 if(CMAKE_CXX_COMPILER_EXTERNAL_TOOLCHAIN) 153 set(_CMAKE_TOOLCHAIN_LOCATION ${_CMAKE_TOOLCHAIN_LOCATION} ${CMAKE_CXX_COMPILER_EXTERNAL_TOOLCHAIN}/bin) 154 endif() 155 156 # Start with the canonical names. 157 set(_CMAKE_AR_NAMES "ar") 158 set(_CMAKE_RANLIB_NAMES "ranlib") 159 set(_CMAKE_STRIP_NAMES "strip") 160 set(_CMAKE_LINKER_NAMES "ld") 161 set(_CMAKE_NM_NAMES "nm") 162 set(_CMAKE_OBJDUMP_NAMES "objdump") 163 set(_CMAKE_OBJCOPY_NAMES "objcopy") 164 set(_CMAKE_READELF_NAMES "readelf") 165 set(_CMAKE_DLLTOOL_NAMES "dlltool") 166 set(_CMAKE_ADDR2LINE_NAMES "addr2line") 167 168 # Prepend toolchain-specific names. 169 if("${CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_ID}" STREQUAL Clang) 170 if("x${CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_SIMULATE_ID}" STREQUAL "xMSVC") 171 list(PREPEND _CMAKE_LINKER_NAMES "lld-link") 172 else() 173 list(PREPEND _CMAKE_LINKER_NAMES "ld.lld") 174 endif() 175 list(PREPEND _CMAKE_AR_NAMES "llvm-ar") 176 list(PREPEND _CMAKE_RANLIB_NAMES "llvm-ranlib") 177 if("${CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_VERSION}" VERSION_GREATER_EQUAL 11) 178 # llvm-strip versions prior to 11 require additional flags we do not yet add. 179 list(PREPEND _CMAKE_STRIP_NAMES "llvm-strip") 180 endif() 181 list(PREPEND _CMAKE_NM_NAMES "llvm-nm") 182 if("${CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_VERSION}" VERSION_GREATER_EQUAL 9) 183 # llvm-objdump versions prior to 9 did not support everything we need. 184 list(PREPEND _CMAKE_OBJDUMP_NAMES "llvm-objdump") 185 endif() 186 list(PREPEND _CMAKE_OBJCOPY_NAMES "llvm-objcopy") 187 list(PREPEND _CMAKE_READELF_NAMES "llvm-readelf") 188 list(PREPEND _CMAKE_DLLTOOL_NAMES "llvm-dlltool") 189 list(PREPEND _CMAKE_ADDR2LINE_NAMES "llvm-addr2line") 190 elseif("${CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_ID}" STREQUAL ARMClang) 191 list(PREPEND _CMAKE_AR_NAMES "armar") 192 list(PREPEND _CMAKE_LINKER_NAMES "armlink") 193 endif() 194 195 list(APPEND _CMAKE_TOOL_VARS AR RANLIB STRIP LINKER NM OBJDUMP OBJCOPY READELF DLLTOOL ADDR2LINE) 196endif() 197 198foreach(_CMAKE_TOOL IN LISTS _CMAKE_TOOL_VARS) 199 # Build the final list of prefixed/suffixed names. 200 set(_CMAKE_${_CMAKE_TOOL}_FIND_NAMES "") 201 foreach(_CMAKE_TOOL_NAME IN LISTS _CMAKE_${_CMAKE_TOOL}_NAMES) 202 list(APPEND _CMAKE_${_CMAKE_TOOL}_FIND_NAMES 203 ${_CMAKE_TOOLCHAIN_PREFIX}${_CMAKE_TOOL_NAME}${_CMAKE_TOOLCHAIN_SUFFIX} 204 ${_CMAKE_TOOLCHAIN_PREFIX}${_CMAKE_TOOL_NAME} 205 ${_CMAKE_TOOL_NAME}${_CMAKE_TOOLCHAIN_SUFFIX} 206 ${_CMAKE_TOOL_NAME} 207 ) 208 endforeach() 209 list(REMOVE_DUPLICATES _CMAKE_${_CMAKE_TOOL}_FIND_NAMES) 210 211 find_program(CMAKE_${_CMAKE_TOOL} NAMES ${_CMAKE_${_CMAKE_TOOL}_FIND_NAMES} HINTS ${_CMAKE_TOOLCHAIN_LOCATION} NO_CMAKE_PATH NO_CMAKE_ENVIRONMENT_PATH) 212 unset(_CMAKE_${_CMAKE_TOOL}_FIND_NAMES) 213endforeach() 214 215if(NOT CMAKE_RANLIB) 216 set(CMAKE_RANLIB : CACHE INTERNAL "noop for ranlib") 217endif() 218 219 220if(CMAKE_PLATFORM_HAS_INSTALLNAME) 221 find_program(CMAKE_INSTALL_NAME_TOOL NAMES ${_CMAKE_TOOLCHAIN_PREFIX}install_name_tool HINTS ${_CMAKE_TOOLCHAIN_LOCATION} NO_CMAKE_PATH NO_CMAKE_ENVIRONMENT_PATH) 222 223 if(NOT CMAKE_INSTALL_NAME_TOOL) 224 message(FATAL_ERROR "Could not find install_name_tool, please check your installation.") 225 endif() 226 227 list(APPEND _CMAKE_TOOL_VARS INSTALL_NAME_TOOL) 228endif() 229 230# Mark any tool cache entries as advanced. 231foreach(_CMAKE_TOOL IN LISTS _CMAKE_TOOL_VARS) 232 get_property(_CMAKE_TOOL_CACHED CACHE CMAKE_${_CMAKE_TOOL} PROPERTY TYPE) 233 if(_CMAKE_TOOL_CACHED) 234 mark_as_advanced(CMAKE_${_CMAKE_TOOL}) 235 endif() 236 unset(_CMAKE_${_CMAKE_TOOL}_NAMES) 237endforeach() 238unset(_CMAKE_TOOL_VARS) 239unset(_CMAKE_TOOL_CACHED) 240unset(_CMAKE_TOOL_NAME) 241unset(_CMAKE_TOOL) 242 243if("x${CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_ID}" MATCHES "^xIAR$") 244 # Set for backwards compatibility 245 set(CMAKE_IAR_ARCHIVE "${CMAKE_AR}" CACHE FILEPATH "The IAR archiver") 246 set(CMAKE_IAR_LINKER "${CMAKE_LINKER}" CACHE FILEPATH "The IAR ILINK linker") 247 mark_as_advanced(CMAKE_IAR_LINKER CMAKE_IAR_AR) 248endif() 249 250cmake_policy(POP) 251