https://github.com/kikairoya updated https://github.com/llvm/llvm-project/pull/147132
>From 9198e98e6dd7a02c5c5b65e400d788b6bac3a3c3 Mon Sep 17 00:00:00 2001 From: kikairoya <kikair...@gmail.com> Date: Sat, 28 Jun 2025 13:11:42 +0900 Subject: [PATCH 1/3] [libclang][Cygwin] Put unversioned DLL file aside of versioned DLL file On Cygwin, a shared library target generates a versioned DLL file like "cyg${OUTPUT_NAME}-${VERSION}.dll" and an import library "lib${OUTPUT_NAME}.dll.a", but it does *not* generate the expected unversioned symlink "cyg${OUTPUT_NAME}.dll" as is typical on other Unix-like platforms. However, `dlopen()` calls typically use the unversioned form (e.g. "cygclang.dll"), and this is consistent with usage on other platforms. In particular, `clang-python` relies on this behavior. Although the Cygwin runtime can resolve other forms like "libclang.so" or "libclang.dll", a symlink alone won't suffice here, as `dlopen()` ultimately calls `LoadLibraryExW`, which does not follow Cygwin-style symlinks. Therefore, this patch installs an unversioned copy of the DLL without the version suffix to improve compatibility with `dlopen()` and tools like `clang-python`. --- clang/tools/libclang/CMakeLists.txt | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/clang/tools/libclang/CMakeLists.txt b/clang/tools/libclang/CMakeLists.txt index ac7a9a8db37c0..9c5ca26aab099 100644 --- a/clang/tools/libclang/CMakeLists.txt +++ b/clang/tools/libclang/CMakeLists.txt @@ -157,15 +157,28 @@ if(ENABLE_STATIC) endif() if(ENABLE_SHARED) - if(WIN32) + if(WIN32 OR CYGWIN) set_target_properties(libclang PROPERTIES VERSION ${LIBCLANG_LIBRARY_VERSION} DEFINE_SYMBOL _CINDEX_LIB_) - # Avoid declaring clang c++ symbols that are statically linked into libclang as dllimport'ed. - # If llvm/libclang-cpp dll is also being built for windows clang c++ symbols will still be - # implicitly be exported from libclang. - target_compile_definitions(libclang PRIVATE CLANG_BUILD_STATIC) + if (CYGWIN) + # On Cygwin environment, a library target generates "cyg${OUTPUT_NAME}-${VERSION}.dll" and "lib${OUTPUT_NAME}.dll.a" but + # don't provide link "cyg${OUTPUT_NAME}.dll" differs from expected as other Unix platforms. + # Although, to dlopen(), usually "cyg${OUTPUT_NAME}.dll" will be passed (or "lib${OUTPUT_NAME}.dll" and "lib${OUTPUT_NAME}.so" + # are also viable as Cygwin runtime replaces those prefix and suffix), which is same manner to other Unix platforms, + # and clang-python does so. + # Thus, put a copy of dll named without version suffix to convinience to use of dlopen(). A symbolic link can't be + # viable here as the path passed to dlopen() will be passed directly to LoadLibraryExW, so it must be a real file. + set(UNPAINTED_TARGET_NAME "$<TARGET_FILE_DIR:libclang>/$<TARGET_FILE_PREFIX:libclang>clang$<TARGET_FILE_SUFFIX:libclang>") + add_custom_command(TARGET libclang POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy "$<TARGET_FILE:libclang>" "${UNPAINTED_TARGET_NAME}") + install(FILES "${UNPAINTED_TARGET_NAME}" DESTINATION "${CMAKE_INSTALL_BINDIR}" COMPONENT libclang) + endif() + # Avoid declaring clang c++ symbols that are statically linked into libclang as dllimport'ed. + # If llvm/libclang-cpp dll is also being built for windows clang c++ symbols will still be + # implicitly be exported from libclang. + target_compile_definitions(libclang PRIVATE CLANG_BUILD_STATIC) elseif(APPLE) set(LIBCLANG_LINK_FLAGS " -Wl,-compatibility_version -Wl,1") set(LIBCLANG_LINK_FLAGS "${LIBCLANG_LINK_FLAGS} -Wl,-current_version -Wl,${LLVM_VERSION_MAJOR}.${LLVM_VERSION_MINOR}.${LLVM_VERSION_PATCH}") >From 64e727aa96fbe69b0d637e243895fcd43dbf8701 Mon Sep 17 00:00:00 2001 From: kikairoya <kikair...@gmail.com> Date: Sat, 5 Jul 2025 22:01:59 +0900 Subject: [PATCH 2/3] rewrite comment --- clang/tools/libclang/CMakeLists.txt | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/clang/tools/libclang/CMakeLists.txt b/clang/tools/libclang/CMakeLists.txt index 9c5ca26aab099..d3214104e6e0d 100644 --- a/clang/tools/libclang/CMakeLists.txt +++ b/clang/tools/libclang/CMakeLists.txt @@ -163,13 +163,15 @@ if(ENABLE_SHARED) VERSION ${LIBCLANG_LIBRARY_VERSION} DEFINE_SYMBOL _CINDEX_LIB_) if (CYGWIN) - # On Cygwin environment, a library target generates "cyg${OUTPUT_NAME}-${VERSION}.dll" and "lib${OUTPUT_NAME}.dll.a" but - # don't provide link "cyg${OUTPUT_NAME}.dll" differs from expected as other Unix platforms. - # Although, to dlopen(), usually "cyg${OUTPUT_NAME}.dll" will be passed (or "lib${OUTPUT_NAME}.dll" and "lib${OUTPUT_NAME}.so" - # are also viable as Cygwin runtime replaces those prefix and suffix), which is same manner to other Unix platforms, - # and clang-python does so. - # Thus, put a copy of dll named without version suffix to convinience to use of dlopen(). A symbolic link can't be - # viable here as the path passed to dlopen() will be passed directly to LoadLibraryExW, so it must be a real file. + # On Cygwin, a shared library target generates "cyg${OUTPUT_NAME}-${VERSION}.dll" + # and "lib${OUTPUT_NAME}.dll.a", but does not generate an unversioned symlink + # "cyg${OUTPUT_NAME}.dll" as is common on other Unix platforms. + # However, tools like clang-python or direct dlopen() calls usually expect the + # unversioned form (e.g. "cygclang.dll"). While Cygwin can resolve some alternate + # names (e.g. "libclang.so", "libclang.dll"), LoadLibraryExW used under the hood + # doesn't follow Cygwin-style symlinks, so a real file is required. + # This copies the versioned DLL to an unversioned name to improve compatibility + # with such tools. set(UNPAINTED_TARGET_NAME "$<TARGET_FILE_DIR:libclang>/$<TARGET_FILE_PREFIX:libclang>clang$<TARGET_FILE_SUFFIX:libclang>") add_custom_command(TARGET libclang POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy "$<TARGET_FILE:libclang>" "${UNPAINTED_TARGET_NAME}") >From 15003b15c9b14326736df46abecfdd7704c7920f Mon Sep 17 00:00:00 2001 From: kikairoya <kikair...@gmail.com> Date: Mon, 7 Jul 2025 07:11:10 +0900 Subject: [PATCH 3/3] use a symlink, don't copy --- clang/tools/libclang/CMakeLists.txt | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/clang/tools/libclang/CMakeLists.txt b/clang/tools/libclang/CMakeLists.txt index d3214104e6e0d..49c56aa701d73 100644 --- a/clang/tools/libclang/CMakeLists.txt +++ b/clang/tools/libclang/CMakeLists.txt @@ -167,14 +167,12 @@ if(ENABLE_SHARED) # and "lib${OUTPUT_NAME}.dll.a", but does not generate an unversioned symlink # "cyg${OUTPUT_NAME}.dll" as is common on other Unix platforms. # However, tools like clang-python or direct dlopen() calls usually expect the - # unversioned form (e.g. "cygclang.dll"). While Cygwin can resolve some alternate - # names (e.g. "libclang.so", "libclang.dll"), LoadLibraryExW used under the hood - # doesn't follow Cygwin-style symlinks, so a real file is required. - # This copies the versioned DLL to an unversioned name to improve compatibility - # with such tools. + # unversioned form (e.g. "cygclang.dll"). + # Therefore, we create a symlink named without the version suffix to + # improve compatibility. set(UNPAINTED_TARGET_NAME "$<TARGET_FILE_DIR:libclang>/$<TARGET_FILE_PREFIX:libclang>clang$<TARGET_FILE_SUFFIX:libclang>") add_custom_command(TARGET libclang POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy "$<TARGET_FILE:libclang>" "${UNPAINTED_TARGET_NAME}") + COMMAND ${CMAKE_COMMAND} -E create_symlink "$<TARGET_FILE:libclang>" "${UNPAINTED_TARGET_NAME}") install(FILES "${UNPAINTED_TARGET_NAME}" DESTINATION "${CMAKE_INSTALL_BINDIR}" COMPONENT libclang) endif() # Avoid declaring clang c++ symbols that are statically linked into libclang as dllimport'ed. _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits