https://github.com/ldionne created https://github.com/llvm/llvm-project/pull/75089
When we use the -nostdlib++ flag, we don't need to explicitly link against compiler-rt, since the compiler already links against it by default. This simplifies the flags that we need to use when building with Clang and GCC, and opens the door to further simplifications since most platforms won't need to detect whether libgcc and libgcc_s are supported anymore. Furthermore, on platforms where -nostdlib++ is used, this patch prevents manually linking compiler-rt *before* other system libraries. For example, Apple platforms have several compiler-rt symbols defined in libSystem.dylib. If we manually link against compiler-rt, we end up overriding the default link order preferred by the compiler and potentially using the symbols from the clang-provided libclang_rt.a library instead of the system provided one. Note that we don't touch how libunwind links against compiler-rt when it builds the .so/.a because libunwind currently doesn't use -nodefaultlibs and we want to avoid rocking the boat too much. rdar://119506163 >From 60950d80acb9364a5e4bc87dd496f80693e28b2a Mon Sep 17 00:00:00 2001 From: Louis Dionne <ldionn...@gmail.com> Date: Mon, 11 Dec 2023 14:17:26 -0500 Subject: [PATCH] [runtimes] Don't link against compiler-rt explicitly when we use -nostdlib++ When we use the -nostdlib++ flag, we don't need to explicitly link against compiler-rt, since the compiler already links against it by default. This simplifies the flags that we need to use when building with Clang and GCC, and opens the door to further simplifications since most platforms won't need to detect whether libgcc and libgcc_s are supported anymore. Furthermore, on platforms where -nostdlib++ is used, this patch prevents manually linking compiler-rt *before* other system libraries. For example, Apple platforms have several compiler-rt symbols defined in libSystem.dylib. If we manually link against compiler-rt, we end up overriding the default link order preferred by the compiler and potentially using the symbols from the clang-provided libclang_rt.a library instead of the system provided one. Note that we don't touch how libunwind links against compiler-rt when it builds the .so/.a because libunwind currently doesn't use -nodefaultlibs and we want to avoid rocking the boat too much. rdar://119506163 --- libcxx/CMakeLists.txt | 18 ++++++++++-------- libcxx/cmake/config-ix.cmake | 7 ++++++- libcxxabi/cmake/config-ix.cmake | 7 ++++++- libcxxabi/src/CMakeLists.txt | 5 ++++- libunwind/cmake/config-ix.cmake | 7 ++++++- 5 files changed, 32 insertions(+), 12 deletions(-) diff --git a/libcxx/CMakeLists.txt b/libcxx/CMakeLists.txt index 31fc9cec1c57f2..2a1458a098d2e7 100644 --- a/libcxx/CMakeLists.txt +++ b/libcxx/CMakeLists.txt @@ -655,15 +655,17 @@ function(cxx_link_system_libraries target) target_add_link_flags_if_supported(${target} PRIVATE "--unwindlib=none") endif() - if (LIBCXX_USE_COMPILER_RT) - find_compiler_rt_library(builtins LIBCXX_BUILTINS_LIBRARY) - if (LIBCXX_BUILTINS_LIBRARY) - target_link_libraries(${target} PRIVATE "${LIBCXX_BUILTINS_LIBRARY}") + if (MSVC) + if (LIBCXX_USE_COMPILER_RT) + find_compiler_rt_library(builtins LIBCXX_BUILTINS_LIBRARY) + if (LIBCXX_BUILTINS_LIBRARY) + target_link_libraries(${target} PRIVATE "${LIBCXX_BUILTINS_LIBRARY}") + endif() + elseif (LIBCXX_HAS_GCC_LIB) + target_link_libraries(${target} PRIVATE gcc) + elseif (LIBCXX_HAS_GCC_S_LIB) + target_link_libraries(${target} PRIVATE gcc_s) endif() - elseif (LIBCXX_HAS_GCC_LIB) - target_link_libraries(${target} PRIVATE gcc) - elseif (LIBCXX_HAS_GCC_S_LIB) - target_link_libraries(${target} PRIVATE gcc_s) endif() if (LIBCXX_HAS_ATOMIC_LIB) diff --git a/libcxx/cmake/config-ix.cmake b/libcxx/cmake/config-ix.cmake index a365517936e756..1e8c2f5ce46321 100644 --- a/libcxx/cmake/config-ix.cmake +++ b/libcxx/cmake/config-ix.cmake @@ -45,7 +45,9 @@ else() endif() endif() -if (CXX_SUPPORTS_NOSTDLIBXX_FLAG OR C_SUPPORTS_NODEFAULTLIBS_FLAG) +# Only link against compiler-rt manually if we use -nodefaultlibs, since +# otherwise the compiler will do the right thing on its own. +if (NOT CXX_SUPPORTS_NOSTDLIBXX_FLAG AND C_SUPPORTS_NODEFAULTLIBS_FLAG) if (LIBCXX_USE_COMPILER_RT) include(HandleCompilerRT) find_compiler_rt_library(builtins LIBCXX_BUILTINS_LIBRARY @@ -73,6 +75,9 @@ if (CXX_SUPPORTS_NOSTDLIBXX_FLAG OR C_SUPPORTS_NODEFAULTLIBS_FLAG) moldname mingwex msvcrt) list(APPEND CMAKE_REQUIRED_LIBRARIES ${MINGW_LIBRARIES}) endif() +endif() + +if (CXX_SUPPORTS_NOSTDLIBXX_FLAG OR C_SUPPORTS_NODEFAULTLIBS_FLAG) if (CMAKE_C_FLAGS MATCHES -fsanitize OR CMAKE_CXX_FLAGS MATCHES -fsanitize) set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -fno-sanitize=all") endif () diff --git a/libcxxabi/cmake/config-ix.cmake b/libcxxabi/cmake/config-ix.cmake index 39b9284b780ebc..10f2087c68c5e7 100644 --- a/libcxxabi/cmake/config-ix.cmake +++ b/libcxxabi/cmake/config-ix.cmake @@ -33,7 +33,9 @@ else() endif() endif() -if (CXX_SUPPORTS_NOSTDLIBXX_FLAG OR C_SUPPORTS_NODEFAULTLIBS_FLAG) +# Only link against compiler-rt manually if we use -nodefaultlibs, since +# otherwise the compiler will do the right thing on its own. +if (NOT CXX_SUPPORTS_NOSTDLIBXX_FLAG AND C_SUPPORTS_NODEFAULTLIBS_FLAG) if (LIBCXXABI_HAS_C_LIB) list(APPEND CMAKE_REQUIRED_LIBRARIES c) endif () @@ -67,6 +69,9 @@ if (CXX_SUPPORTS_NOSTDLIBXX_FLAG OR C_SUPPORTS_NODEFAULTLIBS_FLAG) moldname mingwex msvcrt) list(APPEND CMAKE_REQUIRED_LIBRARIES ${MINGW_LIBRARIES}) endif() +endif() + +if (CXX_SUPPORTS_NOSTDLIBXX_FLAG OR C_SUPPORTS_NODEFAULTLIBS_FLAG) if (CMAKE_C_FLAGS MATCHES -fsanitize OR CMAKE_CXX_FLAGS MATCHES -fsanitize) set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -fno-sanitize=all") endif () diff --git a/libcxxabi/src/CMakeLists.txt b/libcxxabi/src/CMakeLists.txt index 02031b69fd9156..4198827203fc8b 100644 --- a/libcxxabi/src/CMakeLists.txt +++ b/libcxxabi/src/CMakeLists.txt @@ -166,7 +166,10 @@ if (LIBCXXABI_USE_LLVM_UNWINDER) target_link_libraries(cxxabi_shared_objects PUBLIC unwind_shared) endif() endif() -target_link_libraries(cxxabi_shared_objects PRIVATE cxx-headers ${LIBCXXABI_BUILTINS_LIBRARY} ${LIBCXXABI_LIBRARIES}) +target_link_libraries(cxxabi_shared_objects PRIVATE cxx-headers ${LIBCXXABI_LIBRARIES}) +if (NOT CXX_SUPPORTS_NOSTDLIBXX_FLAG) + target_link_libraries(cxxabi_shared_objects PRIVATE ${LIBCXXABI_BUILTINS_LIBRARY}) +endif() target_link_libraries(cxxabi_shared_objects PUBLIC cxxabi-headers) set_target_properties(cxxabi_shared_objects PROPERTIES diff --git a/libunwind/cmake/config-ix.cmake b/libunwind/cmake/config-ix.cmake index 7df8974b0a9254..126c872f0d4895 100644 --- a/libunwind/cmake/config-ix.cmake +++ b/libunwind/cmake/config-ix.cmake @@ -45,7 +45,9 @@ else() endif() endif() -if (CXX_SUPPORTS_NOSTDLIBXX_FLAG OR C_SUPPORTS_NODEFAULTLIBS_FLAG) +# Only link against compiler-rt manually if we use -nodefaultlibs, since +# otherwise the compiler will do the right thing on its own. +if (NOT CXX_SUPPORTS_NOSTDLIBXX_FLAG AND C_SUPPORTS_NODEFAULTLIBS_FLAG) if (LIBUNWIND_HAS_C_LIB) list(APPEND CMAKE_REQUIRED_LIBRARIES c) endif () @@ -78,6 +80,9 @@ if (CXX_SUPPORTS_NOSTDLIBXX_FLAG OR C_SUPPORTS_NODEFAULTLIBS_FLAG) moldname mingwex msvcrt) list(APPEND CMAKE_REQUIRED_LIBRARIES ${MINGW_LIBRARIES}) endif() +endif() + +if (CXX_SUPPORTS_NOSTDLIBXX_FLAG OR C_SUPPORTS_NODEFAULTLIBS_FLAG) if (CMAKE_C_FLAGS MATCHES -fsanitize OR CMAKE_CXX_FLAGS MATCHES -fsanitize) set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -fno-sanitize=all") endif () _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits