Reapply #2 of [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. Since the previous attempt, this no longer uses llvm_enable_language_nolink (and thus doesn't set CMAKE_TRY_COMPILE_TARGET_TYPE=STATIC_LIBRARY during the compiler sanity checks). Setting CMAKE_TRY_COMPILE_TARGET_TYPE=STATIC_LIBRARY during compiler sanity checks makes cmake not learn about some aspects of the compiler, which can make further find_library or find_package fail. This caused OpenMP to not detect libelf and libffi, disabling some OpenMP target plugins. Instead, require the caller to set CMAKE_{C,CXX}_COMPILER_WORKS=YES when building in a configuration with an incomplete toolchain. Differential Revision: https://reviews.llvm.org/D113253
This commit is contained in:
parent
a9a1499080
commit
529a79302b
|
@ -765,6 +765,13 @@ function(cxx_link_system_libraries target)
|
||||||
target_add_link_flags_if_supported(${target} PRIVATE "/nodefaultlib")
|
target_add_link_flags_if_supported(${target} PRIVATE "/nodefaultlib")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if (LIBCXX_SUPPORTS_UNWINDLIB_NONE_FLAG AND LIBCXXABI_USE_LLVM_UNWINDER)
|
||||||
|
# If we're linking directly against the libunwind that we're building
|
||||||
|
# in the same invocation, don't try to link in the toolchain's
|
||||||
|
# default libunwind (which may be missing still).
|
||||||
|
target_add_link_flags_if_supported(${target} PRIVATE "--unwindlib=none")
|
||||||
|
endif()
|
||||||
|
|
||||||
if (LIBCXX_HAS_SYSTEM_LIB)
|
if (LIBCXX_HAS_SYSTEM_LIB)
|
||||||
target_link_libraries(${target} PRIVATE System)
|
target_link_libraries(${target} PRIVATE System)
|
||||||
endif()
|
endif()
|
||||||
|
|
|
@ -1,9 +1,22 @@
|
||||||
include(CMakePushCheckState)
|
include(CMakePushCheckState)
|
||||||
include(CheckLibraryExists)
|
include(CheckLibraryExists)
|
||||||
|
include(CheckLinkerFlag)
|
||||||
include(CheckCCompilerFlag)
|
include(CheckCCompilerFlag)
|
||||||
include(CheckCXXCompilerFlag)
|
include(CheckCXXCompilerFlag)
|
||||||
include(CheckCSourceCompiles)
|
include(CheckCSourceCompiles)
|
||||||
|
|
||||||
|
# The compiler driver may be implicitly trying to link against libunwind.
|
||||||
|
# This is normally ok (libcxx relies on an unwinder), but if libunwind is
|
||||||
|
# built in the same cmake invocation as libcxx and we've got
|
||||||
|
# LIBCXXABI_USE_LLVM_UNWINDER set, we'd be linking against the just-built
|
||||||
|
# libunwind (and the compiler implicit -lunwind wouldn't succeed as the newly
|
||||||
|
# built libunwind isn't installed yet). For those cases, it'd be good to
|
||||||
|
# link with --uwnindlib=none. Check if that option works.
|
||||||
|
llvm_check_linker_flag("--unwindlib=none" LIBCXX_SUPPORTS_UNWINDLIB_NONE_FLAG)
|
||||||
|
if (LIBCXX_SUPPORTS_UNWINDLIB_NONE_FLAG)
|
||||||
|
set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} --unwindlib=none")
|
||||||
|
endif()
|
||||||
|
|
||||||
if(WIN32 AND NOT MINGW)
|
if(WIN32 AND NOT MINGW)
|
||||||
# NOTE(compnerd) this is technically a lie, there is msvcrt, but for now, lets
|
# NOTE(compnerd) this is technically a lie, there is msvcrt, but for now, lets
|
||||||
# let the default linking take care of that.
|
# let the default linking take care of that.
|
||||||
|
|
|
@ -32,6 +32,8 @@ find_package(Clang PATHS "${LLVM_BINARY_DIR}" NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT
|
||||||
list(INSERT CMAKE_MODULE_PATH 0
|
list(INSERT CMAKE_MODULE_PATH 0
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/cmake"
|
"${CMAKE_CURRENT_SOURCE_DIR}/cmake"
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules"
|
"${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"
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/../llvm/cmake/modules"
|
"${CMAKE_CURRENT_SOURCE_DIR}/../llvm/cmake/modules"
|
||||||
)
|
)
|
||||||
|
@ -84,14 +86,29 @@ set(LLVM_CMAKE_DIR ${LLVM_MAIN_SRC_DIR}/cmake/modules)
|
||||||
set(LLVM_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../llvm)
|
set(LLVM_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../llvm)
|
||||||
|
|
||||||
include(CheckLibraryExists)
|
include(CheckLibraryExists)
|
||||||
|
include(CheckLinkerFlag)
|
||||||
include(CheckCCompilerFlag)
|
include(CheckCCompilerFlag)
|
||||||
include(CheckCXXCompilerFlag)
|
include(CheckCXXCompilerFlag)
|
||||||
|
|
||||||
|
|
||||||
|
check_c_compiler_flag("" LLVM_RUNTIMES_LINKING_WORKS)
|
||||||
|
if (NOT LLVM_RUNTIMES_LINKING_WORKS)
|
||||||
|
# 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.
|
||||||
|
# Don't add this if not necessary to fix linking, as it can break using
|
||||||
|
# e.g. ASAN/TSAN.
|
||||||
|
llvm_check_linker_flag("--unwindlib=none" LLVM_RUNTIMES_SUPPORT_UNWINDLIB_NONE_FLAG)
|
||||||
|
if (LLVM_RUNTIMES_SUPPORT_UNWINDLIB_NONE_FLAG)
|
||||||
|
set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} --unwindlib=none")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
# Disable use of the installed C++ standard library when building runtimes.
|
# Disable use of the installed C++ standard library when building runtimes.
|
||||||
# Check for -nostdlib++ first; if there's no C++ standard library yet,
|
# Check for -nostdlib++ first; if there's no C++ standard library yet,
|
||||||
# all check_cxx_compiler_flag commands will fail until we add -nostdlib++
|
# all check_cxx_compiler_flag commands will fail until we add -nostdlib++
|
||||||
# (or -nodefaultlibs).
|
# (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)
|
if (LLVM_RUNTIMES_SUPPORT_NOSTDLIBXX_FLAG)
|
||||||
set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -nostdlib++")
|
set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -nostdlib++")
|
||||||
endif()
|
endif()
|
||||||
|
|
Loading…
Reference in a new issue