Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions clang/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
9 changes: 9 additions & 0 deletions clang/tools/libclang/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Copy link
Copy Markdown
Collaborator

@cachemeifyoucan cachemeifyoucan Mar 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

libclang and libLTO has stable ABI.

It is a requirement on macOS and in our toolchain that we have to link across major version boundaries.

I don't really mind the version number on llvm dylibs from BUILD_SHARED_LIBS=YES but libLTO and libclang cannot be versioned.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this PR preserves that. MACHO_COMPATIBILITY_VERSION and MACHO_CURRENT_VERSION take precedence over VERSION.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there is still a version number on the dylib right here right? It is just not equal to llvm version.

macOS toolchain has always been shipping with no version and new toolchain cannot have a version on it, otherwise, it will break compatibility with old tools. Let me know if I misunderstood the code.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there is still a version number on the dylib right here right? It is just not equal to llvm version.

macOS toolchain has always been shipping with no version and new toolchain cannot have a version on it, otherwise, it will break compatibility with old tools. Let me know if I misunderstood the code.

I think this is not correct; even before this PR libclang and libLTO had explicit version numbers, they were just doing it manually using -compatibility_version and -current_version. The second commit in this PR kept that behavior but changed the implementation to use MACHO_COMPATIBILITY_VERSION and MACHO_CURRENT_VERSION.

Copy link
Copy Markdown
Member Author

@tamird tamird Mar 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is a requirement on macOS and in our toolchain that we have to link across major version boundaries.

Can you help me understand why this is a requirement specifically on macOS? In particular, what behavior or distribution model depends on libclang/libLTO keeping an unversioned dylib identity on macOS only?

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
Expand Down
24 changes: 24 additions & 0 deletions llvm/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's default to NO.

Apple linker is pretty much the only user of libLTO on macOS and it requires unversioned since it has to load libLTO from all versions of LLVM in our internal build system. Loading a single or limited range of version of libLTO is not an option for us.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you want ON since this is making libLTO unversioned?

# 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}")
Expand Down
2 changes: 1 addition & 1 deletion llvm/cmake/modules/AddLLVM.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down
3 changes: 3 additions & 0 deletions llvm/cmake/modules/LLVMConfig.cmake.in
Original file line number Diff line number Diff line change
Expand Up @@ -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@)

Expand Down
15 changes: 15 additions & 0 deletions llvm/docs/CMake.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
9 changes: 9 additions & 0 deletions llvm/tools/lto/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading