-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Use #[link(kind)] to fix imports from native libs on Windows #1717
Conversation
Two questions/problems:
|
It's still needed. The dllimport attribute alters code generation on the caller side.
No, link.exe does not support linking to a .dll without an import library. You can create import library from a dll with either msvc tools or mingw tools. |
Note that it is possible to have rustc emit idata sections and avoid the need for import libraries, but that's not part of the scope of this RFC. If someone wants to create an RFC for rustc emitting idata, go for it. rust-lang/rust#30027 |
This is great! I'm not even primarily windows user, but I was thinking about how originally rustc was very anti endless CLI options, but then Cargo came along any many of those decisions were no longer the purview of the rust source. This is the best of both worlds in the source code can ensure it gets what it needs, but not mandate exactly how that's accomplished.
|
I'm using slightly poor terminology, for which I apologize. I'm aware that link.exe doesn't take dlls. I would love to see another RFC for this. The flexibility of just being able to import without caring is a feature I really wish more native languages had. Unfortunately, I don't know enough about LLVM to even try (but perhaps that is unnecessary). |
cc @nikomatsakis, you had many opinions on #1296 as well. Otherwise looks great to me, thanks @vadimcn! |
I'd argue that "abstract" is superfluous, as discussed in the "unresolved questions" - in particular, the ability to override non- As a further benefit, this means that the approach most people will default to (i.e. the least typing) is the one the tooling expects for such cases, allowing them to fall into the "correctness hole." Another possibility, to address the "drawbacks" section, is that an additional tool could be written to validate that the |
@eternaleye How can you validate whether the user used |
@retep998: That's actually almost exactly backwards of both where and what I was thinking of validating. In particular, I was thinking of validating that the declared symbols are present in (and maybe only in, as more lenient checks have differing behavior across OSes) the declared library. As this check is possible on any OS, it could catch some classes of error before Windows CI is ever run. |
@eternaleye That still seems rather complicated and brittle as Rust/Cargo needs to have access to the library to analyze it and determine whether the symbols exist (which is hard when the library is being pulled in as a system dependency so only the linker knows where it actually is), nevermind that would only verify the current configuration, it wouldn't know whether the declared library on other platforms has those symbols too. Furthermore verifying that the symbols are only in that library would mean analyzing every single other library to ensure they don't have the symbols. Really I think this would be better suited by the crate just having tests to ensure example binaries link correctly and running it on CI on a variety of platforms. |
One clarification. In the RFC, you have this example:
If the user uses the command line to specify that |
I agree that it is not needed. It seems cleaner to me, though, and doesn't seem like a very complex addition. If you expect the details of this library to be specified in the Another way of looking at it is that it is roughly like the difference between doing: let x = if foo { 22 } else { 23 }; versus: let mut x = 23;
if foo { x = 22; }
I don't follow this clause. There is literally a kind |
This part of the RFC feels ... underspecified to me:
But maybe that's all that needs to be said? I'm not close enough to the code to say for sure I guess. |
#[link(name = "foo")] // defaults to kind = "dylib"
extern {
// ...
} See #1717 (comment) As this "dylib" can be overridden, the convention can then be "leave it off for Cargo" - and there could also be lints if a defaulted |
Hmm, that's not a bad idea: add a warning now, and maybe for Rust 2.0 change its meaning so specifying a kind on the CLI is mandatory. Leaving out a kind is definitely the more intuitive syntax than |
Well, you'd have to know when to pass it to the linker, which is particularly important when you are creating Rust dylibs (cdylibs don't count here). For But yes, all of this should be obvious to anyone familiar enough with this sort of stuff, although it wouldn't hurt to clarify it in the RFC. |
I guess it's a matter of taste. I don't consider this a win, for the reasons I already gave. It's ambiguous whether I actually wanted dylib or not. It seems like the result would be "less good" error messages when I fail to override: instead of saying "please supply some information about where to find the abstraction dependency But anyway it's a minor point. |
@nikomatsakis: But with a warning, you would get a good error message.
|
Even better, avoid the word "override" to make clear how things ought to be:
And:
|
OK, I yield, I yield! :) I like the idea of "no kind without an override" being explicitly deprecated, and defaulting just for backwards compat, as opposed to just being defined as falling back to |
@rfcbot fcp merge We've had a lot of discussion on this over time, lots of discussion in amongst the tools team historically, so I think this is ready for merging! |
Team member alexcrichton has proposed to merge this. The next step is review by the rest of the tagged teams: No concerns currently listed. See this document for info about what commands tagged team members can give me. |
@rfcbot reviewed |
@rfcbot reviewed |
Can we get "abstract" removed as per @eternaleye and me above before merging? |
All relevant subteam members have reviewed. No concerns remain. |
🔔 This RFC is now entering its final comment period for merging 🔔 |
3rd above #1717 (comment) :) |
@vadimcn, thoughts? |
Yeah, I'm fine with dropping |
@vadimcn: The Basically: An undeclared kind used to mean |
Yes, I realize that. |
Reword "minus unbundling".
@vadimcn I think most sys crates should support dynamic or static linking, and this reminds them to do that or be explicit they don't. And because of mutable globals and what not, static vs dynamic isn't transparent on unix either. So I think this change RFC is necessary for Windows, but good medicine for all platforms :). |
It has been one week since all blocks to the FCP were resolved. |
Ok, sounds like the brought up concerns were addressed, and otherwise sounds like we're on board! Merging, thanks again for the RFC @vadimcn! Tracking issue: rust-lang/rust#37403 |
Make compiler aware of the association between library names adorning
extern
blocks and symbols defined within the block. Add attributes and command line switches that leverage this association.(based on RFC1296, minus the dllexport bits)
Rendered