[clang] [compiler-rt] [libunwind] [llvm] [clang] recognize any *-ld.lld variant (PR #117338)

Brian Cain via cfe-commits cfe-commits at lists.llvm.org
Fri Nov 22 15:25:52 PST 2024


https://github.com/androm3da updated https://github.com/llvm/llvm-project/pull/117338

>From 40e018ad4a92a20442ad34b0a5b988394e15e609 Mon Sep 17 00:00:00 2001
From: Brian Cain <bcain at quicinc.com>
Date: Thu, 21 Nov 2024 19:46:04 -0800
Subject: [PATCH 1/4] [clang] recognize any *-ld.lld variant

If we create a cross toolchain with a ${triple}-ld.lld symlink, clang finds
that symlink and when it uses it, it's not recognized as "lld".  Let's
resolve that symlink and consider it when determining lld-ness.

For example, clang provides hexagon-link specific link arguments such as
`-mcpu=hexagonv65` and `-march=hexagon` when hexagon-unknown-linux-musl-ld.lld
is found.  lld rejects this with the following error:

    hexagon-unknown-linux-musl-ld.lld: error: unknown emulation: cpu=hexagonv65
---
 clang/lib/Driver/ToolChain.cpp          | 12 +++++++++---
 clang/lib/Driver/ToolChains/Hexagon.cpp |  8 +++++---
 2 files changed, 14 insertions(+), 6 deletions(-)

diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp
index 0d426a467e9a3b..f912cd9229b819 100644
--- a/clang/lib/Driver/ToolChain.cpp
+++ b/clang/lib/Driver/ToolChain.cpp
@@ -964,7 +964,7 @@ std::string ToolChain::GetLinkerPath(bool *LinkerIsLLD) const {
   StringRef UseLinker = A ? A->getValue() : CLANG_DEFAULT_LINKER;
 
   // --ld-path= takes precedence over -fuse-ld= and specifies the executable
-  // name. -B, COMPILER_PATH and PATH and consulted if the value does not
+  // name. -B, COMPILER_PATH and PATH are consulted if the value does not
   // contain a path component separator.
   // -fuse-ld=lld can be used with --ld-path= to inform clang that the binary
   // that --ld-path= points to is lld.
@@ -974,8 +974,11 @@ std::string ToolChain::GetLinkerPath(bool *LinkerIsLLD) const {
       if (llvm::sys::path::parent_path(Path).empty())
         Path = GetProgramPath(A->getValue());
       if (llvm::sys::fs::can_execute(Path)) {
+        SmallString<1024> RealPath;
+        if (llvm::sys::fs::real_path(Path, RealPath))
+          RealPath = llvm::sys::path::stem(RealPath);
         if (LinkerIsLLD)
-          *LinkerIsLLD = UseLinker == "lld";
+          *LinkerIsLLD = UseLinker == "lld" || RealPath == "lld";
         return std::string(Path);
       }
     }
@@ -1014,8 +1017,11 @@ std::string ToolChain::GetLinkerPath(bool *LinkerIsLLD) const {
 
     std::string LinkerPath(GetProgramPath(LinkerName.c_str()));
     if (llvm::sys::fs::can_execute(LinkerPath)) {
+      SmallString<1024> RealPath;
+      if (llvm::sys::fs::real_path(LinkerPath, RealPath))
+        RealPath = llvm::sys::path::stem(RealPath);
       if (LinkerIsLLD)
-        *LinkerIsLLD = UseLinker == "lld";
+        *LinkerIsLLD = UseLinker == "lld" || RealPath == "lld";
       return LinkerPath;
     }
   }
diff --git a/clang/lib/Driver/ToolChains/Hexagon.cpp b/clang/lib/Driver/ToolChains/Hexagon.cpp
index 29781399cbab44..625979d56730bd 100644
--- a/clang/lib/Driver/ToolChains/Hexagon.cpp
+++ b/clang/lib/Driver/ToolChains/Hexagon.cpp
@@ -294,9 +294,11 @@ constructHexagonLinkArgs(Compilation &C, const JobAction &JA,
   bool IncStartFiles = !Args.hasArg(options::OPT_nostartfiles);
   bool IncDefLibs = !Args.hasArg(options::OPT_nodefaultlibs);
   bool UseG0 = false;
-  const char *Exec = Args.MakeArgString(HTC.GetLinkerPath());
-  bool UseLLD = (llvm::sys::path::filename(Exec).equals_insensitive("ld.lld") ||
-                 llvm::sys::path::stem(Exec).equals_insensitive("ld.lld"));
+  bool UseLLD = false;
+  const char *Exec = Args.MakeArgString(HTC.GetLinkerPath(&UseLLD));
+  UseLLD = UseLLD ||
+           llvm::sys::path::filename(Exec).equals_insensitive("ld.lld") ||
+           llvm::sys::path::stem(Exec).equals_insensitive("ld.lld");
   bool UseShared = IsShared && !IsStatic;
   StringRef CpuVer = toolchains::HexagonToolChain::GetTargetCPUVersion(Args);
 

>From 38439937605ac5471004440d25cc397e637174e5 Mon Sep 17 00:00:00 2001
From: Brian Cain <brian.cain at oss.qualcomm.com>
Date: Fri, 22 Nov 2024 13:49:44 -0800
Subject: [PATCH 2/4] Revert "[cmake] Remove obsolete files, docs and CMake
 variables related to the standalone build (#112741)"

This reverts commit 6127724786d581d2653df7420d1f28709288a107.
---
 cmake/Modules/HandleOutOfTreeLLVM.cmake       | 80 +++++++++++++++++++
 compiler-rt/cmake/Modules/AddCompilerRT.cmake |  1 +
 libunwind/docs/BuildingLibunwind.rst          | 19 ++++-
 .../docs/HowToBuildWindowsItaniumPrograms.rst | 18 +++--
 runtimes/CMakeLists.txt                       |  3 +
 5 files changed, 115 insertions(+), 6 deletions(-)
 create mode 100644 cmake/Modules/HandleOutOfTreeLLVM.cmake

diff --git a/cmake/Modules/HandleOutOfTreeLLVM.cmake b/cmake/Modules/HandleOutOfTreeLLVM.cmake
new file mode 100644
index 00000000000000..edffe572e091e3
--- /dev/null
+++ b/cmake/Modules/HandleOutOfTreeLLVM.cmake
@@ -0,0 +1,80 @@
+if (NOT DEFINED LLVM_PATH)
+  set(LLVM_PATH ${CMAKE_CURRENT_LIST_DIR}/../../llvm CACHE PATH "" FORCE)
+endif()
+
+if(NOT IS_DIRECTORY ${LLVM_PATH})
+  message(FATAL_ERROR
+    "The provided LLVM_PATH (${LLVM_PATH}) is not a valid directory. Note that "
+    "building libc++ outside of the monorepo is not supported anymore. Please "
+    "use a Standalone build against the monorepo, a Runtimes build or a classic "
+    "monorepo build.")
+endif()
+
+set(LLVM_INCLUDE_DIR ${LLVM_PATH}/include CACHE PATH "Path to llvm/include")
+set(LLVM_PATH ${LLVM_PATH} CACHE PATH "Path to LLVM source tree")
+set(LLVM_MAIN_SRC_DIR ${LLVM_PATH})
+set(LLVM_CMAKE_DIR "${LLVM_PATH}/cmake/modules")
+set(LLVM_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR})
+set(LLVM_LIBRARY_OUTPUT_INTDIR "${CMAKE_CURRENT_BINARY_DIR}/lib")
+
+if (EXISTS "${LLVM_CMAKE_DIR}")
+  list(APPEND CMAKE_MODULE_PATH "${LLVM_CMAKE_DIR}")
+elseif (EXISTS "${LLVM_MAIN_SRC_DIR}/cmake/modules")
+  list(APPEND CMAKE_MODULE_PATH "${LLVM_MAIN_SRC_DIR}/cmake/modules")
+else()
+  message(FATAL_ERROR "Neither ${LLVM_CMAKE_DIR} nor ${LLVM_MAIN_SRC_DIR}/cmake/modules found. "
+                      "This is not a supported configuration.")
+endif()
+
+message(STATUS "Configuring for standalone build.")
+
+# By default, we target the host, but this can be overridden at CMake invocation time.
+include(GetHostTriple)
+get_host_triple(LLVM_INFERRED_HOST_TRIPLE)
+set(LLVM_HOST_TRIPLE "${LLVM_INFERRED_HOST_TRIPLE}" CACHE STRING "Host on which LLVM binaries will run")
+set(LLVM_DEFAULT_TARGET_TRIPLE "${LLVM_HOST_TRIPLE}" CACHE STRING "Target triple used by default.")
+
+# Add LLVM Functions --------------------------------------------------------
+if (WIN32)
+  set(LLVM_ON_UNIX 0)
+  set(LLVM_ON_WIN32 1)
+else()
+  set(LLVM_ON_UNIX 1)
+  set(LLVM_ON_WIN32 0)
+endif()
+
+include(AddLLVM OPTIONAL)
+
+# LLVM Options --------------------------------------------------------------
+if (NOT DEFINED LLVM_INCLUDE_TESTS)
+  set(LLVM_INCLUDE_TESTS ON)
+endif()
+if (NOT DEFINED LLVM_INCLUDE_DOCS)
+  set(LLVM_INCLUDE_DOCS ON)
+endif()
+if (NOT DEFINED LLVM_ENABLE_SPHINX)
+  set(LLVM_ENABLE_SPHINX OFF)
+endif()
+
+if (LLVM_INCLUDE_TESTS)
+  # Required LIT Configuration ------------------------------------------------
+  # Define the default arguments to use with 'lit', and an option for the user
+  # to override.
+  set(LLVM_DEFAULT_EXTERNAL_LIT "${LLVM_MAIN_SRC_DIR}/utils/lit/lit.py")
+  set(LIT_ARGS_DEFAULT "-sv --show-xfail --show-unsupported")
+  if (MSVC OR XCODE)
+    set(LIT_ARGS_DEFAULT "${LIT_ARGS_DEFAULT} --no-progress-bar")
+  endif()
+  set(LLVM_LIT_ARGS "${LIT_ARGS_DEFAULT}" CACHE STRING "Default options for lit")
+endif()
+
+# Required doc configuration
+if (LLVM_ENABLE_SPHINX)
+  find_package(Sphinx REQUIRED)
+endif()
+
+if (LLVM_ON_UNIX AND NOT APPLE)
+  set(LLVM_HAVE_LINK_VERSION_SCRIPT 1)
+else()
+  set(LLVM_HAVE_LINK_VERSION_SCRIPT 0)
+endif()
diff --git a/compiler-rt/cmake/Modules/AddCompilerRT.cmake b/compiler-rt/cmake/Modules/AddCompilerRT.cmake
index 77261f631ea117..4053185acce0f8 100644
--- a/compiler-rt/cmake/Modules/AddCompilerRT.cmake
+++ b/compiler-rt/cmake/Modules/AddCompilerRT.cmake
@@ -692,6 +692,7 @@ macro(add_custom_libcxx name prefix)
                -DCMAKE_INSTALL_PREFIX=<INSTALL_DIR>
                -DCMAKE_INSTALL_MESSAGE=LAZY
                -DCMAKE_TRY_COMPILE_TARGET_TYPE=STATIC_LIBRARY
+               -DLLVM_PATH=${LLVM_MAIN_SRC_DIR}
                -DLLVM_ENABLE_RUNTIMES=libcxx|libcxxabi
                -DLIBCXXABI_USE_LLVM_UNWINDER=OFF
                -DLIBCXXABI_ENABLE_SHARED=OFF
diff --git a/libunwind/docs/BuildingLibunwind.rst b/libunwind/docs/BuildingLibunwind.rst
index 8b4f1207d4ba99..79166b4769c617 100644
--- a/libunwind/docs/BuildingLibunwind.rst
+++ b/libunwind/docs/BuildingLibunwind.rst
@@ -16,7 +16,7 @@ On Mac OS, the easiest way to get this library is to link with -lSystem.
 However if you want to build tip-of-trunk from here (getting the bleeding
 edge), read on.
 
-The basic steps needed to build libunwind are:
+The basic steps needed to build libc++ are:
 
 #. Checkout LLVM, libunwind, and related projects:
 
@@ -50,6 +50,23 @@ The basic steps needed to build libunwind are:
    * ``make install-unwind`` --- Will install the libraries and the headers
 
 
+It is sometimes beneficial to build outside of the LLVM tree. An out-of-tree
+build would look like this:
+
+.. code-block:: bash
+
+  $ cd where-you-want-libunwind-to-live
+  $ # Check out llvm, and libunwind
+  $ ``svn co https://llvm.org/svn/llvm-project/llvm/trunk llvm``
+  $ ``svn co https://llvm.org/svn/llvm-project/libunwind/trunk libunwind``
+  $ cd where-you-want-to-build
+  $ mkdir build && cd build
+  $ export CC=clang CXX=clang++
+  $ cmake -DLLVM_PATH=path/to/llvm \
+          path/to/libunwind
+  $ make
+
+
 .. _CMake Options:
 
 CMake Options
diff --git a/llvm/docs/HowToBuildWindowsItaniumPrograms.rst b/llvm/docs/HowToBuildWindowsItaniumPrograms.rst
index 48ca7b25b11ef8..883c1868b753a1 100644
--- a/llvm/docs/HowToBuildWindowsItaniumPrograms.rst
+++ b/llvm/docs/HowToBuildWindowsItaniumPrograms.rst
@@ -73,11 +73,19 @@ The procedure is:
 
 It is also possible to cross-compile from Linux.
 
-To build the libraries in step 2, refer to the `libc++ documentation <https://libcxx.llvm.org/VendorDocumentation.html#the-default-build>`_.
-
-The next section discuss the salient options and modifications required for building and installing the
-libraries. This assumes that we are building libunwind and libc++ as DLLs and statically linking libc++abi
-into libc++. Other build configurations are possible, but they are not discussed here.
+One method of building the libraries in step 2. is to build them "stand-alone".
+A stand-alone build doesn't involve the rest of the LLVM tree. The steps are:
+
+* ``cd build-dir``
+* ``cmake -DLLVM_PATH=<path to llvm checkout e.g. /llvm-project/> -DCMAKE_INSTALL_PREFIX=<install path> <other options> <path to project e.g. /llvm-project/libcxxabi>``
+* ``<make program e.g. ninja>``
+* ``<make program> install``
+
+More information on standalone builds can be found in the build documentation for
+the respective libraries. The next section discuss the salient options and modifications
+required for building and installing the libraries using standalone builds. This assumes
+that we are building libunwind and ibc++ as DLLs and statically linking libc++abi into
+libc++. Other build configurations are possible, but they are not discussed here.
 
 Common CMake configuration options:
 -----------------------------------
diff --git a/runtimes/CMakeLists.txt b/runtimes/CMakeLists.txt
index 832a7d0c193592..830165c799c2ab 100644
--- a/runtimes/CMakeLists.txt
+++ b/runtimes/CMakeLists.txt
@@ -75,6 +75,9 @@ set(LLVM_RUNTIME_OUTPUT_INTDIR ${LLVM_TOOLS_BINARY_DIR})
 set(LLVM_MAIN_SRC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../llvm)
 set(LLVM_CMAKE_DIR ${LLVM_MAIN_SRC_DIR}/cmake/modules)
 
+# This variable is used by individual runtimes to locate LLVM files.
+set(LLVM_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../llvm)
+
 include(CheckLibraryExists)
 include(LLVMCheckCompilerLinkerFlag)
 include(CheckCCompilerFlag)

>From e811e1273522b6008bd1ff73fcf02a5cd7ec92ff Mon Sep 17 00:00:00 2001
From: Brian Cain <brian.cain at oss.qualcomm.com>
Date: Fri, 22 Nov 2024 15:17:28 -0800
Subject: [PATCH 3/4] Fix review suggestion: avoid extra syscall

---
 clang/lib/Driver/ToolChain.cpp | 24 ++++++++++++++++--------
 1 file changed, 16 insertions(+), 8 deletions(-)

diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp
index f912cd9229b819..387d0d690f89ff 100644
--- a/clang/lib/Driver/ToolChain.cpp
+++ b/clang/lib/Driver/ToolChain.cpp
@@ -975,10 +975,14 @@ std::string ToolChain::GetLinkerPath(bool *LinkerIsLLD) const {
         Path = GetProgramPath(A->getValue());
       if (llvm::sys::fs::can_execute(Path)) {
         SmallString<1024> RealPath;
-        if (llvm::sys::fs::real_path(Path, RealPath))
-          RealPath = llvm::sys::path::stem(RealPath);
-        if (LinkerIsLLD)
-          *LinkerIsLLD = UseLinker == "lld" || RealPath == "lld";
+        if (LinkerIsLLD) {
+          *LinkerIsLLD = UseLinker == "lld";
+          if (!*LinkerIsLLD)
+            if (llvm::sys::fs::real_path(Path, RealPath)) {
+              RealPath = llvm::sys::path::stem(RealPath);
+              *LinkerIsLLD = RealPath == "lld";
+            }
+        }
         return std::string(Path);
       }
     }
@@ -1018,10 +1022,14 @@ std::string ToolChain::GetLinkerPath(bool *LinkerIsLLD) const {
     std::string LinkerPath(GetProgramPath(LinkerName.c_str()));
     if (llvm::sys::fs::can_execute(LinkerPath)) {
       SmallString<1024> RealPath;
-      if (llvm::sys::fs::real_path(LinkerPath, RealPath))
-        RealPath = llvm::sys::path::stem(RealPath);
-      if (LinkerIsLLD)
-        *LinkerIsLLD = UseLinker == "lld" || RealPath == "lld";
+      if (LinkerIsLLD) {
+        *LinkerIsLLD = UseLinker == "lld";
+        if (!*LinkerIsLLD)
+          if (llvm::sys::fs::real_path(LinkerPath, RealPath)) {
+            RealPath = llvm::sys::path::stem(RealPath);
+            *LinkerIsLLD = RealPath == "lld";
+          }
+      }
       return LinkerPath;
     }
   }

>From c1464c96ed41518c68bece26a57bb9d1468a234c Mon Sep 17 00:00:00 2001
From: Brian Cain <brian.cain at oss.qualcomm.com>
Date: Fri, 22 Nov 2024 15:25:23 -0800
Subject: [PATCH 4/4] Fix review suggestion: "avoid equals_insensitive"

---
 clang/lib/Driver/ToolChains/Hexagon.cpp | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/clang/lib/Driver/ToolChains/Hexagon.cpp b/clang/lib/Driver/ToolChains/Hexagon.cpp
index 625979d56730bd..bd635573376967 100644
--- a/clang/lib/Driver/ToolChains/Hexagon.cpp
+++ b/clang/lib/Driver/ToolChains/Hexagon.cpp
@@ -296,9 +296,8 @@ constructHexagonLinkArgs(Compilation &C, const JobAction &JA,
   bool UseG0 = false;
   bool UseLLD = false;
   const char *Exec = Args.MakeArgString(HTC.GetLinkerPath(&UseLLD));
-  UseLLD = UseLLD ||
-           llvm::sys::path::filename(Exec).equals_insensitive("ld.lld") ||
-           llvm::sys::path::stem(Exec).equals_insensitive("ld.lld");
+  UseLLD = UseLLD || llvm::sys::path::filename(Exec) == "ld.lld" ||
+           llvm::sys::path::stem(Exec) == "ld.lld";
   bool UseShared = IsShared && !IsStatic;
   StringRef CpuVer = toolchains::HexagonToolChain::GetTargetCPUVersion(Args);
 



More information about the cfe-commits mailing list