-
Notifications
You must be signed in to change notification settings - Fork 77
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
Run pkg-config on MSVC #39
Conversation
Confirmed in the servo build that this actually works |
I think one thing I've also seen in the past is that if you build for MSVC in a MinGW environment then |
Generally the ABI of MSVC and mingw is compatible for C (not C++!). Do you have more details? |
Ah sorry I don't recall the logs offhand, but I believe it's moreso around linking than it is ABI issues. C code using the C standard library may link against libc from MinGW but fail to link against MSVC because the C standard library has slightly different internal ABIs |
For GStreamer, we're (currently) building our binaries with MinGW and people are using them with MSVC and MinGW. The C standard library used by MinGW and MSVC is also the same (msvcrt), it might just be a different version. But that's not a problem on Windows, you can have different versions in the same process (you just can't e.g. Not sure how to proceed here without further information :) How do you want to make sure a "correct" library is chosen? |
Hm yeah I think DLLs work out, but you're not shipping objects, right? I'm worried, for example, about picking up TBH I have no idea how one would even begin to configure Could this be behind an off-by-default flag or env var? My experience so far is basically that if pkg-config is used on MSVC it inevitably breaks a bunch of AppVeyor CI for projects like Cargo, curl, RLS, etc. |
Yes, static linking to static libraries and objects that use the MinGW API will lead to undefined symbols since at link time the GCC linker automatically adds some compiler static libs to resolve those (
I thought rustc transforms
I am not sure what you mean by this. The output of pkg-config is mostly compiler-agnostic, and we already handle the differences in the pkg-config crate. |
I'm also not sure why pkg-config-rs should care about this, it seems like it's the user's job to make sure dependencies are found (i.e. The simple reality is that linking libraries (see also DLL hell) on Windows is a mess and things need to be properly set-up in the environment so that it can succeed, independent of pkg-config or not. |
Er sorry, so my point is that I've given up historically with MSVC and pkg-config precisely because all of the situations that aren't supposed to happen end up happening. For example AppVeyor builds (and rustc builds itself) run with MinGW tools in the environment which means that It's on users for sure to set up pkg-config, but it's just too easy for users to accidentally pick up a MinGW |
In my cases I'm actually using the same pkg-config (and the same .pc files) for both MSVC and MinGW builds, so it's not that easy :) Not sure what to do here then, seems like it boils down again to linking and development on Windows in general being a mess. Every option I can think of will fail for someone or require non-obvious configuration via environment variables to change the behaviour of different crates' |
Another thing to note is that Meson always uses |
Would it be possible to actually open up the archive and take a look inside? Perhaps there's an easy-to-find marker which differentiates MinGW from MSVC? |
We could extract an object file from the the archive, peek at the sections in it, and look for a |
Okay, clang-cl also creates The most reliable way to check for usability of a static library is to try to link to it with simple |
I don't think trying to sniff out usable libraries is safe, in general; down that path lies a lot of platform-specific pain. @retep998, could we get some help figuring out the Right Thing to do here, when using |
Fwiw, I'm mostly describing what Meson does on Windows for library detection. All the bugs I've encountered with pkg-config-rs over the past 2 years (on all platforms) have been issues that Meson already solved. I was planning to duplicate that logic in pkg-config-rs. It would not involve peeking into libraries, but it would involve manual filesystem searching, then invoking the compiler to link to the library in question and using the full path to it instead of |
@nirbheek Is that something Meson only does on Windows, or does it also attempt to do manual filesystem searching on other platforms? (One of the biggest potential problems with attempting to reimplement pkg-config is that distributions sometimes patch pkg-config for their particular library paths, such as for multiarch; manual searching would typically be unaware of the right paths to use and the paths to carefully not use. I've run into software that tries to link a library for the wrong architecture because it's aggressively searching in a directory it thinks should contain the library it wants.) |
In my opinion, using |
Meson manually resolves the path to the library to link on all platforms because depending on the linker search path at compile-time is completely broken. If you have multiple sources for libraries to be picked up from (which is fairly common even on Linux), it's quite likely you'll pick up the wrong one.
The idea is not to reimplement pkg-config, but to bypass the linker's automatic library searching. If you call pkg-config with Linking to the library solves the second issue of picking up a library for the wrong arch. F.ex., sometimes distros put both 32-bit libs and 64-bit libs in that path, or the user has made a mistake and pointed But the pkg-config-rs on Windows only needs a tiny subset to work with MSVC: convert
I am not sure it's feasible to tell people to inject a dependency tree using build script overrides. Note that this is required for gstreamer on Windows; we have about 50 rust plugins that have to find gstreamer (+ deps) using pkg-config. There really isn't an alternative on Windows. CMake dependency files are even worse since they're turing-complete and you literally have to create a temporary build directory and run cmake to parse them. We do this in Meson too, and I would not recommend it. |
Ah, I should also mention: by default |
You might also want to take a look at the For the general problem of |
Is there a chance of merging this? I am running into issues building tectonic on Windows in conda-forge, which generally favors pkg-config, and if I patch in this change it fixes my build. (edit: I should mention that the build error is redundant symbols from the "system" libz, found via pkg-config, and the version built inside libz-sys. It is very hard for me to see how to avoid the problem without including this patch.) |
Are there any updates on what's going to happen with this PR? I'm also interested in finding zlib on windows with pkg-config |
This PR has been inactive for quite a while without resolution. Here is the GPT-summary (which I didn't validate) thus far: The GitHub page you provided is a pull request on the
Overall, the pull request and subsequent discussion revolve around the issues and challenges related to using Even though it seems there are various unresolved questions or problems with supporting this, I wonder if we can trust CI (which might have improved by now) to tell us if it's working or not. Let me fix the conflict and see what CI has to say. |
CI is (still) happy, but I wonder if the build environment actually has So as a path forward, I hope we could validate that that…
Maybe there is also a way to merge this with an 'opt-in' toggle so those who benefit can use it, without risk of breaking the world. |
pkg-config indeed sometimes is used on windows, if you look at the vcpkg zlib package you can see it installs the .pc file and the content therein is correct and works on windows, you can verify this, install the zlib port, get pkg-config or pkg-conf in your path (I used the versions in msys2, so long as you use the ucrt/clang/mingw versions things will work, the msys2 version will probably use cygwin style paths), set PKG_CONFIG_PATH to "\lib\pkgconfig" and run Note that the pkg-config crate doesn't pass --msvc-syntax to pkg-config, because it parses the gcc style command line itself, it does seem to support msvc when it does so however, so things should "just work" Let me clone this branch and see what happens |
I tried this out and it seems to work fine, although I'm just looking at the build script output. which follows
|
I also verified that indeed the build script is finding zlib via pkg-config, not vcpkg (even though I installed zlib via vcpkg). I'm just going to point out that chatgpt kinda got things wrong. The issue with pkg-config-rs was fixed years ago and, as nirbheek pointed out there's a very low risk of mixing msvc and mingw libraries because rustc automatically appends .lib on -msvc toolchains and .a on -gnu toolchains. as nirbheek points out projects like gstreamer-rs really, really need pkg-config to work on windows, because they have many, many C dependencies that they want to override to use the same versions as they already build for the gstreamer C libraries. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for validating it and for the additional context and correction, @barcharcraz! I have asked for more reviewers to hopefully be able to make a decision on this PR.
My disposition here is to merge it, as times changed since it was first opened while it seems to work correctly both for CI and for those who try it on their machines.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, but I'm not familiar with Windows (development environment) and I cannot say much more than CI agrees with it.
If it doesn't break the build on the minimal environment, I think it's okay (GitHub-hosted runner has some additional setup for convenience).
I have rebased this PR onto It's also a single line change that can easily be undone as well should serious error occour. However, since it's now more than 4 years later, and I generally think software gets better, I think the chances of this now working are higher than while this PR was new. |
The root cause of the pkg-config failure on MSVC seems to be that pkg-config-rs is appending .lib, while it shouldn't because rustc already does that on Windows.
@sdroege is fixing this issue in rust-lang/pkg-config-rs#72.