https://github.com/arsenm created https://github.com/llvm/llvm-project/pull/205517
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. The bodies of the newly-conditional blocks are left at their original indentation to keep this diff minimal. A follow-up commit will fix the indentation. This was mostly AI generated with some comment fixups. Co-authored-by: Claude (Opus 4.8) <[email protected]> >From 21a98c3264d9926ecf15c25ef51646bfd73243ba Mon Sep 17 00:00:00 2001 From: Matt Arsenault <[email protected]> Date: Wed, 24 Jun 2026 10:36:01 +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. The bodies of the newly-conditional blocks are left at their original indentation to keep this diff minimal. A follow-up commit will fix the indentation. This was mostly AI generated with some comment fixups. Co-authored-by: Claude (Opus 4.8) <[email protected]> --- cmake/Modules/CMakePolicy.cmake | 6 ++++++ libcxx/CMakeLists.txt | 13 +++++++++++++ libcxx/src/CMakeLists.txt | 10 ++++++---- libcxxabi/CMakeLists.txt | 13 +++++++++++++ libcxxabi/src/CMakeLists.txt | 6 ++++-- libunwind/CMakeLists.txt | 13 +++++++++++++ libunwind/src/CMakeLists.txt | 8 +++++--- 7 files changed, 60 insertions(+), 9 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 845240d1b894c..e58191ccae592 100644 --- a/libcxx/CMakeLists.txt +++ b/libcxx/CMakeLists.txt @@ -445,6 +445,19 @@ 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), 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(NOT DEFINED LIBCXX_TARGET_SUPPORTS_SHARED_LIBS OR LIBCXX_TARGET_SUPPORTS_SHARED_LIBS) + set(LIBCXX_SUPPORTS_SHARED_LIBRARY ON) +else() + set(LIBCXX_SUPPORTS_SHARED_LIBRARY OFF) +endif() 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.") diff --git a/libcxx/src/CMakeLists.txt b/libcxx/src/CMakeLists.txt index de7817ad69f26..6af0a235ac718 100644 --- a/libcxx/src/CMakeLists.txt +++ b/libcxx/src/CMakeLists.txt @@ -172,6 +172,7 @@ split_list(LIBCXX_LINK_FLAGS) include(FindLibcCommonUtils) # Build the shared library. +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 @@ -255,6 +256,7 @@ if(WIN32 AND NOT MINGW AND NOT "${CMAKE_HOST_SYSTEM_NAME}" STREQUAL "Windows") 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 e1a1587fb6283..aca448ccf10b0 100644 --- a/libcxxabi/CMakeLists.txt +++ b/libcxxabi/CMakeLists.txt @@ -89,6 +89,19 @@ 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), 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(NOT DEFINED LIBCXXABI_TARGET_SUPPORTS_SHARED_LIBS OR LIBCXXABI_TARGET_SUPPORTS_SHARED_LIBS) + set(LIBCXXABI_SUPPORTS_SHARED_LIBRARY ON) +else() + set(LIBCXXABI_SUPPORTS_SHARED_LIBRARY OFF) +endif() 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.") diff --git a/libcxxabi/src/CMakeLists.txt b/libcxxabi/src/CMakeLists.txt index 88ae36e8310fd..c6652a831a4ad 100644 --- a/libcxxabi/src/CMakeLists.txt +++ b/libcxxabi/src/CMakeLists.txt @@ -161,6 +161,7 @@ endif() include(WarningFlags) # Build the shared library. +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) @@ -260,6 +261,7 @@ if (LIBCXXABI_ENABLE_EXCEPTIONS) reexport_symbols("${CMAKE_CURRENT_SOURCE_DIR}/../lib/personality-v0.exp") 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 02132f6c07fcd..9606b072be0ca 100644 --- a/libunwind/CMakeLists.txt +++ b/libunwind/CMakeLists.txt @@ -137,6 +137,19 @@ 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), 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(NOT DEFINED LIBUNWIND_TARGET_SUPPORTS_SHARED_LIBS OR LIBUNWIND_TARGET_SUPPORTS_SHARED_LIBS) + set(LIBUNWIND_SUPPORTS_SHARED_LIBRARY ON) +else() + set(LIBUNWIND_SUPPORTS_SHARED_LIBRARY OFF) +endif() 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.") diff --git a/libunwind/src/CMakeLists.txt b/libunwind/src/CMakeLists.txt index 6e947039fb0d5..57e780afb90b2 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,6 +125,7 @@ set(CMAKE_CXX_IMPLICIT_LINK_LIBRARIES "") include(WarningFlags) # Build the shared library. +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) @@ -158,6 +159,7 @@ set_target_properties(unwind_shared 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 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
