[llvm-branch-commits] [libcxx] [libcxxabi] [libunwind] [llvm] [runtimes] Don't create shared library targets when unsupported (PR #205132)

Matt Arsenault via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Mon Jun 22 09:29:00 PDT 2026


https://github.com/arsenm created https://github.com/llvm/llvm-project/pull/205132

On platforms that don't support shared libraries (e.g. CMAKE_SYSTEM_NAME of
"Generic", used for GPU and other baremetal targets), CMake's
Platform/Generic.cmake sets the global TARGET_SUPPORTS_SHARED_LIBS property to
FALSE. Under CMP0164's OLD behavior (the default, since the runtimes set
cmake_minimum_required(3.20)), CMake silently demotes SHARED library targets to
STATIC archives. libcxx, libcxxabi and libunwind always create their shared
target, so after demotion both the shared and static targets emit e.g.
"libc++abi.a" and Ninja fails with "multiple rules generate ...".

Rather than papering over the collision with a distinct output name, skip
creating the shared library targets entirely when the platform does not support
them, gating on the TARGET_SUPPORTS_SHARED_LIBS property (left undefined on
platforms that do support shared libraries). The few consumers of the shared
targets are guarded with TARGET checks so they fall back to the static library
or are skipped.

Also set policy CMP0164 to NEW so that any future unguarded
add_library(... SHARED ...) on an unsupported platform fails at configure time
instead of silently producing a colliding static archive.

See https://gitlab.kitware.com/cmake/cmake/-/issues/25759.

This was mostly AI generated with some comment and indentation fixups. Most of the
diff is just reindenting new conditions. The original generated diff did not
re-indent and was much smaller.

Co-Authored-By: Claude <noreply at anthropic.com>

>From f38770a97bef318ab0387515dbb5c24b1fd5e8fe Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Mon, 22 Jun 2026 18:09:18 +0200
Subject: [PATCH] [runtimes] Don't create shared library targets when
 unsupported

On platforms that don't support shared libraries (e.g. CMAKE_SYSTEM_NAME of
"Generic", used for GPU and other baremetal targets), CMake's
Platform/Generic.cmake sets the global TARGET_SUPPORTS_SHARED_LIBS property to
FALSE. Under CMP0164's OLD behavior (the default, since the runtimes set
cmake_minimum_required(3.20)), CMake silently demotes SHARED library targets to
STATIC archives. libcxx, libcxxabi and libunwind always create their shared
target, so after demotion both the shared and static targets emit e.g.
"libc++abi.a" and Ninja fails with "multiple rules generate ...".

Rather than papering over the collision with a distinct output name, skip
creating the shared library targets entirely when the platform does not support
them, gating on the TARGET_SUPPORTS_SHARED_LIBS property (left undefined on
platforms that do support shared libraries). The few consumers of the shared
targets are guarded with TARGET checks so they fall back to the static library
or are skipped.

Also set policy CMP0164 to NEW so that any future unguarded
add_library(... SHARED ...) on an unsupported platform fails at configure time
instead of silently producing a colliding static archive.

See https://gitlab.kitware.com/cmake/cmake/-/issues/25759.

This was mostly AI generated with some comment and indentation fixups. Most of the
diff is just reindenting new conditions. The original generated diff did not
re-indent and was much smaller.

Co-Authored-By: Claude <noreply at anthropic.com>
---
 cmake/Modules/CMakePolicy.cmake |   6 ++
 libcxx/CMakeLists.txt           |  23 ++--
 libcxx/src/CMakeLists.txt       | 158 +++++++++++++--------------
 libcxxabi/CMakeLists.txt        |  23 ++--
 libcxxabi/src/CMakeLists.txt    | 184 ++++++++++++++++----------------
 libunwind/CMakeLists.txt        |  23 ++--
 libunwind/src/CMakeLists.txt    |  72 +++++++------
 7 files changed, 249 insertions(+), 240 deletions(-)

diff --git a/cmake/Modules/CMakePolicy.cmake b/cmake/Modules/CMakePolicy.cmake
index cf986331707b6..1975580ae171c 100644
--- a/cmake/Modules/CMakePolicy.cmake
+++ b/cmake/Modules/CMakePolicy.cmake
@@ -47,3 +47,9 @@ endif()
 if(POLICY CMP0182)
   cmake_policy(SET CMP0182 NEW)
 endif()
