我正在尝试将Rust程序与libsoundio相关联。我正在使用Windows,并且可以使用GCC二进制下载。如果我把它放在与我的项目相同的文件夹中,我可以像这样链接它:
#[link(name = ":libsoundio-1.1.0/i686/libsoundio.a")]
#[link(name = "ole32")]
extern {
fn soundio_version_string() -> *const c_char;
}
但我真的想指定#[link(name = "libsoundio")]
甚至#[link(name = "soundio")]
,然后在其他地方提供链接器路径。
我可以在哪里指定该路径?
我尝试了rustc-link-search
建议如下:
#[link(name = "libsoundio")]
#[link(name = "ole32")]
extern {
fn soundio_version_string() -> *const c_char;
}
在.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"]
但它仍然只会将"-l" "libsoundio"
传递给gcc并失败并使用相同的ld: cannot find -llibsoundio
。我错过了一些非常明显的东西吗文档似乎表明这应该有效。
答案 0 :(得分:9)
如documentation for a build script中所述:
由[{1}}构建脚本[...起始]打印到stdout的所有行都由Cargo [...]
cargo:
直接解释,表示应将指定的值传递给编译器作为rustc-link-search
标志。
在 Cargo.toml :
中-L
您的 build.rs :
[package]
name = "link-example"
version = "0.1.0"
authors = ["An Devloper <an.devloper@example.com>"]
build = "build.rs"
请注意,您的构建脚本可以使用Rust的所有功能,并且可以根据目标平台(例如32位和64位)输出不同的值。
最后,您的代码:
fn main() {
println!(r"cargo:rustc-link-search=C:\Rust\linka\libsoundio-1.1.0\i686");
}
证据在布丁中:
extern crate libc;
use libc::c_char;
use std::ffi::CStr;
#[link(name = "soundio")]
extern {
fn soundio_version_string() -> *const c_char;
}
fn main() {
let v = unsafe { CStr::from_ptr(soundio_version_string()) };
println!("{:?}", v);
}
理想情况下,您将使用the convention for *-sys
packages创建$ cargo run
Finished debug [unoptimized + debuginfo] target(s) in 0.0 secs
Running `target\debug\linka.exe`
"1.0.3"
个包。它只是有一个构建脚本,链接到相应的库并公开C方法。它将使用Cargo links
key来唯一标识本机库并防止多次链接。然后其他库可以包含这个新的包,而不用担心链接细节。
答案 1 :(得分:4)
我找到了一些正常的方法:您可以在links
中指定Cargo.toml
:
[package]
links = "libsoundio"
build = "build.rs"
这指定项目链接到libsoundio
。现在,您可以在.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"]
(:
前缀告诉GCC使用实际文件名,而不是做所有愚蠢的lib
- 前置和扩展魔术。)
您还需要创建一个空的build.rs
:
fn main() {}
此文件永远不会运行,因为.cargo/config
中的值会覆盖其输出,但由于某种原因,Cargo仍然需要它 - 只要您使用links =
,就必须拥有build =
,即使它没有被使用。
最后在main.rs
:
#[link(name = "libsoundio")]
#[link(name = "ole32")]
extern {
fn soundio_version_string() -> *const c_char;
}
答案 2 :(得分:1)
另一种可能的方式是setting the RUSTFLAGS
,例如:
RUSTFLAGS='-L my/lib/location' cargo build # or cargo run
我不知道这是否是最有条理和推荐的方法,但是它适用于我的简单项目。
答案 3 :(得分:0)
使用rustc
,使用-L
和-l
:
$ rustc --help
...
-L [KIND=]PATH Add a directory to the library search path. The
optional KIND can be one of dependency, crate, native,
framework or all (the default).
-l [KIND=]NAME Link the generated crate(s) to the specified native
library NAME. The optional KIND can be one of static,
dylib, or framework. If omitted, dylib is assumed.
...
注意,对于-l
,您应该放弃静态库的前缀lib
和扩展名.a
:-lsoundio