Skip to content

Commit cd173cb

Browse files
committed
[clang][compiler-rt] Support LLVM_ENABLE_PER_TARGET_RUNTIME_DIR on Arm Linux and BSD
The orginal single folder layout produced libraries in the form: lib/linux/<libname>-<archname>.a That archname for Arm depended on whether you had hard or soft float. This is sometimes shown as "arm" (soft) vs. "armhf" (hard). If this is set in a triple we do it in the final portion, the ABI. "gnueabi" for soft float, "gnueabihf" for hard float. Meaning that the expected triple is: arm-unknown-linux-gnueabihf Not this: armhf-unknown-linux-gnueabihf For the per target layout I have decided to rely on the ABI portion of the triple instead of the arch name used for the old layout (doing that would produce the invalid triple above). This means that building with triple: armv8l-unknown-linux-gnueabihf Will result in libraries in: lib/arm-unknown-linux-gnueabihf/ And clang will now know to look for "arm" instead of "armv8l". Meaning that we can share libraries between an armv8 and armv7 build as we did with the previous layout. In addition to handling spelling differences e.g. "armv8l" with an "l" on some Linux distros. compiler-rt will autodetect that the "armhf" and/or "arm" architecture can be built. We then replace the given triple's architecture with that. Then if the triple's float ABI doesn't match, we change that. That new triple is then used as the folder name. If you select to build only the given triple, with COMPILER_RT_DEFAULT_TARGET_ONLY, compiler-rt will not autodetect the architecture and for that I assume you know what you're doing. In that case the library path will use the unomdified triple. From what I can tell, this is how most large builds e.g Android and Arm's Embedded Toolchain for llvm do things. I assume that big endian "armeb" builds would end up doing this too. Bare metal builds will not be using per target runtime dirs so they remain as they were. Depends on D139536 Reviewed By: MaskRay, phosek Differential Revision: https://reviews.llvm.org/D140011
1 parent a6f66d5 commit cd173cb

File tree

9 files changed

+74
-2
lines changed

9 files changed

+74
-2
lines changed

