diff --git a/clang/CMakeLists.txt b/clang/CMakeLists.txt index b3bc56209fc9e..40506fc8a1546 100644 --- a/clang/CMakeLists.txt +++ b/clang/CMakeLists.txt @@ -724,6 +724,9 @@ if (CLANG_ENABLE_BOOTSTRAP) LLVM_VERSION_MAJOR LLVM_VERSION_MINOR LLVM_VERSION_PATCH + LLVM_VERSIONED_DYLIB_NAME_ON_DARWIN + LLVM_UNVERSIONED_LIBCLANG_ON_DARWIN + LLVM_UNVERSIONED_LIBLTO_ON_DARWIN CLANG_VERSION_MAJOR CLANG_VERSION_MINOR CLANG_VERSION_PATCHLEVEL diff --git a/clang/tools/libclang/CMakeLists.txt b/clang/tools/libclang/CMakeLists.txt index 9b7ee51bb0c24..5fdfc474332f7 100644 --- a/clang/tools/libclang/CMakeLists.txt +++ b/clang/tools/libclang/CMakeLists.txt @@ -170,6 +170,15 @@ if(ENABLE_SHARED) # implicitly be exported from libclang. target_compile_definitions(libclang PRIVATE CLANG_BUILD_STATIC) elseif(APPLE) + if(LLVM_VERSIONED_DYLIB_NAME_ON_DARWIN) + set_target_properties(libclang PROPERTIES + VERSION ${LIBCLANG_LIBRARY_VERSION} + ${LIBCLANG_SOVERSION_ARG}) + if(LLVM_UNVERSIONED_LIBCLANG_ON_DARWIN) + set_property(TARGET libclang PROPERTY SOVERSION) + set_property(TARGET libclang PROPERTY VERSION) + endif() + endif() llvm_set_macho_current_version(libclang ${LLVM_VERSION_MAJOR}) else() set_target_properties(libclang diff --git a/llvm/CMakeLists.txt b/llvm/CMakeLists.txt index 359d1591925b1..da012596cca93 100644 --- a/llvm/CMakeLists.txt +++ b/llvm/CMakeLists.txt @@ -16,6 +16,30 @@ if(NOT LLVM_NO_INSTALL_NAME_DIR_FOR_BUILD_TREE) set(CMAKE_BUILD_WITH_INSTALL_NAME_DIR ON) endif() +# Darwin used to keep libLLVM's install name unversioned even when +# LLVM_VERSION_SUFFIX was set. That makes distinct LLVM builds look +# interchangeable to Mach-O consumers. Keep an opt-out for downstream users +# that still depend on the legacy install name. +option(LLVM_VERSIONED_DYLIB_NAME_ON_DARWIN "If set, use versioned dylib names and install names on Darwin like other Unix platforms" ON) +mark_as_advanced(LLVM_VERSIONED_DYLIB_NAME_ON_DARWIN) +# At the time of writing (2026-04-01), +# https://github.com/llvm/llvm-project/pull/189004#issuecomment-4171272082 +# claims that Xcode uses libclang for indexing and can load additional +# toolchains, so keeping libclang.dylib unversioned avoids breaking that +# compatibility by default. If this ever changes, audit Darwin libclang users +# first and verify that Xcode and downstream toolchains accept a versioned +# libclang install name before changing this default. +option(LLVM_UNVERSIONED_LIBCLANG_ON_DARWIN "If set, keep libclang's Darwin dylib identity unversioned when Darwin versioned dylib names are enabled" ON) +mark_as_advanced(LLVM_UNVERSIONED_LIBCLANG_ON_DARWIN) +# At the time of writing (2026-04-01), +# https://github.com/llvm/llvm-project/pull/189004#issuecomment-4165730721 +# claims that the macOS linker requires libLTO.dylib to keep that stable name +# for LTO builds. If this ever changes, audit Darwin LTO users first and +# verify that ld64 and downstream toolchains accept a versioned libLTO install +# name before changing this default. +option(LLVM_UNVERSIONED_LIBLTO_ON_DARWIN "If set, keep libLTO's Darwin dylib identity unversioned when Darwin versioned dylib names are enabled" ON) +mark_as_advanced(LLVM_UNVERSIONED_LIBLTO_ON_DARWIN) + include(${LLVM_COMMON_CMAKE_UTILS}/Modules/LLVMVersion.cmake) set_directory_properties(PROPERTIES LLVM_VERSION_MAJOR "${LLVM_VERSION_MAJOR}") diff --git a/llvm/cmake/modules/AddLLVM.cmake b/llvm/cmake/modules/AddLLVM.cmake index 7b2424bf67e7d..0730ba2f529ed 100644 --- a/llvm/cmake/modules/AddLLVM.cmake +++ b/llvm/cmake/modules/AddLLVM.cmake @@ -803,7 +803,7 @@ function(llvm_add_library name) ) endif() - if(NOT APPLE) + if(NOT APPLE OR LLVM_VERSIONED_DYLIB_NAME_ON_DARWIN) if(ARG_SONAME) get_target_property(output_name ${name} OUTPUT_NAME) if(${output_name} STREQUAL "output_name-NOTFOUND") diff --git a/llvm/cmake/modules/LLVMConfig.cmake.in b/llvm/cmake/modules/LLVMConfig.cmake.in index 0a7ae97bd7549..23933e882ecec 100644 --- a/llvm/cmake/modules/LLVMConfig.cmake.in +++ b/llvm/cmake/modules/LLVMConfig.cmake.in @@ -17,6 +17,9 @@ set(LLVM_BUILD_TYPE @CMAKE_BUILD_TYPE@) set(CMAKE_MSVC_RUNTIME_LIBRARY @CMAKE_MSVC_RUNTIME_LIBRARY@) set(LLVM_USE_SPLIT_DWARF @LLVM_USE_SPLIT_DWARF@) +set(LLVM_VERSIONED_DYLIB_NAME_ON_DARWIN @LLVM_VERSIONED_DYLIB_NAME_ON_DARWIN@) +set(LLVM_UNVERSIONED_LIBCLANG_ON_DARWIN @LLVM_UNVERSIONED_LIBCLANG_ON_DARWIN@) +set(LLVM_UNVERSIONED_LIBLTO_ON_DARWIN @LLVM_UNVERSIONED_LIBLTO_ON_DARWIN@) set(LLVM_COMMON_DEPENDS @LLVM_COMMON_DEPENDS@) diff --git a/llvm/docs/CMake.rst b/llvm/docs/CMake.rst index 6a70a82a6e438..7a73dd7f1e0f4 100644 --- a/llvm/docs/CMake.rst +++ b/llvm/docs/CMake.rst @@ -808,6 +808,21 @@ its enabled sub-projects. Nearly all of these variable names begin with library ID control variables (e.g., ``CMAKE_INSTALL_NAME_DIR``) are being set to non-standard values. +**LLVM_VERSIONED_DYLIB_NAME_ON_DARWIN**:BOOL + Defaults to ``ON``. If set to ``ON``, Darwin shared libraries built through + LLVM's CMake helpers use versioned dylib filenames and install names, matching + the behavior on other Unix platforms more closely. If set to ``OFF``, Darwin + keeps the legacy unversioned dylib install name, for compatibility with + existing consumers that expect ``@rpath/libLLVM.dylib``. + +**LLVM_UNVERSIONED_{LIBLTO,LIBCLANG}_ON_DARWIN**:BOOL + Default to ``ON``. When ``LLVM_VERSIONED_DYLIB_NAME_ON_DARWIN`` is ``ON``, + these keep ``libLTO`` and ``libclang``'s Darwin dylib identities + unversioned. Set ``LLVM_UNVERSIONED_LIBLTO_ON_DARWIN`` to ``OFF`` to + version ``libLTO`` using its Darwin ``LTO_VERSION`` policy instead. Set + ``LLVM_UNVERSIONED_LIBCLANG_ON_DARWIN`` to ``OFF`` to version + ``libclang`` using its existing ABI version policy instead. + **LLVM_OPTIMIZED_TABLEGEN**:BOOL If enabled and building a debug or assert build, the CMake build system will generate a Release build tree to build a fully optimized tablegen for use diff --git a/llvm/tools/lto/CMakeLists.txt b/llvm/tools/lto/CMakeLists.txt index 6be458dca7aac..5d13bf5e1e80d 100644 --- a/llvm/tools/lto/CMakeLists.txt +++ b/llvm/tools/lto/CMakeLists.txt @@ -45,6 +45,15 @@ if(LLVM_ENABLE_PIC) if(LLVM_LTO_VERSION_OFFSET) math(EXPR LTO_VERSION "${LLVM_VERSION_MAJOR} + ${LLVM_LTO_VERSION_OFFSET}") endif() + if(LLVM_VERSIONED_DYLIB_NAME_ON_DARWIN) + set_target_properties(LTO PROPERTIES + SOVERSION ${LTO_VERSION}.${LLVM_VERSION_MINOR}${LLVM_VERSION_SUFFIX} + VERSION ${LTO_VERSION}.${LLVM_VERSION_MINOR}${LLVM_VERSION_SUFFIX}) + if(LLVM_UNVERSIONED_LIBLTO_ON_DARWIN) + set_property(TARGET LTO PROPERTY SOVERSION) + set_property(TARGET LTO PROPERTY VERSION) + endif() + endif() llvm_set_macho_current_version(LTO ${LTO_VERSION}) if(LLVM_USE_SANITIZER) execute_process(COMMAND ${CMAKE_CXX_COMPILER} -print-file-name=lib