+
+# CMP0164: add_library(... SHARED ...) fails on platforms that do not support
+# shared libraries, instead of silently building a static library.
+if(POLICY CMP0164)
+  cmake_policy(SET CMP0164 NEW)
+endif()
diff --git a/libcxx/CMakeLists.txt b/libcxx/CMakeLists.txt
index 72f1eda6393e6..e58191ccae592 100644
--- a/libcxx/CMakeLists.txt
+++ b/libcxx/CMakeLists.txt
@@ -445,21 +445,20 @@ set(LIBCXX_INSTALL_RUNTIME_DIR "${CMAKE_INSTALL_BINDIR}" CACHE STRING
 set(LIBCXX_INSTALL_MODULES_DIR "share/libc++/v1" CACHE STRING
     "Path where target-agnostic libc++ module source files should be installed.")
 
-# On platforms that don't support shared library targets (e.g. CMAKE_SYSTEM_NAME
-# of "Generic", used for GPU and other baremetal targets), CMake implicitly
-# changes shared library targets into static library targets. The shared target
-# is always defined even when LIBCXX_ENABLE_SHARED is off, so this would result
-# in two targets producing the same "libc++.a" output and break the build. Give
-# the shared library a different default output name in that case so it can't
-# collide with the static library.
-# See https://gitlab.kitware.com/cmake/cmake/-/issues/25759.
+# On platforms that don't support shared library targets
+# (e.g. CMAKE_SYSTEM_NAME of "Generic", used for GPU and other
+# baremetal targets), the shared library target is not built at
+# all. The global TARGET_SUPPORTS_SHARED_LIBS property is left
+# undefined on platforms that do support shared libraries, and only
+# set to FALSE on those that don't. See
+# https://gitlab.kitware.com/cmake/cmake/-/issues/25759.
 get_property(LIBCXX_TARGET_SUPPORTS_SHARED_LIBS GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS)
-if(DEFINED LIBCXX_TARGET_SUPPORTS_SHARED_LIBS AND NOT LIBCXX_TARGET_SUPPORTS_SHARED_LIBS)
-  set(LIBCXX_DEFAULT_SHARED_OUTPUT_NAME "c++-shared")
+if(NOT DEFINED LIBCXX_TARGET_SUPPORTS_SHARED_LIBS OR LIBCXX_TARGET_SUPPORTS_SHARED_LIBS)
+  set(LIBCXX_SUPPORTS_SHARED_LIBRARY ON)
 else()
-  set(LIBCXX_DEFAULT_SHARED_OUTPUT_NAME "c++")
+  set(LIBCXX_SUPPORTS_SHARED_LIBRARY OFF)
 endif()
-set(LIBCXX_SHARED_OUTPUT_NAME "${LIBCXX_DEFAULT_SHARED_OUTPUT_NAME}" CACHE STRING "Output name for the shared libc++ runtime library.")
+set(LIBCXX_SHARED_OUTPUT_NAME "c++" CACHE STRING "Output name for the shared libc++ runtime library.")
 set(LIBCXX_STATIC_OUTPUT_NAME "c++" CACHE STRING "Output name for the static libc++ runtime library.")
 
 # TODO: Use common runtimes infrastructure for output and install paths
diff --git a/libcxx/src/CMakeLists.txt b/libcxx/src/CMakeLists.txt
index de7817ad69f26..4f91994204c67 100644
--- a/libcxx/src/CMakeLists.txt
+++ b/libcxx/src/CMakeLists.txt
@@ -172,89 +172,91 @@ split_list(LIBCXX_LINK_FLAGS)
 include(FindLibcCommonUtils)
 
 # Build the shared library.
-add_library(cxx_shared SHARED ${LIBCXX_SOURCES} ${LIBCXX_HEADERS})
-target_include_directories(cxx_shared PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
-target_link_libraries(cxx_shared PUBLIC cxx-headers runtimes-libc-shared
-                                  PRIVATE ${LIBCXX_LIBRARIES}
-                                  PRIVATE llvm-libc-common-utilities)
-set_target_properties(cxx_shared
-  PROPERTIES
-    EXCLUDE_FROM_ALL "$<IF:$<BOOL:${LIBCXX_ENABLE_SHARED}>,FALSE,TRUE>"
-    COMPILE_FLAGS "${LIBCXX_COMPILE_FLAGS}"
-    LINK_FLAGS    "${LIBCXX_LINK_FLAGS}"
-    OUTPUT_NAME   "${LIBCXX_SHARED_OUTPUT_NAME}"
-    VERSION       "${LIBCXX_LIBRARY_VERSION}"
-    SOVERSION     "${LIBCXX_ABI_VERSION}"
-    DEFINE_SYMBOL ""
-)
-cxx_add_common_build_flags(cxx_shared)
-
-if(ZOS)
-  add_custom_command(TARGET cxx_shared POST_BUILD
-    COMMAND
-      ${LIBCXX_SOURCE_DIR}/utils/zos_rename_dll_side_deck.sh
-      $<TARGET_LINKER_FILE_NAME:cxx_shared> $<TARGET_FILE_NAME:cxx_shared> "${LIBCXX_DLL_NAME}"
-    COMMENT "Rename dll name inside the side deck file"
-    WORKING_DIRECTORY $<TARGET_FILE_DIR:cxx_shared>
+if (LIBCXX_SUPPORTS_SHARED_LIBRARY)
+  add_library(cxx_shared SHARED ${LIBCXX_SOURCES} ${LIBCXX_HEADERS})
+  target_include_directories(cxx_shared PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
+  target_link_libraries(cxx_shared PUBLIC cxx-headers runtimes-libc-shared
+                                   PRIVATE ${LIBCXX_LIBRARIES}
+                                   PRIVATE llvm-libc-common-utilities)
+  set_target_properties(cxx_shared
+    PROPERTIES
+      EXCLUDE_FROM_ALL "$<IF:$<BOOL:${LIBCXX_ENABLE_SHARED}>,FALSE,TRUE>"
+      COMPILE_FLAGS "${LIBCXX_COMPILE_FLAGS}"
+      LINK_FLAGS    "${LIBCXX_LINK_FLAGS}"
+      OUTPUT_NAME   "${LIBCXX_SHARED_OUTPUT_NAME}"
+      VERSION       "${LIBCXX_LIBRARY_VERSION}"
+      SOVERSION     "${LIBCXX_ABI_VERSION}"
+      DEFINE_SYMBOL ""
   )
-endif()
+  cxx_add_common_build_flags(cxx_shared)
+
+  if(ZOS)
+    add_custom_command(TARGET cxx_shared POST_BUILD
+      COMMAND
+        ${LIBCXX_SOURCE_DIR}/utils/zos_rename_dll_side_deck.sh
+        $<TARGET_LINKER_FILE_NAME:cxx_shared> $<TARGET_FILE_NAME:cxx_shared> "${LIBCXX_DLL_NAME}"
+      COMMENT "Rename dll name inside the side deck file"
+      WORKING_DIRECTORY $<TARGET_FILE_DIR:cxx_shared>
+    )
+  endif()
 
-# Link against libc++abi
-if (LIBCXX_STATICALLY_LINK_ABI_IN_SHARED_LIBRARY)
-  target_link_libraries(cxx_shared PRIVATE libcxx-abi-shared-objects)
-else()
-  target_link_libraries(cxx_shared PUBLIC libcxx-abi-shared)
-endif()
+  # Link against libc++abi
+  if (LIBCXX_STATICALLY_LINK_ABI_IN_SHARED_LIBRARY)
+    target_link_libraries(cxx_shared PRIVATE libcxx-abi-shared-objects)
+  else()
+    target_link_libraries(cxx_shared PUBLIC libcxx-abi-shared)
+  endif()
 
-# Maybe force some symbols to be weak, not weak or not exported.
-# TODO: This shouldn't depend on the platform, and ideally it should be done in the sources.
-if (APPLE AND LIBCXX_CXX_ABI MATCHES "libcxxabi$"
-          AND NOT LIBCXX_STATICALLY_LINK_ABI_IN_SHARED_LIBRARY)
-  target_link_libraries(cxx_shared PRIVATE
-    "-Wl,-force_symbols_not_weak_list,${CMAKE_CURRENT_SOURCE_DIR}/../lib/notweak.exp"
-    "-Wl,-force_symbols_weak_list,${CMAKE_CURRENT_SOURCE_DIR}/../lib/weak.exp")
-endif()
+  # Maybe force some symbols to be weak, not weak or not exported.
+  # TODO: This shouldn't depend on the platform, and ideally it should be done in the sources.
+  if (APPLE AND LIBCXX_CXX_ABI MATCHES "libcxxabi$"
+            AND NOT LIBCXX_STATICALLY_LINK_ABI_IN_SHARED_LIBRARY)
+    target_link_libraries(cxx_shared PRIVATE
+      "-Wl,-force_symbols_not_weak_list,${CMAKE_CURRENT_SOURCE_DIR}/../lib/notweak.exp"
+      "-Wl,-force_symbols_weak_list,${CMAKE_CURRENT_SOURCE_DIR}/../lib/weak.exp")
+  endif()
 
-# Generate a linker script in place of a libc++.so symlink.
-if (LIBCXX_ENABLE_ABI_LINKER_SCRIPT)
-  set(link_libraries)
+  # Generate a linker script in place of a libc++.so symlink.
+  if (LIBCXX_ENABLE_ABI_LINKER_SCRIPT)
+    set(link_libraries)
+
+    set(imported_libname "$<TARGET_PROPERTY:libcxx-abi-shared,IMPORTED_LIBNAME>")
+    set(output_name "$<TARGET_PROPERTY:libcxx-abi-shared,OUTPUT_NAME>")
+    string(APPEND link_libraries "${CMAKE_LINK_LIBRARY_FLAG}$<IF:$<BOOL:${imported_libname}>,${imported_libname},${output_name}>")
+
+    # TODO: Move to the same approach as above for the unwind library
+    if (LIBCXXABI_USE_LLVM_UNWINDER)
+      if (LIBCXXABI_STATICALLY_LINK_UNWINDER_IN_SHARED_LIBRARY)
+        # libunwind is already included in libc++abi
+      elseif (TARGET unwind_shared OR HAVE_LIBUNWIND)
+        string(APPEND link_libraries " ${CMAKE_LINK_LIBRARY_FLAG}$<TARGET_PROPERTY:unwind_shared,OUTPUT_NAME>")
+      else()
+        string(APPEND link_libraries " ${CMAKE_LINK_LIBRARY_FLAG}unwind")
+      endif()
+    endif()
 
-  set(imported_libname "$<TARGET_PROPERTY:libcxx-abi-shared,IMPORTED_LIBNAME>")
-  set(output_name "$<TARGET_PROPERTY:libcxx-abi-shared,OUTPUT_NAME>")
-  string(APPEND link_libraries "${CMAKE_LINK_LIBRARY_FLAG}$<IF:$<BOOL:${imported_libname}>,${imported_libname},${output_name}>")
+    set(linker_script "INPUT($<TARGET_SONAME_FILE_NAME:cxx_shared> ${link_libraries})")
+    add_custom_command(TARGET cxx_shared POST_BUILD
+      COMMAND "${CMAKE_COMMAND}" -E remove "$<TARGET_LINKER_FILE:cxx_shared>"
+      COMMAND "${CMAKE_COMMAND}" -E echo "${linker_script}" > "$<TARGET_LINKER_FILE:cxx_shared>"
+      COMMENT "Generating linker script: '${linker_script}' as file $<TARGET_LINKER_FILE:cxx_shared>"
+      VERBATIM
+    )
+  endif()
 
-  # TODO: Move to the same approach as above for the unwind library
-  if (LIBCXXABI_USE_LLVM_UNWINDER)
-    if (LIBCXXABI_STATICALLY_LINK_UNWINDER_IN_SHARED_LIBRARY)
-      # libunwind is already included in libc++abi
-    elseif (TARGET unwind_shared OR HAVE_LIBUNWIND)
-      string(APPEND link_libraries " ${CMAKE_LINK_LIBRARY_FLAG}$<TARGET_PROPERTY:unwind_shared,OUTPUT_NAME>")
+  if(WIN32 AND NOT MINGW AND NOT "${CMAKE_HOST_SYSTEM_NAME}" STREQUAL "Windows")
+    # Since we most likely do not have a mt.exe replacement, disable the
+    # manifest bundling.  This allows a normal cmake invocation to pass which
+    # will attempt to use the manifest tool to generate the bundled manifest
+    if (${CMAKE_CXX_COMPILER_FRONTEND_VARIANT} STREQUAL "MSVC")
+      set_target_properties(cxx_shared PROPERTIES
+                            APPEND_STRING PROPERTY LINK_FLAGS " /MANIFEST:NO")
     else()
-      string(APPEND link_libraries " ${CMAKE_LINK_LIBRARY_FLAG}unwind")
+      set_target_properties(cxx_shared PROPERTIES
+                            APPEND_STRING PROPERTY LINK_FLAGS " -Xlinker /MANIFEST:NO")
     endif()
   endif()
-
-  set(linker_script "INPUT($<TARGET_SONAME_FILE_NAME:cxx_shared> ${link_libraries})")
-  add_custom_command(TARGET cxx_shared POST_BUILD
-    COMMAND "${CMAKE_COMMAND}" -E remove "$<TARGET_LINKER_FILE:cxx_shared>"
-    COMMAND "${CMAKE_COMMAND}" -E echo "${linker_script}" > "$<TARGET_LINKER_FILE:cxx_shared>"
-    COMMENT "Generating linker script: '${linker_script}' as file $<TARGET_LINKER_FILE:cxx_shared>"
-    VERBATIM
-  )
-endif()
-
-if(WIN32 AND NOT MINGW AND NOT "${CMAKE_HOST_SYSTEM_NAME}" STREQUAL "Windows")
-  # Since we most likely do not have a mt.exe replacement, disable the
-  # manifest bundling.  This allows a normal cmake invocation to pass which
-  # will attempt to use the manifest tool to generate the bundled manifest
-  if (${CMAKE_CXX_COMPILER_FRONTEND_VARIANT} STREQUAL "MSVC")
-    set_target_properties(cxx_shared PROPERTIES
-                          APPEND_STRING PROPERTY LINK_FLAGS " /MANIFEST:NO")
-  else()
-    set_target_properties(cxx_shared PROPERTIES
-                          APPEND_STRING PROPERTY LINK_FLAGS " -Xlinker /MANIFEST:NO")
-  endif()
-endif()
+endif() # LIBCXX_SUPPORTS_SHARED_LIBRARY
 
 set(CMAKE_STATIC_LIBRARY_PREFIX "lib")
 
@@ -324,7 +326,7 @@ endif()
 
 add_library(cxx_experimental STATIC ${LIBCXX_EXPERIMENTAL_SOURCES})
 target_link_libraries(cxx_experimental PUBLIC cxx-headers)
-if (LIBCXX_ENABLE_SHARED)
+if (LIBCXX_ENABLE_SHARED AND TARGET cxx_shared)
   target_link_libraries(cxx_experimental PRIVATE cxx_shared)
 else()
   target_link_libraries(cxx_experimental PRIVATE cxx_static)
@@ -346,14 +348,14 @@ target_compile_options(cxx_experimental PUBLIC -D_LIBCPP_ENABLE_EXPERIMENTAL)
 
 # Add a meta-target for both libraries and the experimental library.
 add_custom_target(cxx DEPENDS cxx_experimental)
-if (LIBCXX_ENABLE_SHARED)
+if (LIBCXX_ENABLE_SHARED AND TARGET cxx_shared)
   add_dependencies(cxx cxx_shared)
 endif()
 if (LIBCXX_ENABLE_STATIC)
   add_dependencies(cxx cxx_static)
 endif()
 
-if (LIBCXX_INSTALL_SHARED_LIBRARY)
+if (LIBCXX_INSTALL_SHARED_LIBRARY AND TARGET cxx_shared)
   install(TARGETS cxx_shared
     ARCHIVE DESTINATION ${LIBCXX_INSTALL_LIBRARY_DIR} COMPONENT cxx
     LIBRARY DESTINATION ${LIBCXX_INSTALL_LIBRARY_DIR} COMPONENT cxx
@@ -376,7 +378,7 @@ endif()
 
 # NOTE: This install command must go after the cxx install command otherwise
 # it will not be executed after the library symlinks are installed.
-if (LIBCXX_ENABLE_SHARED AND LIBCXX_ENABLE_ABI_LINKER_SCRIPT)
+if (LIBCXX_ENABLE_SHARED AND LIBCXX_ENABLE_ABI_LINKER_SCRIPT AND TARGET cxx_shared)
   install(FILES "$<TARGET_LINKER_FILE:cxx_shared>"
     DESTINATION ${LIBCXX_INSTALL_LIBRARY_DIR}
     COMPONENT cxx)
diff --git a/libcxxabi/CMakeLists.txt b/libcxxabi/CMakeLists.txt
index f6ad2e1bf314a..aca448ccf10b0 100644
--- a/libcxxabi/CMakeLists.txt
+++ b/libcxxabi/CMakeLists.txt
@@ -89,21 +89,20 @@ set(LIBCXXABI_LIBDIR_SUFFIX "${LLVM_LIBDIR_SUFFIX}" CACHE STRING
 option(LIBCXXABI_INSTALL_HEADERS "Install the libc++abi headers." ON)
 option(LIBCXXABI_INSTALL_LIBRARY "Install the libc++abi library." ON)
 
-# On platforms that don't support shared library targets (e.g. CMAKE_SYSTEM_NAME
-# of "Generic", used for GPU and other baremetal targets), CMake implicitly
-# changes shared library targets into static library targets. The shared target
-# is always defined even when LIBCXXABI_ENABLE_SHARED is off, so this would
-# result in two targets producing the same "libc++abi.a" output and break the
-# build. Give the shared library a different default output name in that case so
-# it can't collide with the static library.
-# See https://gitlab.kitware.com/cmake/cmake/-/issues/25759.
+# On platforms that don't support shared library targets
+# (e.g. CMAKE_SYSTEM_NAME of "Generic", used for GPU and other
+# baremetal targets), the shared library target is not built at
+# all. The global TARGET_SUPPORTS_SHARED_LIBS property is left
+# undefined on platforms that do support shared libraries, and only
+# set to FALSE on those that don't.  See
+# https://gitlab.kitware.com/cmake/cmake/-/issues/25759.
 get_property(LIBCXXABI_TARGET_SUPPORTS_SHARED_LIBS GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS)
-if(DEFINED LIBCXXABI_TARGET_SUPPORTS_SHARED_LIBS AND NOT LIBCXXABI_TARGET_SUPPORTS_SHARED_LIBS)
-  set(LIBCXXABI_DEFAULT_SHARED_OUTPUT_NAME "c++abi-shared")
+if(NOT DEFINED LIBCXXABI_TARGET_SUPPORTS_SHARED_LIBS OR LIBCXXABI_TARGET_SUPPORTS_SHARED_LIBS)
+  set(LIBCXXABI_SUPPORTS_SHARED_LIBRARY ON)
 else()
-  set(LIBCXXABI_DEFAULT_SHARED_OUTPUT_NAME "c++abi")
+  set(LIBCXXABI_SUPPORTS_SHARED_LIBRARY OFF)
 endif()
-set(LIBCXXABI_SHARED_OUTPUT_NAME "${LIBCXXABI_DEFAULT_SHARED_OUTPUT_NAME}" CACHE STRING "Output name for the shared libc++abi runtime library.")
+set(LIBCXXABI_SHARED_OUTPUT_NAME "c++abi" CACHE STRING "Output name for the shared libc++abi runtime library.")
 set(LIBCXXABI_STATIC_OUTPUT_NAME "c++abi" CACHE STRING "Output name for the static libc++abi runtime library.")
 
 set(LIBCXXABI_INSTALL_INCLUDE_DIR "${CMAKE_INSTALL_INCLUDEDIR}/c++/v1" CACHE STRING "Path to install the libc++abi headers at.")
diff --git a/libcxxabi/src/CMakeLists.txt b/libcxxabi/src/CMakeLists.txt
index 88ae36e8310fd..4e9481e39e49a 100644
--- a/libcxxabi/src/CMakeLists.txt
+++ b/libcxxabi/src/CMakeLists.txt
@@ -161,105 +161,107 @@ endif()
 include(WarningFlags)
 
 # Build the shared library.
-add_library(cxxabi_shared_objects OBJECT EXCLUDE_FROM_ALL ${LIBCXXABI_SOURCES} ${LIBCXXABI_HEADERS})
-cxx_add_warning_flags(cxxabi_shared_objects ${LIBCXXABI_ENABLE_WERROR} ${LIBCXXABI_ENABLE_PEDANTIC})
-if (LIBCXXABI_USE_LLVM_UNWINDER)
-  if (LIBCXXABI_STATICALLY_LINK_UNWINDER_IN_SHARED_LIBRARY OR
-      (DEFINED LIBUNWIND_ENABLE_SHARED AND NOT LIBUNWIND_ENABLE_SHARED))
-    target_link_libraries(cxxabi_shared_objects PUBLIC unwind_shared_objects) # propagate usage requirements
-    target_sources(cxxabi_shared_objects PUBLIC $<TARGET_OBJECTS:unwind_shared_objects>)
-  else()
-    target_link_libraries(cxxabi_shared_objects PUBLIC unwind_shared)
+if (LIBCXXABI_SUPPORTS_SHARED_LIBRARY)
+  add_library(cxxabi_shared_objects OBJECT EXCLUDE_FROM_ALL ${LIBCXXABI_SOURCES} ${LIBCXXABI_HEADERS})
+  cxx_add_warning_flags(cxxabi_shared_objects ${LIBCXXABI_ENABLE_WERROR} ${LIBCXXABI_ENABLE_PEDANTIC})
+  if (LIBCXXABI_USE_LLVM_UNWINDER)
+    if (LIBCXXABI_STATICALLY_LINK_UNWINDER_IN_SHARED_LIBRARY OR
+        (DEFINED LIBUNWIND_ENABLE_SHARED AND NOT LIBUNWIND_ENABLE_SHARED))
+      target_link_libraries(cxxabi_shared_objects PUBLIC unwind_shared_objects) # propagate usage requirements
+      target_sources(cxxabi_shared_objects PUBLIC $<TARGET_OBJECTS:unwind_shared_objects>)
+    else()
+      target_link_libraries(cxxabi_shared_objects PUBLIC unwind_shared)
+    endif()
   endif()
-endif()
-target_link_libraries(cxxabi_shared_objects
-  PUBLIC cxxabi-headers
-  PRIVATE cxx-headers runtimes-libc-headers ${LIBCXXABI_LIBRARIES})
-if (NOT CXX_SUPPORTS_NOSTDLIBXX_FLAG)
-  target_link_libraries(cxxabi_shared_objects PRIVATE ${LIBCXXABI_BUILTINS_LIBRARY})
-endif()
-set_target_properties(cxxabi_shared_objects
-  PROPERTIES
-    CXX_EXTENSIONS OFF
-    CXX_STANDARD 23
-    CXX_STANDARD_REQUIRED OFF # TODO: Make this REQUIRED once we don't need to accommodate the LLVM documentation builders using an ancient CMake
-    COMPILE_FLAGS "${LIBCXXABI_COMPILE_FLAGS}"
-    DEFINE_SYMBOL ""
-)
-if (CMAKE_POSITION_INDEPENDENT_CODE OR NOT DEFINED CMAKE_POSITION_INDEPENDENT_CODE)
-  set_target_properties(cxxabi_shared_objects PROPERTIES POSITION_INDEPENDENT_CODE ON) # must set manually because it's an object library
-endif()
-target_compile_options(cxxabi_shared_objects PRIVATE "${LIBCXXABI_ADDITIONAL_COMPILE_FLAGS}")
-
-# Build with -fsized-deallocation, which is default in recent versions of Clang.
-# TODO(LLVM 21): This can be dropped once we only support Clang >= 19.
-target_add_compile_flags_if_supported(cxxabi_shared_objects PRIVATE -fsized-deallocation)
-
-add_library(cxxabi_shared SHARED)
-set_target_properties(cxxabi_shared
-  PROPERTIES
-    EXCLUDE_FROM_ALL "$<IF:$<BOOL:${LIBCXXABI_ENABLE_SHARED}>,FALSE,TRUE>"
-    LINK_FLAGS "${LIBCXXABI_LINK_FLAGS}"
-    OUTPUT_NAME "${LIBCXXABI_SHARED_OUTPUT_NAME}"
-    SOVERSION "1"
-    VERSION "${LIBCXXABI_LIBRARY_VERSION}"
-)
-
-if (ZOS)
-  add_custom_command(TARGET cxxabi_shared POST_BUILD
-    COMMAND
-      ${LIBCXXABI_LIBCXX_PATH}/utils/zos_rename_dll_side_deck.sh
-      $<TARGET_LINKER_FILE_NAME:cxxabi_shared> $<TARGET_FILE_NAME:cxxabi_shared> "${LIBCXXABI_DLL_NAME}"
-    COMMENT "Rename dll name inside the side deck file"
-    WORKING_DIRECTORY $<TARGET_FILE_DIR:cxxabi_shared>
+  target_link_libraries(cxxabi_shared_objects
+    PUBLIC cxxabi-headers
+    PRIVATE cxx-headers runtimes-libc-headers ${LIBCXXABI_LIBRARIES})
+  if (NOT CXX_SUPPORTS_NOSTDLIBXX_FLAG)
+    target_link_libraries(cxxabi_shared_objects PRIVATE ${LIBCXXABI_BUILTINS_LIBRARY})
+  endif()
+  set_target_properties(cxxabi_shared_objects
+    PROPERTIES
+      CXX_EXTENSIONS OFF
+      CXX_STANDARD 23
+      CXX_STANDARD_REQUIRED OFF # TODO: Make this REQUIRED once we don't need to accommodate the LLVM documentation builders using an ancient CMake
+      COMPILE_FLAGS "${LIBCXXABI_COMPILE_FLAGS}"
+      DEFINE_SYMBOL ""
   )
-endif ()
-
-target_link_libraries(cxxabi_shared
-  PUBLIC cxxabi_shared_objects runtimes-libc-shared
-  PRIVATE ${LIBCXXABI_LIBRARIES})
-
-# TODO: Move this to libc++'s HandleLibCXXABI.cmake since this is effectively trying to control
-#       what libc++ re-exports.
-add_library(cxxabi-reexports INTERFACE)
-function(export_symbols file)
-  # -exported_symbols_list is only available on Apple platforms
-  if (APPLE)
-    target_link_libraries(cxxabi_shared PRIVATE "-Wl,-exported_symbols_list,${file}")
+  if (CMAKE_POSITION_INDEPENDENT_CODE OR NOT DEFINED CMAKE_POSITION_INDEPENDENT_CODE)
+    set_target_properties(cxxabi_shared_objects PROPERTIES POSITION_INDEPENDENT_CODE ON) # must set manually because it's an object library
   endif()
-endfunction()
+  target_compile_options(cxxabi_shared_objects PRIVATE "${LIBCXXABI_ADDITIONAL_COMPILE_FLAGS}")
+
+  # Build with -fsized-deallocation, which is default in recent versions of Clang.
+  # TODO(LLVM 21): This can be dropped once we only support Clang >= 19.
+  target_add_compile_flags_if_supported(cxxabi_shared_objects PRIVATE -fsized-deallocation)
+
+  add_library(cxxabi_shared SHARED)
+  set_target_properties(cxxabi_shared
+    PROPERTIES
+      EXCLUDE_FROM_ALL "$<IF:$<BOOL:${LIBCXXABI_ENABLE_SHARED}>,FALSE,TRUE>"
+      LINK_FLAGS "${LIBCXXABI_LINK_FLAGS}"
+      OUTPUT_NAME "${LIBCXXABI_SHARED_OUTPUT_NAME}"
+      SOVERSION "1"
+      VERSION "${LIBCXXABI_LIBRARY_VERSION}"
+  )
 
-function(reexport_symbols file)
-  export_symbols("${file}")
-  # -reexported_symbols_list is only available on Apple platforms
-  if (APPLE)
-    target_link_libraries(cxxabi-reexports INTERFACE "-Wl,-reexported_symbols_list,${file}")
-  endif()
-endfunction()
+  if (ZOS)
+    add_custom_command(TARGET cxxabi_shared POST_BUILD
+      COMMAND
+        ${LIBCXXABI_LIBCXX_PATH}/utils/zos_rename_dll_side_deck.sh
+        $<TARGET_LINKER_FILE_NAME:cxxabi_shared> $<TARGET_FILE_NAME:cxxabi_shared> "${LIBCXXABI_DLL_NAME}"
+      COMMENT "Rename dll name inside the side deck file"
+      WORKING_DIRECTORY $<TARGET_FILE_DIR:cxxabi_shared>
+    )
+  endif ()
+
+  target_link_libraries(cxxabi_shared
+    PUBLIC cxxabi_shared_objects runtimes-libc-shared
+    PRIVATE ${LIBCXXABI_LIBRARIES})
+
+  # TODO: Move this to libc++'s HandleLibCXXABI.cmake since this is effectively trying to control
+  #       what libc++ re-exports.
+  add_library(cxxabi-reexports INTERFACE)
+  function(export_symbols file)
+    # -exported_symbols_list is only available on Apple platforms
+    if (APPLE)
+      target_link_libraries(cxxabi_shared PRIVATE "-Wl,-exported_symbols_list,${file}")
+    endif()
+  endfunction()
 
-export_symbols("${CMAKE_CURRENT_SOURCE_DIR}/../lib/symbols-not-reexported.exp")
-reexport_symbols("${CMAKE_CURRENT_SOURCE_DIR}/../lib/cxxabiv1.exp")
-reexport_symbols("${CMAKE_CURRENT_SOURCE_DIR}/../lib/fundamental-types.exp")
-reexport_symbols("${CMAKE_CURRENT_SOURCE_DIR}/../lib/itanium-base.exp")
-reexport_symbols("${CMAKE_CURRENT_SOURCE_DIR}/../lib/std-misc.exp")
+  function(reexport_symbols file)
+    export_symbols("${file}")
+    # -reexported_symbols_list is only available on Apple platforms
+    if (APPLE)
+      target_link_libraries(cxxabi-reexports INTERFACE "-Wl,-reexported_symbols_list,${file}")
+    endif()
+  endfunction()
 
-if (LIBCXXABI_ENABLE_NEW_DELETE_DEFINITIONS)
-  reexport_symbols("${CMAKE_CURRENT_SOURCE_DIR}/../lib/new-delete.exp")
-endif()
+  export_symbols("${CMAKE_CURRENT_SOURCE_DIR}/../lib/symbols-not-reexported.exp")
+  reexport_symbols("${CMAKE_CURRENT_SOURCE_DIR}/../lib/cxxabiv1.exp")
+  reexport_symbols("${CMAKE_CURRENT_SOURCE_DIR}/../lib/fundamental-types.exp")
+  reexport_symbols("${CMAKE_CURRENT_SOURCE_DIR}/../lib/itanium-base.exp")
+  reexport_symbols("${CMAKE_CURRENT_SOURCE_DIR}/../lib/std-misc.exp")
 
-# Note that std:: exception types are always defined by the library regardless of
-# whether the exception runtime machinery is provided.
-reexport_symbols("${CMAKE_CURRENT_SOURCE_DIR}/../lib/std-exceptions.exp")
+  if (LIBCXXABI_ENABLE_NEW_DELETE_DEFINITIONS)
+    reexport_symbols("${CMAKE_CURRENT_SOURCE_DIR}/../lib/new-delete.exp")
+  endif()
 
-if (LIBCXXABI_ENABLE_EXCEPTIONS)
-  reexport_symbols("${CMAKE_CURRENT_SOURCE_DIR}/../lib/itanium-exceptions.exp")
+  # Note that std:: exception types are always defined by the library regardless of
+  # whether the exception runtime machinery is provided.
+  reexport_symbols("${CMAKE_CURRENT_SOURCE_DIR}/../lib/std-exceptions.exp")
 
-  if ("${CMAKE_OSX_ARCHITECTURES}" MATCHES "^(armv6|armv7|armv7s)$")
-    reexport_symbols("${CMAKE_CURRENT_SOURCE_DIR}/../lib/personality-sjlj.exp")
-  else()
-    reexport_symbols("${CMAKE_CURRENT_SOURCE_DIR}/../lib/personality-v0.exp")
+  if (LIBCXXABI_ENABLE_EXCEPTIONS)
+    reexport_symbols("${CMAKE_CURRENT_SOURCE_DIR}/../lib/itanium-exceptions.exp")
+
+    if ("${CMAKE_OSX_ARCHITECTURES}" MATCHES "^(armv6|armv7|armv7s)$")
+      reexport_symbols("${CMAKE_CURRENT_SOURCE_DIR}/../lib/personality-sjlj.exp")
+    else()
+      reexport_symbols("${CMAKE_CURRENT_SOURCE_DIR}/../lib/personality-v0.exp")
+    endif()
   endif()
-endif()
+endif() # LIBCXXABI_SUPPORTS_SHARED_LIBRARY
 
 # Build the static library.
 add_library(cxxabi_static_objects OBJECT EXCLUDE_FROM_ALL ${LIBCXXABI_SOURCES} ${LIBCXXABI_HEADERS})
@@ -320,14 +322,14 @@ target_link_libraries(cxxabi_static
 
 # Add a meta-target for both libraries.
 add_custom_target(cxxabi)
-if (LIBCXXABI_ENABLE_SHARED)
+if (LIBCXXABI_ENABLE_SHARED AND TARGET cxxabi_shared)
   add_dependencies(cxxabi cxxabi_shared)
 endif()
 if (LIBCXXABI_ENABLE_STATIC)
   add_dependencies(cxxabi cxxabi_static)
 endif()
 
-if (LIBCXXABI_INSTALL_SHARED_LIBRARY)
+if (LIBCXXABI_INSTALL_SHARED_LIBRARY AND TARGET cxxabi_shared)
   install(TARGETS cxxabi_shared
     ARCHIVE DESTINATION ${LIBCXXABI_INSTALL_LIBRARY_DIR} COMPONENT cxxabi
     LIBRARY DESTINATION ${LIBCXXABI_INSTALL_LIBRARY_DIR} COMPONENT cxxabi
diff --git a/libunwind/CMakeLists.txt b/libunwind/CMakeLists.txt
index 65dabf605f252..9606b072be0ca 100644
--- a/libunwind/CMakeLists.txt
+++ b/libunwind/CMakeLists.txt
@@ -137,21 +137,20 @@ set(LIBUNWIND_INSTALL_INCLUDE_DIR "${CMAKE_INSTALL_INCLUDEDIR}" CACHE STRING
 set(LIBUNWIND_INSTALL_RUNTIME_DIR "${CMAKE_INSTALL_BINDIR}" CACHE STRING
     "Path where built libunwind runtime libraries should be installed.")
 
-# On platforms that don't support shared library targets (e.g. CMAKE_SYSTEM_NAME
-# of "Generic", used for GPU and other baremetal targets), CMake implicitly
-# changes shared library targets into static library targets. The shared target
-# is always defined even when LIBUNWIND_ENABLE_SHARED is off, so this would
-# result in two targets producing the same "libunwind.a" output and break the
-# build. Give the shared library a different default output name in that case so
-# it can't collide with the static library.
-# See https://gitlab.kitware.com/cmake/cmake/-/issues/25759.
+# On platforms that don't support shared library targets
+# (e.g. CMAKE_SYSTEM_NAME of "Generic", used for GPU and other
+# baremetal targets), the shared library target is not built at
+# all. The global TARGET_SUPPORTS_SHARED_LIBS property is left
+# undefined on platforms that do support shared libraries, and only
+# set to FALSE on those that don't.  See
+# https://gitlab.kitware.com/cmake/cmake/-/issues/25759.
 get_property(LIBUNWIND_TARGET_SUPPORTS_SHARED_LIBS GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS)
-if(DEFINED LIBUNWIND_TARGET_SUPPORTS_SHARED_LIBS AND NOT LIBUNWIND_TARGET_SUPPORTS_SHARED_LIBS)
-  set(LIBUNWIND_DEFAULT_SHARED_OUTPUT_NAME "unwind-shared")
+if(NOT DEFINED LIBUNWIND_TARGET_SUPPORTS_SHARED_LIBS OR LIBUNWIND_TARGET_SUPPORTS_SHARED_LIBS)
+  set(LIBUNWIND_SUPPORTS_SHARED_LIBRARY ON)
 else()
-  set(LIBUNWIND_DEFAULT_SHARED_OUTPUT_NAME "unwind")
+  set(LIBUNWIND_SUPPORTS_SHARED_LIBRARY OFF)
 endif()
-set(LIBUNWIND_SHARED_OUTPUT_NAME "${LIBUNWIND_DEFAULT_SHARED_OUTPUT_NAME}" CACHE STRING "Output name for the shared libunwind runtime library.")
+set(LIBUNWIND_SHARED_OUTPUT_NAME "unwind" CACHE STRING "Output name for the shared libunwind runtime library.")
 set(LIBUNWIND_STATIC_OUTPUT_NAME "unwind" CACHE STRING "Output name for the static libunwind runtime library.")
 
 # TODO: Use common runtimes infrastructure for output and install paths
diff --git a/libunwind/src/CMakeLists.txt b/libunwind/src/CMakeLists.txt
index 6e947039fb0d5..8c3e15bfff0ba 100644
--- a/libunwind/src/CMakeLists.txt
+++ b/libunwind/src/CMakeLists.txt
@@ -89,7 +89,7 @@ add_link_flags_if(CXX_SUPPORTS_UNWINDLIB_EQ_NONE_FLAG --unwindlib=none)
 # MINGW_LIBRARIES is defined in config-ix.cmake
 add_library_flags_if(MINGW "${MINGW_LIBRARIES}")
 
-if (LIBUNWIND_ENABLE_SHARED AND
+if (LIBUNWIND_ENABLE_SHARED AND LIBUNWIND_SUPPORTS_SHARED_LIBRARY AND
     NOT (CXX_SUPPORTS_FNO_EXCEPTIONS_FLAG AND
          CXX_SUPPORTS_FUNWIND_TABLES_FLAG))
   message(FATAL_ERROR
@@ -125,39 +125,41 @@ set(CMAKE_CXX_IMPLICIT_LINK_LIBRARIES "")
 include(WarningFlags)
 
 # Build the shared library.
-add_library(unwind_shared_objects OBJECT EXCLUDE_FROM_ALL ${LIBUNWIND_SOURCES} ${LIBUNWIND_HEADERS})
-cxx_add_warning_flags(unwind_shared_objects ${LIBUNWIND_ENABLE_WERROR} ${LIBUNWIND_ENABLE_PEDANTIC})
-if(CMAKE_C_COMPILER_ID STREQUAL MSVC)
-  target_compile_options(unwind_shared_objects PRIVATE /GR-)
-else()
-  target_compile_options(unwind_shared_objects PRIVATE -fno-rtti)
-endif()
-target_compile_options(unwind_shared_objects PUBLIC "${LIBUNWIND_ADDITIONAL_COMPILE_FLAGS}")
-target_link_libraries(unwind_shared_objects
-  PUBLIC "${LIBUNWIND_ADDITIONAL_LIBRARIES}"
-  PRIVATE unwind-headers runtimes-libc-headers ${LIBUNWIND_LIBRARIES})
-set_target_properties(unwind_shared_objects
-  PROPERTIES
-    CXX_EXTENSIONS OFF
-    CXX_STANDARD 17
-    CXX_STANDARD_REQUIRED ON
-    COMPILE_FLAGS "${LIBUNWIND_COMPILE_FLAGS}"
-)
-if (CMAKE_POSITION_INDEPENDENT_CODE OR NOT DEFINED CMAKE_POSITION_INDEPENDENT_CODE)
-  set_target_properties(unwind_shared_objects PROPERTIES POSITION_INDEPENDENT_CODE ON) # must set manually because it's an object library
-endif()
+if (LIBUNWIND_SUPPORTS_SHARED_LIBRARY)
+  add_library(unwind_shared_objects OBJECT EXCLUDE_FROM_ALL ${LIBUNWIND_SOURCES} ${LIBUNWIND_HEADERS})
+  cxx_add_warning_flags(unwind_shared_objects ${LIBUNWIND_ENABLE_WERROR} ${LIBUNWIND_ENABLE_PEDANTIC})
+  if(CMAKE_C_COMPILER_ID STREQUAL MSVC)
+    target_compile_options(unwind_shared_objects PRIVATE /GR-)
+  else()
+    target_compile_options(unwind_shared_objects PRIVATE -fno-rtti)
+  endif()
+  target_compile_options(unwind_shared_objects PUBLIC "${LIBUNWIND_ADDITIONAL_COMPILE_FLAGS}")
+  target_link_libraries(unwind_shared_objects
+    PUBLIC "${LIBUNWIND_ADDITIONAL_LIBRARIES}"
+    PRIVATE unwind-headers runtimes-libc-headers ${LIBUNWIND_LIBRARIES})
+  set_target_properties(unwind_shared_objects
+    PROPERTIES
+      CXX_EXTENSIONS OFF
+      CXX_STANDARD 17
+      CXX_STANDARD_REQUIRED ON
+      COMPILE_FLAGS "${LIBUNWIND_COMPILE_FLAGS}"
+  )
+  if (CMAKE_POSITION_INDEPENDENT_CODE OR NOT DEFINED CMAKE_POSITION_INDEPENDENT_CODE)
+    set_target_properties(unwind_shared_objects PROPERTIES POSITION_INDEPENDENT_CODE ON) # must set manually because it's an object library
+  endif()
 
-add_library(unwind_shared SHARED)
-target_link_libraries(unwind_shared PUBLIC unwind_shared_objects runtimes-libc-shared)
-set_target_properties(unwind_shared
-  PROPERTIES
-    EXCLUDE_FROM_ALL "$<IF:$<BOOL:${LIBUNWIND_ENABLE_SHARED}>,FALSE,TRUE>"
-    LINK_FLAGS "${LIBUNWIND_LINK_FLAGS}"
-    LINKER_LANGUAGE C
-    OUTPUT_NAME "${LIBUNWIND_SHARED_OUTPUT_NAME}"
-    VERSION     "${LIBUNWIND_LIBRARY_VERSION}"
-    SOVERSION   "1"
-)
+  add_library(unwind_shared SHARED)
+  target_link_libraries(unwind_shared PUBLIC unwind_shared_objects runtimes-libc-shared)
+  set_target_properties(unwind_shared
+    PROPERTIES
+      EXCLUDE_FROM_ALL "$<IF:$<BOOL:${LIBUNWIND_ENABLE_SHARED}>,FALSE,TRUE>"
+      LINK_FLAGS "${LIBUNWIND_LINK_FLAGS}"
+      LINKER_LANGUAGE C
+      OUTPUT_NAME "${LIBUNWIND_SHARED_OUTPUT_NAME}"
+      VERSION     "${LIBUNWIND_LIBRARY_VERSION}"
+      SOVERSION   "1"
+  )
+endif() # LIBUNWIND_SUPPORTS_SHARED_LIBRARY
 
 # Build the static library.
 add_library(unwind_static_objects OBJECT EXCLUDE_FROM_ALL ${LIBUNWIND_SOURCES} ${LIBUNWIND_HEADERS})
@@ -200,14 +202,14 @@ set_target_properties(unwind_static
 
 # Add a meta-target for both libraries.
 add_custom_target(unwind)
-if (LIBUNWIND_ENABLE_SHARED)
+if (LIBUNWIND_ENABLE_SHARED AND TARGET unwind_shared)
   add_dependencies(unwind unwind_shared)
 endif()
 if (LIBUNWIND_ENABLE_STATIC)
   add_dependencies(unwind unwind_static)
 endif()
 
-if (LIBUNWIND_INSTALL_SHARED_LIBRARY)
+if (LIBUNWIND_INSTALL_SHARED_LIBRARY AND TARGET unwind_shared)
   install(TARGETS unwind_shared
     ARCHIVE DESTINATION ${LIBUNWIND_INSTALL_LIBRARY_DIR} COMPONENT unwind
     LIBRARY DESTINATION ${LIBUNWIND_INSTALL_LIBRARY_DIR} COMPONENT unwind



More information about the llvm-branch-commits mailing list