From a73c0bb79393a3bcef21da36d5ea2ab2585958ba Mon Sep 17 00:00:00 2001 From: Martin Kinkelin Date: Fri, 11 Apr 2025 14:23:59 +0200 Subject: [PATCH 1/4] CMake: Improve default value of COMPILER_RT_LIBDIR_OS on non-Mac Posix By preferring the LLVM host target triple (instead of hardcoding a Linux x86_64 glibc one), and falling back to the OS name alone if that directory exists. --- .github/workflows/main.yml | 5 ++--- CMakeLists.txt | 9 ++++++++- cmake/Modules/FindLLVM.cmake | 1 + 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index d11623042bd..b3699a39e49 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -36,8 +36,6 @@ jobs: - job_name: Linux aarch64 os: ubuntu-22.04-arm arch: aarch64 - base_cmake_flags: >- - -DCOMPILER_RT_LIBDIR_OS=aarch64-unknown-linux-gnu extra_cmake_flags: >- -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ @@ -52,7 +50,6 @@ jobs: container_image: alpine:3.21 arch: x86_64 base_cmake_flags: >- - -DCOMPILER_RT_LIBDIR_OS=linux -DLDC_INSTALL_LLVM_RUNTIME_LIBS_ARCH=x86_64 -DLLVM_IS_SHARED=OFF -DLDC_ENABLE_PLUGINS=OFF @@ -254,6 +251,8 @@ jobs: os: android arch: armv7a android_x86_arch: i686 + extra_cmake_flags: >- + -DCOMPILER_RT_LIBDIR_OS=linux - job_name: Android aarch64 host_os: ubuntu-22.04 diff --git a/CMakeLists.txt b/CMakeLists.txt index 5f05e1f80db..84f2e164716 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -823,7 +823,14 @@ set(COMPILER_RT_LIBDIR "${COMPILER_RT_LIBDIR}/lib") if(APPLE) set(COMPILER_RT_LIBDIR "${COMPILER_RT_LIBDIR}/darwin") elseif(UNIX) - set(COMPILER_RT_LIBDIR_OS_DEFAULT "x86_64-unknown-linux-gnu") + set(COMPILER_RT_LIBDIR_OS_DEFAULT "${LLVM_HOST_TARGET}") # default when building compiler-rt alongside LLVM + if(NOT EXISTS "${COMPILER_RT_LIBDIR}/${COMPILER_RT_LIBDIR_OS_DEFAULT}") + # default when building compiler-rt separately: OS name alone in lowercase + string(TOLOWER "${CMAKE_SYSTEM_NAME}" lowercase_CMAKE_SYSTEM_NAME) + if(EXISTS "${COMPILER_RT_LIBDIR}/${lowercase_CMAKE_SYSTEM_NAME}") + set(COMPILER_RT_LIBDIR_OS_DEFAULT "${lowercase_CMAKE_SYSTEM_NAME}") + endif() + endif() set(COMPILER_RT_LIBDIR_OS "${COMPILER_RT_LIBDIR_OS_DEFAULT}" CACHE STRING "Non-Mac Posix: OS used as directory name for the compiler-rt source libraries, e.g., 'freebsd'.") set(COMPILER_RT_LIBDIR "${COMPILER_RT_LIBDIR}/${COMPILER_RT_LIBDIR_OS}") elseif(WIN32) diff --git a/cmake/Modules/FindLLVM.cmake b/cmake/Modules/FindLLVM.cmake index 03b868f3c3c..95b3244ce67 100644 --- a/cmake/Modules/FindLLVM.cmake +++ b/cmake/Modules/FindLLVM.cmake @@ -142,6 +142,7 @@ else() llvm_set(INCLUDE_DIRS includedir true) llvm_set(ROOT_DIR prefix true) llvm_set(ENABLE_ASSERTIONS assertion-mode) + llvm_set(HOST_TARGET host-target) # The LLVM version string _may_ contain a git/svn suffix, so match only the x.y.z part string(REGEX MATCH "^[0-9]+[.][0-9]+[.][0-9]+" LLVM_VERSION_BASE_STRING "${LLVM_VERSION_STRING}") From cf624b2b667a189377d4b07a00b584554403ad61 Mon Sep 17 00:00:00 2001 From: Martin Kinkelin Date: Fri, 11 Apr 2025 14:30:10 +0200 Subject: [PATCH 2/4] CMake: Warn if expected compiler-rt directory doesn't exist --- CMakeLists.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 84f2e164716..402b45516f9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -836,6 +836,9 @@ elseif(UNIX) elseif(WIN32) set(COMPILER_RT_LIBDIR "${COMPILER_RT_LIBDIR}/windows") endif() +if(NOT EXISTS "${COMPILER_RT_LIBDIR}") + message(WARNING "Expected compiler-rt directory '${COMPILER_RT_LIBDIR}' does not exist. To include PGO and sanitizers support, please set COMPILER_RT_LIBDIR_OS to the correct last component of this path.") +endif() if(LLVM_IS_SHARED) set(LDC_INSTALL_LLVM_RUNTIME_LIBS_DEFAULT OFF) else() From 86a53591f65362114133db34b6d1850e4d398cd9 Mon Sep 17 00:00:00 2001 From: Martin Kinkelin Date: Fri, 11 Apr 2025 19:43:26 +0200 Subject: [PATCH 3/4] linker-gcc: Support triple-'OS' compiler-rt directory in compiler too Not just in CMake. --- driver/linker-gcc.cpp | 36 ++++++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/driver/linker-gcc.cpp b/driver/linker-gcc.cpp index a41afb9bc59..9193245c1ad 100644 --- a/driver/linker-gcc.cpp +++ b/driver/linker-gcc.cpp @@ -269,26 +269,34 @@ std::string getCompilerRTLibFilename(const llvm::Twine &name, // See clang/lib/Driver/Toolchain.cpp. std::vector getRelativeClangCompilerRTLibPath( const llvm::Twine &name, const llvm::Triple &triple, bool sharedLibrary) { - llvm::StringRef OSName = triple.isOSDarwin() ? "darwin" - : triple.isOSFreeBSD() ? "freebsd" - : triple.getOSName(); - auto llvm_major_version = llvm::StringRef(ldc::llvm_version_base).take_until([](char c) { return c == '.'; }); + LLSmallVector llvmVersionCandidates = { + ldc::llvm_version_base, llvm_major_version}; - std::string relPath = (llvm::Twine("clang/") + ldc::llvm_version_base + - "/lib/" + OSName + "/" + name) - .str(); - std::string relPath_llvm_major_version = - (llvm::Twine("clang/") + llvm_major_version + "/lib/" + OSName + "/" + - name) - .str(); + LLSmallVector osNameCandidates; + if (triple.isOSDarwin()) { + osNameCandidates.emplace_back("darwin"); + } else { + osNameCandidates.emplace_back(triple.str()); + // using getOSTypeName() to avoid any OS version substring + osNameCandidates.emplace_back(llvm::Triple::getOSTypeName(triple.getOS())); + } - return {getCompilerRTLibFilename(relPath, triple, sharedLibrary), - getCompilerRTLibFilename(relPath_llvm_major_version, triple, - sharedLibrary)}; + std::vector r; + for (auto osName : osNameCandidates) { + for (auto llvmVersion : llvmVersionCandidates) { + std::string relPath = + (llvm::Twine("clang/") + llvmVersion + "/lib/" + osName + "/" + name) + .str(); + + r.push_back(getCompilerRTLibFilename(relPath, triple, sharedLibrary)); + } + } + + return r; } void appendFullLibPathCandidates(std::vector &paths, From 92c8b5f597892b5af1b20e7c505967f30d1a1f13 Mon Sep 17 00:00:00 2001 From: Martin Kinkelin Date: Fri, 11 Apr 2025 19:58:29 +0200 Subject: [PATCH 4/4] Android: Fix expected compiler-rt OS dir name And the arch filename part. --- .github/workflows/main.yml | 3 --- CMakeLists.txt | 2 ++ driver/linker-gcc.cpp | 7 +++++-- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index b3699a39e49..5059991276b 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -251,8 +251,6 @@ jobs: os: android arch: armv7a android_x86_arch: i686 - extra_cmake_flags: >- - -DCOMPILER_RT_LIBDIR_OS=linux - job_name: Android aarch64 host_os: ubuntu-22.04 @@ -260,7 +258,6 @@ jobs: arch: aarch64 android_x86_arch: x86_64 extra_cmake_flags: >- - -DCOMPILER_RT_LIBDIR_OS=linux -DLDC_INSTALL_LLVM_RUNTIME_LIBS_ARCH=aarch64-android name: ${{ matrix.job_name }} diff --git a/CMakeLists.txt b/CMakeLists.txt index 402b45516f9..9708b0b12f6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -822,6 +822,8 @@ endif() set(COMPILER_RT_LIBDIR "${COMPILER_RT_LIBDIR}/lib") if(APPLE) set(COMPILER_RT_LIBDIR "${COMPILER_RT_LIBDIR}/darwin") +elseif(ANDROID) + set(COMPILER_RT_LIBDIR "${COMPILER_RT_LIBDIR}/linux") elseif(UNIX) set(COMPILER_RT_LIBDIR_OS_DEFAULT "${LLVM_HOST_TARGET}") # default when building compiler-rt alongside LLVM if(NOT EXISTS "${COMPILER_RT_LIBDIR}/${COMPILER_RT_LIBDIR_OS_DEFAULT}") diff --git a/driver/linker-gcc.cpp b/driver/linker-gcc.cpp index 9193245c1ad..cc522553e7c 100644 --- a/driver/linker-gcc.cpp +++ b/driver/linker-gcc.cpp @@ -243,8 +243,9 @@ bool ArgsBuilder::isLldDefaultLinker() { // Returns the arch name as used in the compiler_rt libs. // FIXME: implement correctly for non-x86 platforms (e.g. ARM) // See clang/lib/Driver/Toolchain.cpp. -llvm::StringRef getCompilerRTArchName(const llvm::Triple &triple) { - return triple.getArchName(); +std::string getCompilerRTArchName(const llvm::Triple &triple) { + llvm::StringRef archName = triple.getArchName(); + return (triple.isAndroid() ? archName + "-android" : archName).str(); } // Appends arch suffix and extension. @@ -279,6 +280,8 @@ std::vector getRelativeClangCompilerRTLibPath( LLSmallVector osNameCandidates; if (triple.isOSDarwin()) { osNameCandidates.emplace_back("darwin"); + } else if (triple.isAndroid()) { + osNameCandidates.emplace_back("linux"); } else { osNameCandidates.emplace_back(triple.str()); // using getOSTypeName() to avoid any OS version substring