Skip to content

#[link] attribute should better describe platform specific handling #638

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
ralfbiedert opened this issue Jul 13, 2019 · 3 comments
Open
Labels
E-Easy We believe this would not be difficult to actually fix New Content Missing features or aspects of language not currently documented.

Comments

@ralfbiedert
Copy link

ralfbiedert commented Jul 13, 2019

When working cross platform, in particular when producing a dylib from Rust and then again consuming it, the current resolution of #[link(name = "mylib"] is somewhat confusing.

  • If you start developing on Windows, Rust will produce a mylib.dll and mylib.dll.lib. To use this lib again from Rust you will have to specify #[link(name = "mylib.dll")], thus giving the impression that the full file name has to be specified. On Mac, however, #[link(name = "libmylib.dylib"] will fail (likewise Linux).

  • If you start developing on Mac and Linux, #[link(name = "mylib")] just works, giving you the impression Rust handles the name resolution (fully) automatically like other platforms that just require the base name.

In fact, the correct way to cross platform link against a dylib produced by Rust seems to be:

#[cfg_attr(all(target_os = "windows", target_env = "msvc"), link(name = "dylib.dll"))]
#[cfg_attr(not(all(target_os = "windows", target_env = "msvc")), link(name = "dylib"))]
extern "C" {}

Since according to this issue the current behavior can't be fixed and is "stable", I believe this should be documented somewhere. For me, the #[link] attribute was where I started my debug journey originally.

The documentation could be something like:

Note that on Mac and Linux name is the base name of the actual library (e.g., #[link(name = "mylib")] if you want to link against libmylib.so). On Windows, the base name of the .lib file has to be provided.

For 3rd party libraries such as mylib.dll and mylib.lib, this still equals #[link(name = "mylib")], but for Rust produced library pairs mylib.dll and mylib.dll.lib a #[link(name = "mylib.dll")] is needed instead.

Update - Changed #[cfg_attr] to be more correctish ...

@Havvy
Copy link
Contributor

Havvy commented Jul 15, 2019

The documentation you provided is written in a more guide-like style than (to quote Centril on Discord) a "definition-style spec text", but the information is there. Do you want to take your hand at improving that section? You definitely know more about the link attribute than I do.

@Havvy Havvy added E-Easy We believe this would not be difficult to actually fix New Content Missing features or aspects of language not currently documented. labels Jul 15, 2019
@ralfbiedert
Copy link
Author

Sure, I can try a PR.

@rossy62
Copy link

rossy62 commented Jul 8, 2021

Is there any information on why Rust produces mylib.dll then mylib.dll.lib and mylib.dll.exp in windows instead of mylib.exp and mylib.exp which is what the windows linker expects? At the moment I'm renaming these outputs to mylib.exp and mylib.lib
Perhaps I'm missing something but in windows when I produce a DLL I will get *.dll and only get *.lib and *.exp if there are exports, but when I have symbols exported I get *.dll *.lib and *.exp.
This issue of #link only applies to linking these modules to RUST libraries.
But as a user trying to integrate RUST into native C I found this naming issue to be a burden. I have to add a post build step to rename the files I think long term. But if the build system could be coerced into producig mylib.lib and mylib.exp then that would be ideal. Just trying to understand why it works the way it does.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
E-Easy We believe this would not be difficult to actually fix New Content Missing features or aspects of language not currently documented.
Projects
None yet
Development

No branches or pull requests

3 participants