I'm trying to link a Rust program with libsoundio. I'm using Windows and there's a GCC binary download available. I can link it like this if I put it in the same folder as my project:
#[link(name = ":libsoundio-1.1.0/i686/libsoundio.a")]
#[link(name = "ole32")]
extern {
fn soundio_version_string() -> *const c_char;
}
But I really want to specify #[link(name = "libsoundio")]
or even #[link(name = "soundio")]
, and then provide a linker path somewhere else.
Where can I specify that path?
I tried the rustc-link-search
suggestion as follows:
#[link(name = "libsoundio")]
#[link(name = "ole32")]
extern {
fn soundio_version_string() -> *const c_char;
}
And in .cargo/config
:
[target.i686-pc-windows-gnu.libsoundio]
rustc-link-search = ["libsoundio-1.1.0/i686"]
rustc-link-lib = ["libsoundio.a"]
[target.x86_64-pc-windows-gnu.libsoundio]
rustc-link-search = ["libsoundio-1.1.0/x86_64"]
rustc-link-lib = ["libsoundio.a"]
But it still only passes "-l" "libsoundio"
to gcc and fails with the same ld: cannot find -llibsoundio
. Am I missing something really obvious? The docs seem to suggest this should work.
With
rustc
, use-L
and-l
:Note, with
-l
you should discard the prefixlib
and the extension.a
of your static library:-lsoundio
As stated in the documentation for a build script:
In your Cargo.toml:
And your build.rs:
Note that your build script can use all the power of Rust and can output different values depending on target platform (e.g. 32- and 64-bit).
Finally, your code:
The proof is in the pudding:
Ideally, you will create a
soundio-sys
package, using the convention for*-sys
packages. That simply has a build script that links to the appropriate libraries and exposes the C methods. It will use the Cargolinks
key to uniquely identify the native library and prevent linking to it multiple times. Other libraries can then include this new crate and not worry about those linking details.Another possible way is setting the
RUSTFLAGS
like:I don't know if this is the most organized and recommended approach, but it worked for my simple project.
I found something that works OK: you can specify
links
in yourCargo.toml
:This specifies that the project links to
libsoundio
. Now you can specify the search path and library name in the.cargo/config
file:(The
:
prefix tells GCC to use the actual filename and not to do all its idioticlib
-prepending and extension magic.)You also need to create an empty
build.rs
:This file is never run, because the values in
.cargo/config
override its output, but for some reason Cargo still requires it - any time you uselinks =
you have to havebuild =
, even if it isn't used.Finally in
main.rs
: