|
| 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-exception |
| 6 | +# |
| 7 | +#===------------------------------------------------------------------------===# |
| 8 | + |
| 9 | +include(GNUInstallDirs) |
| 10 | + |
| 11 | + |
| 12 | +# Determine the subdirectory relative to Clang's resource dir/sysroot where to |
| 13 | +# install target-specific libraries, to be found by Clang/Flang driver. This was |
| 14 | +# adapted from Compiler-RT's mechanism to find the path for |
| 15 | +# libclang_rt.builtins.a. |
| 16 | +# |
| 17 | +# Compiler-RT has two mechanisms for the path (simplified): |
| 18 | +# |
| 19 | +# * LLVM_ENABLE_PER_TARGET_RUNTIME_DIR=1: lib/${oslibname}/libclang_rt.builtins-${arch}.a |
| 20 | +# * LLVM_ENABLE_PER_TARGET_RUNTIME_DIR=0: lib/${triple}/libclang_rt.builtins.a |
| 21 | +# |
| 22 | +# LLVM_ENABLE_PER_TARGET_RUNTIME_DIR=ON is the newer scheme, but the old one is |
| 23 | +# currently still used for some platforms such as Windows. Clang looks for which |
| 24 | +# of the files exist before passing the path to the linker. Hence, the |
| 25 | +# directories have to match what Clang is looking for, which is done in |
| 26 | +# ToolChain::getArchSpecificLibPaths(..), ToolChain::getRuntimePath(), |
| 27 | +# ToolChain::getCompilerRTPath(), and ToolChain::getCompilerRT(..), not entirely |
| 28 | +# consistent between these functions, Compiler-RT's CMake code, and overrides |
| 29 | +# in different toolchains. |
| 30 | +# |
| 31 | +# For Fortran, Flang always assumes the library name libflang_rt.a without |
| 32 | +# architecture suffix. Hence, we always use the second scheme even as if |
| 33 | +# LLVM_ENABLE_PER_TARGET_RUNTIME_DIR=ON, even if it actually set to OFF. It as |
| 34 | +# added unconditionally to the library search path by |
| 35 | +# ToolChain::getArchSpecificLibPaths(...). |
| 36 | +function (get_toolchain_library_subdir outvar) |
| 37 | + if (NOT APPLE) |
| 38 | + set(outval "${CMAKE_INSTALL_LIBDIR}") |
| 39 | + else () |
| 40 | + # Required to be "darwin" for MachO toolchain. |
| 41 | + get_toolchain_os_dirname(os_dirname) |
| 42 | + set(outval "${CMAKE_INSTALL_LIBDIR}/${os_dirname}") |
| 43 | + endif () |
| 44 | + |
| 45 | + get_toolchain_arch_dirname(arch_dirname) |
| 46 | + set(outval "${CMAKE_INSTALL_LIBDIR}/${arch_dirname}") |
| 47 | + |
| 48 | + set(${outvar} "${outval}" PARENT_SCOPE) |
| 49 | +endfunction () |
| 50 | + |
| 51 | + |
| 52 | +# Corresponds to Clang's ToolChain::getOSLibName(). Adapted from Compiler-RT. |
| 53 | +function (get_toolchain_os_dirname outvar) |
| 54 | + if (ANDROID) |
| 55 | + # The CMAKE_SYSTEM_NAME for Android is "Android", but the OS is Linux and the |
| 56 | + # driver will search for libraries in the "linux" directory. |
| 57 | + set(outval "linux") |
| 58 | + else () |
| 59 | + string(TOLOWER "${CMAKE_SYSTEM_NAME}" outval) |
| 60 | + endif () |
| 61 | + set(${outvar} "${outval}" PARENT_SCOPE) |
| 62 | +endfunction () |
| 63 | + |
| 64 | + |
| 65 | +# Corresponds to Clang's ToolChain::getRuntimePath(). Adapted from Compiler-RT. |
| 66 | +function (get_toolchain_arch_dirname outvar) |
| 67 | + string(REPLACE "-" ";" triple_list ${LLVM_TARGET_TRIPLE}) |
| 68 | + list(GET triple_list 0 arch) |
| 69 | + |
| 70 | + if("${arch}" MATCHES "^i.86$") |
| 71 | + # Android uses i686, but that's remapped at a later stage. |
| 72 | + set(arch "i386") |
| 73 | + endif() |
| 74 | + |
| 75 | + string(FIND ${LLVM_TARGET_TRIPLE} "-" dash_index) |
| 76 | + string(SUBSTRING ${LLVM_TARGET_TRIPLE} ${dash_index} -1 triple_suffix) |
| 77 | + string(SUBSTRING ${LLVM_TARGET_TRIPLE} 0 ${dash_index} triple_cpu) |
| 78 | + set(arch "${triple_cpu}") |
| 79 | + if("${arch}" MATCHES "^i.86$") |
| 80 | + # Android uses i686, but that's remapped at a later stage. |
| 81 | + set(arch "i386") |
| 82 | + endif() |
| 83 | + |
| 84 | + if(ANDROID AND ${arch} STREQUAL "i386") |
| 85 | + set(target "i686${triple_suffix}") |
| 86 | + elseif(${arch} STREQUAL "amd64") |
| 87 | + set(target "x86_64${triple_suffix}") |
| 88 | + elseif(${arch} STREQUAL "sparc64") |
| 89 | + set(target "sparcv9${triple_suffix}") |
| 90 | + elseif("${arch}" MATCHES "mips64|mips64el") |
| 91 | + string(REGEX REPLACE "-gnu.*" "-gnuabi64" triple_suffix_gnu "${triple_suffix}") |
| 92 | + string(REGEX REPLACE "mipsisa32" "mipsisa64" triple_cpu_mips "${triple_cpu}") |
| 93 | + string(REGEX REPLACE "^mips$" "mips64" triple_cpu_mips "${triple_cpu_mips}") |
| 94 | + string(REGEX REPLACE "^mipsel$" "mips64el" triple_cpu_mips "${triple_cpu_mips}") |
| 95 | + set(target "${triple_cpu_mips}${triple_suffix_gnu}") |
| 96 | + elseif("${arch}" MATCHES "mips|mipsel") |
| 97 | + string(REGEX REPLACE "-gnuabi.*" "-gnu" triple_suffix_gnu "${triple_suffix}") |
| 98 | + string(REGEX REPLACE "mipsisa64" "mipsisa32" triple_cpu_mips "${triple_cpu}") |
| 99 | + string(REGEX REPLACE "mips64" "mips" triple_cpu_mips "${triple_cpu_mips}") |
| 100 | + set(target "${triple_cpu_mips}${triple_suffix_gnu}") |
| 101 | + elseif("${arch}" MATCHES "^arm") |
| 102 | + # FIXME: Handle arch other than arm, armhf, armv6m |
| 103 | + if (${arch} STREQUAL "armhf") |
| 104 | + # If we are building for hard float but our ABI is soft float. |
| 105 | + if ("${triple_suffix}" MATCHES ".*eabi$") |
| 106 | + # Change "eabi" -> "eabihf" |
| 107 | + set(triple_suffix "${triple_suffix}hf") |
| 108 | + endif() |
| 109 | + # ABI is already set in the triple, don't repeat it in the architecture. |
| 110 | + set(arch "arm") |
| 111 | + else () |
| 112 | + # If we are building for soft float, but the triple's ABI is hard float. |
| 113 | + if ("${triple_suffix}" MATCHES ".*eabihf$") |
| 114 | + # Change "eabihf" -> "eabi" |
| 115 | + string(REGEX REPLACE "hf$" "" triple_suffix "${triple_suffix}") |
| 116 | + endif() |
| 117 | + endif() |
| 118 | + set(target "${arch}${triple_suffix}") |
| 119 | + elseif("${arch}" MATCHES "^amdgcn") |
| 120 | + set(target "amdgcn-amd-amdhsa") |
| 121 | + elseif("${arch}" MATCHES "^nvptx") |
| 122 | + set(target "nvptx64-nvidia-cuda") |
| 123 | + else() |
| 124 | + set(target "${arch}${triple_suffix}") |
| 125 | + endif() |
| 126 | + set(${outvar} "${target}" PARENT_SCOPE) |
| 127 | +endfunction() |
0 commit comments