Skip to content

fix zstd_shared detection on mingw #139945

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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open

Conversation

vtjnash
Copy link
Member

@vtjnash vtjnash commented May 14, 2025

The zstd_shared autodetection was broken for non-MSVC (mingw) compiled LLVM, since it assumed that *.a uniquely identifies a file as being a static library, but typically this is actually an import lib formed as the longer name *.dll.a from the binary. This leads to confusing output elsewhere, in cmake and llvm-config, when they report this is a static library at an absolute path instead of a shared library named -lzstd.

MSVC is not the only compiler that produces Windows dlls, which results
in llvm-config printing incorrect paths for --system-libs when
libzstd.dll support is enabled.
@llvmbot llvmbot added the cmake Build system in general and CMake in particular label May 14, 2025
@vtjnash vtjnash requested a review from mstorsjo May 14, 2025 19:41
Copy link
Member

@mstorsjo mstorsjo left a comment

Choose a reason for hiding this comment

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

The changes look reasonable overall, but I would prefer a bit more explanation of what went wrong before, what the previously MSVC specific codepaths do. It could be good to explicitly call it out in the commit message, that this fixes zstd in mingw builds (instead of implicitly via a negation, about windows compilers that aren't msvc).

@@ -29,11 +29,11 @@ find_package_handle_standard_args(
)

if(zstd_FOUND)
if(zstd_LIBRARY MATCHES "${zstd_STATIC_LIBRARY_SUFFIX}$")
if(zstd_LIBRARY MATCHES "${zstd_STATIC_LIBRARY_SUFFIX}$" AND NOT zstd_LIBRARY MATCHES "\\.dll\\.a$")
Copy link
Member

Choose a reason for hiding this comment

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

Is there any cmake variable that contains the .dll.a suffix as a string? But perhaps we don't want to use that here; for MSVC that (.lib) would be equal to the static library suffix, so it would negate the effect of the first part of the condition.

Copy link
Member Author

Choose a reason for hiding this comment

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

I don't know of any such variable, though we're more interested here in how zstd was compiled, while this check still incorrectly assumes the conventions are based on how LLVM will be compiled. I wasn't sure it is even possible to correctly identify the kind of file this is just using pattern matching on the name, but this change is trying to just make it behave more consistently. (When compiling MSVC, this tests against "_static.lib", so adding "not .dll.a" has no impact)

Copy link
Member

Choose a reason for hiding this comment

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

Oh, I missed that this used zstd_STATIC_LIBRARY_SUFFIX, I thought it was the usual CMAKE_STATIC_LIBRARY_SUFFIX.

If it would be the cmake general ones, and if we'd use the variable for import library suffix, like if (zstd_LIBRARY MATCHES "${CMAKE_STATIC_LIBRARY_SUFFIX}$" AND NOT zstd_LIBRARY MATCHES "${CMAKE_IMPORT_LIBRARY_SUFFIX}$"), it'd essentially be if (zstd_LIBRARY MATCHES ".lib$" AND NOT zstd_LIBRARY MATCHES ".lib$").

But this wasn't the case, so nevermind - sorry for the detour.

set(zstd_STATIC_LIBRARY "${zstd_LIBRARY}")
elseif (NOT TARGET zstd::libzstd_shared)
add_library(zstd::libzstd_shared SHARED IMPORTED)
if(MSVC OR "${CMAKE_CXX_SIMULATE_ID}" STREQUAL "MSVC")
if(WIN32 OR CYGWIN)
include(GNUInstallDirs) # For CMAKE_INSTALL_LIBDIR and friends.
Copy link
Member

Choose a reason for hiding this comment

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

Can you briefly explain what the code within this conditional branch does? (It's quite unreadable cmake soup as is...) I presume it does some transformation which is essential for using zstd in a mingw build setting.

Is it essential only for using the output of llvm-config, or for building llvm itself as well?

Copy link
Member Author

Choose a reason for hiding this comment

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

It transforms the detected zstd_LIBRARY value from an absolute path such as "/usr/lib/libzstd.dll.a" into a linker flag "-lzstd" and marks it in cmake as being a dll. The linker usually doesn't care very much about whether you pass an absolute path or -lzstd and ends up doing mostly the same thing either way, but it leads to inconsistencies when trying to use llvm-config and expecting it to have listed shared libraries with -lzstd

@vtjnash vtjnash changed the title fix zstd_shared detection on Windows fix zstd_shared detection on mingw May 22, 2025
@vtjnash
Copy link
Member Author

vtjnash commented May 22, 2025

I updated the github message, so you can just take that text when merging (I don't have merge rights)

@mstorsjo
Copy link
Member

I updated the github message, so you can just take that text when merging (I don't have merge rights)

Thanks!

The zstd_shared autodetection was broken for non-MSVC (mingw or clang) compiled LLVM

I'd like to nitpick the wording here, "mingw or clang" feels like a bit of an oxymoron (or something...) here. "Mingw" is the name of the environment, not a name that specifically means GCC; and clang can either be in mingw mode or in msvc mode. And clang in msvc mode has the same naming style/behaviour as regular MSVC.

Anyway, by just replacing the parenthesis with "(mingw)" it sounds fine to me. I'll approve the patch and I can update the PR description.

Copy link
Member

@mstorsjo mstorsjo left a comment

Choose a reason for hiding this comment

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

LGTM.

CCing @petrhosek who I think authored this cmake file, in case he has opinions on it. Otherwise I can probably merge it in a day or two (or whenever I remember it again).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cmake Build system in general and CMake in particular julialang
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants