[clang] [libclang][Cygwin] Provide unversioned DLL file alongside versioned one (PR #147132)

via cfe-commits cfe-commits at lists.llvm.org
Sat Jul 5 00:53:30 PDT 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Tomohiro Kashiwada (kikairoya)

<details>
<summary>Changes</summary>

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`.

---
Full diff: https://github.com/llvm/llvm-project/pull/147132.diff


1 Files Affected:

- (modified) clang/tools/libclang/CMakeLists.txt (+18-5) 


``````````diff
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}")

``````````

</details>


https://github.com/llvm/llvm-project/pull/147132


More information about the cfe-commits mailing list