clang/lib/Driver/ToolChain.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -578,6 +578,27 @@ ToolChain::path_list ToolChain::getRuntimePaths() const {
578578

579579
addPathForTriple(getTriple());
580580

581+
// When building with per target runtime directories, various ways of naming
582+
// the Arm architecture may have been normalised to simply "arm".
583+
// For example "armv8l" (Armv8 AArch32 little endian) is replaced with "arm".
584+
// Since an armv8l system can use libraries built for earlier architecture
585+
// versions assuming endian and float ABI match.
586+
//
587+
// Original triple: armv8l-unknown-linux-gnueabihf
588+
// Runtime triple: arm-unknown-linux-gnueabihf
589+
//
590+
// We do not do this for armeb (big endian) because doing so could make us
591+
// select little endian libraries. In addition, all known armeb triples only
592+
// use the "armeb" architecture name.
593+
//
594+
// M profile Arm is bare metal and we know they will not be using the per
595+
// target runtime directory layout.
596+
if (getTriple().getArch() == Triple::arm && !getTriple().isArmMClass()) {
597+
llvm::Triple ArmTriple = getTriple();
598+
ArmTriple.setArch(Triple::arm);
599+
addPathForTriple(ArmTriple);
600+
}
601+
581602
// Android targets may include an API level at the end. We still want to fall
582603
// back on a path without the API level.
583604
if (getTriple().isAndroid() &&

clang/test/Driver/Inputs/arm_float_abi_runtime_path/lib/arm-pc-windows-msvc/.keep

Whitespace-only changes.

clang/test/Driver/Inputs/arm_float_abi_runtime_path/lib/arm-unknown-linux-gnueabi/.keep

Whitespace-only changes.

clang/test/Driver/Inputs/arm_float_abi_runtime_path/lib/arm-unknown-linux-gnueabihf/.keep

Whitespace-only changes.

clang/test/Driver/Inputs/arm_float_abi_runtime_path/lib/armeb-unknown-linux-gnueabi/.keep

Whitespace-only changes.

clang/test/Driver/Inputs/arm_float_abi_runtime_path/lib/armeb-unknown-linux-gnueabihf/.keep

Whitespace-only changes.
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/// Check that libraries built with the per target runtime directory layout
2+
/// are selected correctly when using variations of Arm triples.
3+
4+
// REQUIRES: arm-registered-target
5+
6+
// RUN: %clang %s --target=arm-unknown-linux-gnueabihf -print-runtime-dir \
7+
// RUN: -resource-dir=%S/Inputs/arm_float_abi_runtime_path 2>&1 | FileCheck -check-prefix=ARMHF %s
8+
/// "armv7l" should be normalised to just "arm".
9+
// RUN: %clang %s --target=armv7l-unknown-linux-gnueabihf -print-runtime-dir \
10+
// RUN: -resource-dir=%S/Inputs/arm_float_abi_runtime_path 2>&1 | FileCheck -check-prefix=ARMHF %s
11+
12+
// RUN: %clang %s --target=arm-unknown-linux-gnueabi -print-runtime-dir \
13+
// RUN: -resource-dir=%S/Inputs/arm_float_abi_runtime_path 2>&1 | FileCheck -check-prefix=ARM %s
14+
// RUN: %clang %s --target=armv7l-unknown-linux-gnueabi -print-runtime-dir \
15+
// RUN: -resource-dir=%S/Inputs/arm_float_abi_runtime_path 2>&1 | FileCheck -check-prefix=ARM %s
16+
17+
/// armeb triples should be unmodified.
18+
// RUN: %clang %s --target=armeb-unknown-linux-gnueabihf -print-runtime-dir \
19+
// RUN: -resource-dir=%S/Inputs/arm_float_abi_runtime_path 2>&1 | FileCheck -check-prefix=ARMEBHF %s
20+
// RUN: %clang %s --target=armeb-unknown-linux-gnueabi -print-runtime-dir \
21+
// RUN: -resource-dir=%S/Inputs/arm_float_abi_runtime_path 2>&1 | FileCheck -check-prefix=ARMEB %s
22+
23+
// RUN: %clang %s --target=arm-pc-windows-msvc -print-runtime-dir \
24+
// RUN: -resource-dir=%S/Inputs/arm_float_abi_runtime_path 2>&1 | FileCheck -check-prefix=WINDOWS %s
25+
/// armhf-pc... isn't recognised so just check that the float-abi option is ignored
26+
// RUN: %clang %s --target=arm-pc-windows-msvc -mfloat-abi=hard -print-runtime-dir \
27+
// RUN: -resource-dir=%S/Inputs/arm_float_abi_runtime_path 2>&1 | FileCheck -check-prefix=WINDOWS %s
28+
29+
// ARMHF: lib{{/|\\}}arm-unknown-linux-gnueabihf{{$}}
30+
// ARM: lib{{/|\\}}arm-unknown-linux-gnueabi{{$}}
31+
// ARMEBHF: lib{{/|\\}}armeb-unknown-linux-gnueabihf{{$}}
32+
// ARMEB: lib{{/|\\}}armeb-unknown-linux-gnueabi{{$}}
33+
// WINDOWS: lib{{/|\\}}arm-pc-windows-msvc{{$}}

compiler-rt/cmake/Modules/CompilerRTUtils.cmake

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -433,6 +433,25 @@ function(get_compiler_rt_target arch variable)
433433
string(REGEX REPLACE "mipsisa64" "mipsisa32" triple_cpu_mips "${triple_cpu}")
434434
string(REGEX REPLACE "mips64" "mips" triple_cpu_mips "${triple_cpu_mips}")
435435
set(target "${triple_cpu_mips}${triple_suffix_gnu}")
436+
elseif("${arch}" MATCHES "^arm")
437+
# Arch is arm, armhf, armv6m (anything else would come from using
438+
# COMPILER_RT_DEFAULT_TARGET_ONLY, which is checked above).
439+
if (${arch} STREQUAL "armhf")
440+
# If we are building for hard float but our ABI is soft float.
441+
if ("${triple_suffix}" MATCHES ".*eabi$")
442+
# Change "eabi" -> "eabihf"
443+
set(triple_suffix "${triple_suffix}hf")
444+
endif()
445+
# ABI is already set in the triple, don't repeat it in the architecture.
446+
set(arch "arm")
447+
else ()
448+
# If we are building for soft float, but the triple's ABI is hard float.
449+
if ("${triple_suffix}" MATCHES ".*eabihf$")
450+
# Change "eabihf" -> "eabi"
451+
string(REGEX REPLACE "hf$" "" triple_suffix "${triple_suffix}")
452+
endif()
453+
endif()
454+
set(target "${arch}${triple_suffix}")
436455
else()
437456
set(target "${arch}${triple_suffix}")
438457
endif()

llvm/CMakeLists.txt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -817,8 +817,7 @@ endif()
817817
set(LLVM_TARGET_TRIPLE_ENV CACHE STRING "The name of environment variable to override default target. Disabled by blank.")
818818
mark_as_advanced(LLVM_TARGET_TRIPLE_ENV)
819819

820-
# Per target dir not yet supported on Arm 32 bit due to arm vs armhf handling
821-
if(CMAKE_SYSTEM_NAME MATCHES "BSD|Linux" AND NOT CMAKE_SYSTEM_PROCESSOR MATCHES "^arm")
820+
if(CMAKE_SYSTEM_NAME MATCHES "BSD|Linux")
822821
set(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR_default ON)
823822
else()
824823
set(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR_default OFF)

0 commit comments

Comments
 (0)