[libcxx-commits] [PATCH] D113252: [runtimes] Fix building initial libunwind+libcxxabi+libcxx with compiler implied -lunwind

Martin Storsjö via Phabricator via libcxx-commits libcxx-commits at lists.llvm.org
Fri Nov 5 02:56:56 PDT 2021


mstorsjo created this revision.
mstorsjo added reviewers: phosek, hvdijk.
Herald added a subscriber: mgorny.
mstorsjo requested review of this revision.
Herald added projects: libc++, libc++abi.
Herald added a reviewer: libc++.
Herald added a reviewer: libc++abi.

This does mostly the same as D112126 <https://reviews.llvm.org/D112126>, but for the runtimes cmake files.
Most of that is straightforward, but the interdependency between
libcxx and libunwind is tricky:

Libunwind is built at the same time as libcxx, but libunwind is not
installed yet. LIBCXXABI_USE_LLVM_UNWINDER makes libcxx link directly
against the just-built libunwind, but the compiler implicit -lunwind
isn't found. This patch avoids that by adding the intermediate library
output path to `link_directories()`. I have a separate alternative
patch for the same issue that I'll post in tandem.

(There might be a similar interdependency between libcxxabi and
libunwind too - it doesn't show up in my builds targeting Windows,
as libcxxabi is always built statically though. @hvdijk, can you test
using the new build layout by targeting cmake at llvm-project/runtimes
instead of building libunwind/libcxxabi/libcxx individually in your
environment and see how it behaves?)


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D113252

Files:
  libcxx/src/CMakeLists.txt
  runtimes/CMakeLists.txt


Index: runtimes/CMakeLists.txt
===================================================================
--- runtimes/CMakeLists.txt
+++ runtimes/CMakeLists.txt
@@ -1,6 +1,21 @@
 # This file handles building LLVM runtime sub-projects.
 cmake_minimum_required(VERSION 3.13.4)
-project(Runtimes C CXX ASM)
+
+# Add path for custom and the LLVM build's modules to the CMake module path.
+list(INSERT CMAKE_MODULE_PATH 0
+  "${CMAKE_CURRENT_SOURCE_DIR}/cmake"
+  "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules"
+  "${CMAKE_CURRENT_SOURCE_DIR}/../cmake"
+  "${CMAKE_CURRENT_SOURCE_DIR}/../cmake/Modules"
+  "${CMAKE_CURRENT_SOURCE_DIR}/../llvm/cmake"
+  "${CMAKE_CURRENT_SOURCE_DIR}/../llvm/cmake/modules"
+)
+
+# We may have an incomplete toolchain - do language support tests without
+# linking.
+include(EnableLanguageNolink)
+project(Runtimes LANGUAGES NONE)
+llvm_enable_language_nolink(C CXX ASM)
 
 set(LLVM_ALL_RUNTIMES "compiler-rt;libc;libcxx;libcxxabi;libunwind;openmp")
 set(LLVM_ENABLE_RUNTIMES "" CACHE STRING
@@ -28,14 +43,6 @@
 find_package(LLVM PATHS "${LLVM_BINARY_DIR}" NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH)
 find_package(Clang PATHS "${LLVM_BINARY_DIR}" NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH)
 
-# Add path for custom and the LLVM build's modules to the CMake module path.
-list(INSERT CMAKE_MODULE_PATH 0
-  "${CMAKE_CURRENT_SOURCE_DIR}/cmake"
-  "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules"
-  "${CMAKE_CURRENT_SOURCE_DIR}/../llvm/cmake"
-  "${CMAKE_CURRENT_SOURCE_DIR}/../llvm/cmake/modules"
-)
-
 function(get_compiler_rt_path path)
   foreach(entry ${runtimes})
     get_filename_component(projName ${entry} NAME)
@@ -86,14 +93,24 @@
 endif()
 
 include(CheckLibraryExists)
+include(CheckLinkerFlag)
 include(CheckCCompilerFlag)
 include(CheckCXXCompilerFlag)
 
+
+# The compiler driver may be implicitly trying to link against libunwind, which
+# might not work if libunwind doesn't exist yet. Try to check if
+# --unwindlib=none is supported, and use that if possible.
+llvm_check_linker_flag("--unwindlib=none" LIBUNWIND_SUPPORTS_UNWINDLIB_NONE_FLAG)
+if (LIBUNWIND_SUPPORTS_UNWINDLIB_NONE_FLAG)
+  set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} --unwindlib=none")
+endif()
+
 # Disable use of the installed C++ standard library when building runtimes.
 # Check for -nostdlib++ first; if there's no C++ standard library yet,
 # all check_cxx_compiler_flag commands will fail until we add -nostdlib++
 # (or -nodefaultlibs).
-check_c_compiler_flag(-nostdlib++ LLVM_RUNTIMES_SUPPORT_NOSTDLIBXX_FLAG)
+llvm_check_linker_flag(-nostdlib++ LLVM_RUNTIMES_SUPPORT_NOSTDLIBXX_FLAG)
 if (LLVM_RUNTIMES_SUPPORT_NOSTDLIBXX_FLAG)
   set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -nostdlib++")
 endif()
Index: libcxx/src/CMakeLists.txt
===================================================================
--- libcxx/src/CMakeLists.txt
+++ libcxx/src/CMakeLists.txt
@@ -195,6 +195,22 @@
 
 # Build the shared library.
 if (LIBCXX_ENABLE_SHARED)
+  if (LIBCXXABI_USE_LLVM_UNWINDER AND (TARGET unwind OR HAVE_LIBUNWIND))
+    # If the compiler driver implicitly links -lunwind, and it's built as part
+    # of this same build but not installed in the compiler's default lib
+    # directories yet, -lunwind wouldn't be found. (I.e., after adding
+    # implicit options, the linker would be getting the arguments
+    # "<intermediate-lib-dir>/libunwind.<ext> [...] -lunwind".)
+    # Add the intermediate lib directory to the linker path, so that the
+    # linker is given the arguments
+    # "<intermediate-lib-dir>/libunwind.<ext> -L<intermediate-lib-dir>
+    #  [...] -lunwind". The -lunwind should resolve to the recently
+    # built library and nothing gets linked in from there anyway.
+    #
+    # LIBUNWIND_LIBRARY_DIR might not be set yet, but assume it's the same
+    # as LIBCXX_LIBRARY_DIR.
+    link_directories(${LIBCXX_LIBRARY_DIR})
+  endif()
   add_library(cxx_shared SHARED ${exclude_from_all} ${LIBCXX_SOURCES} ${LIBCXX_HEADERS})
   target_link_libraries(cxx_shared PUBLIC cxx-headers
                                    PRIVATE ${LIBCXX_LIBRARIES})


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D113252.385000.patch
Type: text/x-patch
Size: 4083 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/libcxx-commits/attachments/20211105/98d8568e/attachment.bin>


More information about the libcxx-commits mailing list