126 lines · plain
1#===-- cmake/modules/GetToolchainDirs.cmake --------------------------------===#2#3# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4# See https://llvm.org/LICENSE.txt for license information.5# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6#7#===------------------------------------------------------------------------===#8 9 10# Determine the subdirectory relative to Clang's resource dir/sysroot where to11# install target-specific libraries, to be found by Clang/Flang driver. This was12# adapted from Compiler-RT's mechanism to find the path for13# libclang_rt.builtins.a.14#15# Compiler-RT has two mechanisms for the path (simplified):16#17# * LLVM_ENABLE_PER_TARGET_RUNTIME_DIR=0: lib/${oslibname}/libclang_rt.builtins-${arch}.a18# * LLVM_ENABLE_PER_TARGET_RUNTIME_DIR=1: lib/${triple}/libclang_rt.builtins.a19#20# LLVM_ENABLE_PER_TARGET_RUNTIME_DIR=ON is the newer scheme, but the old one is21# currently still used for some platforms such as Windows. Clang looks for which22# of the files exist before passing the path to the linker. Hence, the23# directories have to match what Clang is looking for, which is done in24# ToolChain::getArchSpecificLibPaths(..), ToolChain::getRuntimePath(),25# ToolChain::getCompilerRTPath(), and ToolChain::getCompilerRT(..), not entirely26# consistent between these functions, Compiler-RT's CMake code, and overrides27# in different toolchains.28#29# For Fortran, Flang always assumes the library name libflang_rt.a without30# architecture suffix. Hence, we always use the second scheme even as if31# LLVM_ENABLE_PER_TARGET_RUNTIME_DIR=ON, even if it actually set to OFF. It as32# added unconditionally to the library search path by33# ToolChain::getArchSpecificLibPaths(...).34function (get_toolchain_library_subdir outvar)35 set(outval "lib")36 37 if (APPLE)38 # Required to be "darwin" for MachO toolchain.39 get_toolchain_os_dirname(os_dirname)40 set(outval "${outval}/${os_dirname}")41 else ()42 get_toolchain_arch_dirname(arch_dirname)43 set(outval "${outval}/${arch_dirname}")44 endif ()45 46 set(${outvar} "${outval}" PARENT_SCOPE)47endfunction ()48 49 50# Corresponds to Clang's ToolChain::getOSLibName(). Adapted from Compiler-RT.51function (get_toolchain_os_dirname outvar)52 if (ANDROID)53 # The CMAKE_SYSTEM_NAME for Android is "Android", but the OS is Linux and the54 # driver will search for libraries in the "linux" directory.55 set(outval "linux")56 else ()57 string(TOLOWER "${CMAKE_SYSTEM_NAME}" outval)58 endif ()59 set(${outvar} "${outval}" PARENT_SCOPE)60endfunction ()61 62 63# Corresponds to Clang's ToolChain::getRuntimePath(). Adapted from Compiler-RT.64function (get_toolchain_arch_dirname outvar)65 string(REPLACE "-" ";" triple_list ${LLVM_TARGET_TRIPLE})66 list(GET triple_list 0 arch)67 68 if("${arch}" MATCHES "^i.86$")69 # Android uses i686, but that's remapped at a later stage.70 set(arch "i386")71 endif()72 73 string(FIND ${LLVM_TARGET_TRIPLE} "-" dash_index)74 string(SUBSTRING ${LLVM_TARGET_TRIPLE} ${dash_index} -1 triple_suffix)75 string(SUBSTRING ${LLVM_TARGET_TRIPLE} 0 ${dash_index} triple_cpu)76 set(arch "${triple_cpu}")77 if("${arch}" MATCHES "^i.86$")78 # Android uses i686, but that's remapped at a later stage.79 set(arch "i386")80 endif()81 82 if(ANDROID AND ${arch} STREQUAL "i386")83 set(target "i686${triple_suffix}")84 elseif(${arch} STREQUAL "amd64")85 set(target "x86_64${triple_suffix}")86 elseif(${arch} STREQUAL "sparc64")87 set(target "sparcv9${triple_suffix}")88 elseif("${arch}" MATCHES "mips64|mips64el")89 string(REGEX REPLACE "-gnu.*" "-gnuabi64" triple_suffix_gnu "${triple_suffix}")90 string(REGEX REPLACE "mipsisa32" "mipsisa64" triple_cpu_mips "${triple_cpu}")91 string(REGEX REPLACE "^mips$" "mips64" triple_cpu_mips "${triple_cpu_mips}")92 string(REGEX REPLACE "^mipsel$" "mips64el" triple_cpu_mips "${triple_cpu_mips}")93 set(target "${triple_cpu_mips}${triple_suffix_gnu}")94 elseif("${arch}" MATCHES "mips|mipsel")95 string(REGEX REPLACE "-gnuabi.*" "-gnu" triple_suffix_gnu "${triple_suffix}")96 string(REGEX REPLACE "mipsisa64" "mipsisa32" triple_cpu_mips "${triple_cpu}")97 string(REGEX REPLACE "mips64" "mips" triple_cpu_mips "${triple_cpu_mips}")98 set(target "${triple_cpu_mips}${triple_suffix_gnu}")99 elseif("${arch}" MATCHES "^arm")100 # FIXME: Handle arch other than arm, armhf, armv6m101 if (${arch} STREQUAL "armhf")102 # If we are building for hard float but our ABI is soft float.103 if ("${triple_suffix}" MATCHES ".*eabi$")104 # Change "eabi" -> "eabihf"105 set(triple_suffix "${triple_suffix}hf")106 endif()107 # ABI is already set in the triple, don't repeat it in the architecture.108 set(arch "arm")109 else ()110 # If we are building for soft float, but the triple's ABI is hard float.111 if ("${triple_suffix}" MATCHES ".*eabihf$")112 # Change "eabihf" -> "eabi"113 string(REGEX REPLACE "hf$" "" triple_suffix "${triple_suffix}")114 endif()115 endif()116 set(target "${arch}${triple_suffix}")117 elseif("${arch}" MATCHES "^amdgcn")118 set(target "amdgcn-amd-amdhsa")119 elseif("${arch}" MATCHES "^nvptx")120 set(target "nvptx64-nvidia-cuda")121 else()122 set(target "${arch}${triple_suffix}")123 endif()124 set(${outvar} "${target}" PARENT_SCOPE)125endfunction()126