-
Notifications
You must be signed in to change notification settings - Fork 14.4k
[libclang][Cygwin] Provide unversioned DLL file alongside versioned one #147132
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
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`.
@llvm/pr-subscribers-clang Author: Tomohiro Kashiwada (kikairoya) ChangesOn Cygwin, a shared library target generates a versioned DLL file like However, Therefore, this patch installs an unversioned copy of the DLL without the version suffix to improve compatibility with Full diff: https://github.com/llvm/llvm-project/pull/147132.diff 1 Files Affected:
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}")
|
If dlopen doesn't work on a Cygwin symlink, that is a bug in dlopen and should be fixed in Cygwin. |
I had been misunderstood the functionality. That's cool. Thank you. I made changes for description, commit and function body to use symlink. |
|
Updated for use relative path to link target. |
Perhaps the change in https://github.com/llvm/llvm-project/pull/136599/files#diff-f60dae8e82f67fa5e534e9ea566430d5b79f36119020865dc37b95d9a3635c5eR753 should be reconsidered instead, I wasn't thinking about dlopen in that case. |
I'm thinking about each DLLs:
I had focused to make a symlink So, installed-tree will be:
I would like to know if there are any concerns to do this. |
@mstorsjo ? I imagine whatever scheme is adopted should be considered with consistency with MinGW also. |
On Cygwin, a shared library target generates a versioned DLL file like
cyg${OUTPUT_NAME}-${VERSION}.dll
and an import librarylib${OUTPUT_NAME}.dll.a
, but it does not generate the expected unversioned symlinkcyg${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.This patch creates a symbolic link named "cygclang.dll" pointing to the versioned DLL to improve compatibility with existing tooling and usage patterns.