Description
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
andmylib.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 againstlibmylib.so
). On Windows, the base name of the.lib
file has to be provided.For 3rd party libraries such as
mylib.dll
andmylib.lib
, this still equals#[link(name = "mylib")]
, but for Rust produced library pairsmylib.dll
andmylib.dll.lib
a#[link(name = "mylib.dll")]
is needed instead.
Update - Changed #[cfg_attr]
to be more correctish ...