-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
[MSVC] Referencing a static from another crate doesn't seem to work #26591
Comments
Since build scripts link to their dependencies dynamically instead of statically, this means that statics have to be properly marked with dllimport and dllexport, unlike for functions where those attributes can be left off with only a minor performance hit. MinGW's |
cc @alexcrichton I guess |
See also #7196 |
We currently do place dllimport on statics (and dllexport), but I haven't had a chance to investigate this thoroughly yet. I'm surprised that this doesn't work when the bootstrap works. |
I'm going to replace However any static + build script combination seems to trigger this problem, so it should be easy to reproduce. |
I have the same problem with my
But interesingly if I add |
Apparently using For each usage of I tried to compile a complex project (outside of a build script), and I got hundreds and hundreds of warnings, and 9 errors. In my opinion this wasn't detected earlier because warnings from the linker are simply ignored. |
I'm having a similar issue during linking using |
OK, I had some time to investigate this and I believe I know what's going on now. The fundamental problem here is #7196 (we don't handle dllimport/dllexport properly). To recap, a constant
Now one question I had personally was "why doesn't this break everything?!" We have a huge test suite, most of which is passing on MSVC, and most of which references a static from the standard library (aka this exact situation). It turns out that if the linker already included the object file for another reason (e.g. it resolved another function) then it will detect that we're looking for What this ends up meaning is that if any other symbol from our upstream library was used, then the linker error goes away. For example if you add So, to summary, there are a number of ways to work around this:
We currently don't tag any functions with dllimport (only dllexport), so I'm currently exploring that route to see if it works for constants as well (which would fix this problem), but I vaguely remember it specifically not working before, so my hopes are not that high. Otherwise this is basically a dupe of #7196 (correctly dealing with dllimport/dllexport), so I'm going to close this in favor of that. |
Ah yeah unfortunately not using dllimport didn't work. If you're importing a function from a dll and forget dllimport I think you take a small perf hit (e.g. one jump instruction) to link anyway, but if you're importing a constant from a dll and forget dllimport it just hits a link error. |
Currently you can hit a link error on MSVC by only referencing static items from a crate (no functions for example) and then link to the crate statically (as all Rust crates do 99% of the time). A detailed investigation can be found [on github][details], but the tl;dr is that we need to stop applying dllimport so aggressively. This commit alters the application of dllimport on constants to only cases where the crate the constant originated from will be linked as a dylib in some output crate type. That way if we're just linking rlibs (like the motivation for this issue) we won't use dllimport. For the compiler, however, (which has lots of dylibs) we'll use dllimport. [details]: rust-lang#26591 (comment) cc rust-lang#26591
Currently you can hit a link error on MSVC by only referencing static items from a crate (no functions for example) and then link to the crate statically (as all Rust crates do 99% of the time). A detailed investigation can be found [on github][details], but the tl;dr is that we need to stop applying dllimport so aggressively. This commit alters the application of dllimport on constants to only cases where the crate the constant originated from will be linked as a dylib in some output crate type. That way if we're just linking rlibs (like the motivation for this issue) we won't use dllimport. For the compiler, however, (which has lots of dylibs) we'll use dllimport. [details]: #26591 (comment) cc #26591
The
glutin
library has a build script and thekhronos_api
build-dependency.The
khronos_api
crate does nothing except export 4 pub static items (source code here).This build script fails to compile with the MSVC++ nightlies with the following error:
The four unresolved symbols refer to the four static variables exported by
khronos_api
.This only happens with the 64bits version. The 32bits build works fine.EDIT: oops, 32bits was in fact using MinGW, so nevermind.In addition to this, there are also a lot of warnings generated:
The symbols of these warnings refer to functions of the other build-dependency, which is
gl_generator
. I don't really know what they mean. Maybe they are shown only because of the linking errors and would be hidden otherwise?Here is the complete log from appveyor for reference.
The text was updated successfully, but these errors were encountered: