Skip to content

Commit 7c3d19a

Browse files
committed
[runtimes] Fix building initial libunwind+libcxxabi+libcxx with compiler implied -lunwind
This does mostly the same as 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 --unwindlib=none if supported, if we are going to link explicitly against a newly built unwinder anyway. Differential Revision: https://reviews.llvm.org/D113253
1 parent 86d866f commit 7c3d19a

File tree

3 files changed

+52
-10
lines changed

3 files changed

+52
-10
lines changed

libcxx/CMakeLists.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -773,6 +773,13 @@ function(cxx_link_system_libraries target)
773773
target_add_link_flags_if_supported(${target} PRIVATE "/nodefaultlib")
774774
endif()
775775

776+
if (LIBCXX_SUPPORTS_UNWINDLIB_NONE_FLAG AND LIBCXXABI_USE_LLVM_UNWINDER)
777+
# If we're linking directly against the libunwind that we're building
778+
# in the same invocation, don't try to link in the toolchain's
779+
# default libunwind (which may be missing still).
780+
target_add_link_flags_if_supported(${target} PRIVATE "--unwindlib=none")
781+
endif()
782+
776783
if (LIBCXX_HAS_SYSTEM_LIB)
777784
target_link_libraries(${target} PRIVATE System)
778785
endif()

libcxx/cmake/config-ix.cmake

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,22 @@
11
include(CMakePushCheckState)
22
include(CheckLibraryExists)
3+
include(CheckLinkerFlag)
34
include(CheckCCompilerFlag)
45
include(CheckCXXCompilerFlag)
56
include(CheckCSourceCompiles)
67

8+
# The compiler driver may be implicitly trying to link against libunwind.
9+
# This is normally ok (libcxx relies on an unwinder), but if libunwind is
10+
# built in the same cmake invocation as libcxx and we've got
11+
# LIBCXXABI_USE_LLVM_UNWINDER set, we'd be linking against the just-built
12+
# libunwind (and the compiler implicit -lunwind wouldn't succeed as the newly
13+
# built libunwind isn't installed yet). For those cases, it'd be good to
14+
# link with --uwnindlib=none. Check if that option works.
15+
llvm_check_linker_flag("--unwindlib=none" LIBCXX_SUPPORTS_UNWINDLIB_NONE_FLAG)
16+
if (LIBCXX_SUPPORTS_UNWINDLIB_NONE_FLAG)
17+
set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} --unwindlib=none")
18+
endif()
19+
720
if(WIN32 AND NOT MINGW)
821
# NOTE(compnerd) this is technically a lie, there is msvcrt, but for now, lets
922
# let the default linking take care of that.

runtimes/CMakeLists.txt

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,21 @@
11
# This file handles building LLVM runtime sub-projects.
22
cmake_minimum_required(VERSION 3.13.4)
3-
project(Runtimes C CXX ASM)
3+
4+
# Add path for custom and the LLVM build's modules to the CMake module path.
5+
list(INSERT CMAKE_MODULE_PATH 0
6+
"${CMAKE_CURRENT_SOURCE_DIR}/cmake"
7+
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules"
8+
"${CMAKE_CURRENT_SOURCE_DIR}/../cmake"
9+
"${CMAKE_CURRENT_SOURCE_DIR}/../cmake/Modules"
10+
"${CMAKE_CURRENT_SOURCE_DIR}/../llvm/cmake"
11+
"${CMAKE_CURRENT_SOURCE_DIR}/../llvm/cmake/modules"
12+
)
13+
14+
# We may have an incomplete toolchain - do language support tests without
15+
# linking.
16+
include(EnableLanguageNolink)
17+
project(Runtimes LANGUAGES NONE)
18+
llvm_enable_language_nolink(C CXX ASM)
419

520
set(LLVM_ALL_RUNTIMES "compiler-rt;libc;libcxx;libcxxabi;libunwind;openmp")
621
set(LLVM_ENABLE_RUNTIMES "" CACHE STRING
@@ -28,14 +43,6 @@ endfunction()
2843
find_package(LLVM PATHS "${LLVM_BINARY_DIR}" NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH)
2944
find_package(Clang PATHS "${LLVM_BINARY_DIR}" NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH)
3045

31-
# Add path for custom and the LLVM build's modules to the CMake module path.
32-
list(INSERT CMAKE_MODULE_PATH 0
33-
"${CMAKE_CURRENT_SOURCE_DIR}/cmake"
34-
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules"
35-
"${CMAKE_CURRENT_SOURCE_DIR}/../llvm/cmake"
36-
"${CMAKE_CURRENT_SOURCE_DIR}/../llvm/cmake/modules"
37-
)
38-
3946
set(LLVM_THIRD_PARTY_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../third-party")
4047

4148
function(get_compiler_rt_path path)
@@ -88,14 +95,29 @@ if(APPLE)
8895
endif()
8996

9097
include(CheckLibraryExists)
98+
include(CheckLinkerFlag)
9199
include(CheckCCompilerFlag)
92100
include(CheckCXXCompilerFlag)
93101

102+
103+
check_c_compiler_flag("" LLVM_RUNTIMES_LINKING_WORKS)
104+
if (NOT LLVM_RUNTIMES_LINKING_WORKS)
105+
# The compiler driver may be implicitly trying to link against libunwind, which
106+
# might not work if libunwind doesn't exist yet. Try to check if
107+
# --unwindlib=none is supported, and use that if possible.
108+
# Don't add this if not necessary to fix linking, as it can break using
109+
# e.g. ASAN/TSAN.
110+
llvm_check_linker_flag("--unwindlib=none" LLVM_RUNTIMES_SUPPORT_UNWINDLIB_NONE_FLAG)
111+
if (LLVM_RUNTIMES_SUPPORT_UNWINDLIB_NONE_FLAG)
112+
set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} --unwindlib=none")
113+
endif()
114+
endif()
115+
94116
# Disable use of the installed C++ standard library when building runtimes.
95117
# Check for -nostdlib++ first; if there's no C++ standard library yet,
96118
# all check_cxx_compiler_flag commands will fail until we add -nostdlib++
97119
# (or -nodefaultlibs).
98-
check_c_compiler_flag(-nostdlib++ LLVM_RUNTIMES_SUPPORT_NOSTDLIBXX_FLAG)
120+
llvm_check_linker_flag(-nostdlib++ LLVM_RUNTIMES_SUPPORT_NOSTDLIBXX_FLAG)
99121
if (LLVM_RUNTIMES_SUPPORT_NOSTDLIBXX_FLAG)
100122
set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -nostdlib++")
101123
endif()

0 commit comments

Comments
 (0)