-
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
Implement RFC 1717 #37973
Implement RFC 1717 #37973
Conversation
cc @retep998 |
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.
Looks good! Some further thoughts:
- At the same time, this should supplant
#[linked_from]
, can all usages of that be replaced with this? - Shouldn't
dllexport
get hooked up into this infrastructure as well?
if item.name == name { | ||
item.kind = new_kind; | ||
if let Some(new_name) = new_name { | ||
item.name = Symbol::intern(new_name); |
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.
Could we take an extra conservative route here and avoid multiple indirections of libraries? Ideally each library would be renamed at most once and wouldn't have to worry about what order we process options in.
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.
Not sure what you mean by "multiple indirections"... Is this about the fact that there may be several NativeLibrary
entries for the same library? I don't think we can just merge them,- because library ordering on linker's command line is important.
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.
Oh I mean something like:
rustc -l foo:bar -l bar:baz -l baz:real-name
We shouldn't allow something like that and a lib should be "renamed" at most once.
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.
Ok. Just want to note that this behavior is occasionally useful when you want to override something by appending to a pre-composed command line (usually comes up in makefiles and such).
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.
@alexcrichton: How far did you want to take this checking?
Currently the following are allowed:
-l foo -l foo
-l static=foo -l dylib=foo
which would result in adding foo
to the linker command line twice.
Under the new rules, this will merely change the kind of foo
two times (assuming it's been defined in crate source, and if not... I am not sure).
It feels a bit weird to allow chaining for kind alterations, but not for names.
Perhaps this part of the RFC merits additional discussion.
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.
Hm that does sound like an unfortunate "regression", but I'd imagine that in practice that was doomed to never link correctly anyway?
It does seem like we can't strictly require that -lfoo
isn't specified more than once, but perhaps we can still be strict about renamings where a lib is only renamed once?
cfg: None, | ||
foreign_items: Vec::new(), | ||
}; | ||
register_native_lib(self.sess, self.cstore, None, lib); |
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.
In this case the new_name
is thrown away, but isn't that the name the library should be linked under?
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.
Good point. Yes, I should use new_name
here, if available.
Probably also emit a warning?
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.
Hm actually given the option to do so let's make this a hard error to be conservative.
@@ -98,7 +98,7 @@ mod tests { | |||
#[derive(Copy, Clone)] | |||
pub struct Floats { a: f64, b: u8, c: f64 } | |||
|
|||
#[link(name = "rust_test_helpers")] | |||
#[link(name = "rust_test_helpers", kind = "static")] |
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.
Were these changes (and those below) required? If so that may be quite worrisome as this is a breaking change...
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.
rust_test_helpers
is a static lib, so it started failing on Windows after this change. Granted it was only a couple of tests that used the rust_dbg_static_mut
export, but I did a bulk change for consistency sake.
So yeah, there is some potential for breakage, but importing data from a library is a relatively rare thing, and it was already broken on Windows half the time. Not sure how to assess the extent of this breakage though. There is no such thing as Windows crater, right?
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.
Yeah unfortunately no crater coverage just yet, but to be clear the failure mode here was:
- The linkage was incorrectly tagged
- The library only pulled in statics
- We then spit out a linker error
If that's the case then yeah seems like ok breakage. There's a way to fix it to work on all rustc versions, and otherwise we're just fixing a bug.
Specifically, if an extern symbol is known to come from a static library, and that extern symbol is reachable in a |
I thought we already did this (export all reachable public symbols via a .def file)? |
@vadimcn We do export all reachable stuff right now, except for extern symbols pulled in from static libraries. If |
@vadimcn I suppose both of my points should get lumped into one. The |
As-implemented, I've noticed, though, that upstream publics are exported only for dylibs. Cdylibs export just their own public symbols. @alexcrichton: is it supposed to be this way, or was this case overlooked when cdylibs were added? |
@vadimcn hm I believe that's overlooked, cdylibs shouldn't be exporting statically linked libraries. |
Shouldn't or should? Right now they don't, so this sentence seems self-contradictory :-/ |
If I have an |
Oh sorry, I misinterpreted. If we have a "bug" where we export fewer symbols let's keep it that way. Easier to later export symbols than to hide them. |
We do currently incorrectly export some functions from cdylibs which shouldn't be exported, so fixing that would be really nice. #34493 |
I'm talking about this case: #![crate_type = "cdylib"]
#[link(name = "native", kind="static")]
extern "C" {
pub fn static_func2(x: i32) -> i32;
pub static static_global2: i32;
}
#[no_mangle]
pub extern "C" fn local() {} Right now only the |
@vadimcn Because |
@vadimcn I'm fine classifying that as a bug, but I'm also fine not explicitly fixing that here unless it just happens to fall out naturally. |
Removed "linked_from" and added more error checking. |
📌 Commit a23c470 has been approved by |
lib.name = Symbol::intern(new_name); | ||
} | ||
found = true; | ||
break; |
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.
How does this break
live along with the (there may be more than one)
comment?
You are right, it doesn't :( @bors: r- |
@bors: r=alexcrichton |
📌 Commit 923034f has been approved by |
⌛ Testing commit 923034f with merge 32e99bd... |
💔 Test failed - auto-win-gnu-32-opt-rustbuild |
Hrm, is there a way to restrict a test to -windows-msvc only? |
@bors: r=alexcrichton |
📌 Commit 2e03549 has been approved by |
⌛ Testing commit 2e03549 with merge 925bc9b... |
💔 Test failed - auto-win-msvc-64-opt-rustbuild |
Turns out I never ran the full test suite on a Windows host. :-/ |
@bors: r+ |
📌 Commit 7d05d1e has been approved by |
Implement RFC 1717 Implement the first two points from #37403. r? @alexcrichton
let mut found = false; | ||
for lib in self.cstore.get_used_libraries().borrow_mut().iter_mut() { | ||
if lib.name == name as &str { | ||
lib.kind = kind; |
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.
Does this mean the a kind specified in the source will be silently overwritten?
Implement the first two points from #37403.
r? @alexcrichton