Tim*_*mmm 8 dynamic-linking static-linking rust rust-cargo
我正在尝试将Rust程序与libsoundio链接起来.我正在使用Windows,并且可以使用GCC二进制下载.如果我把它放在与我的项目相同的文件夹中,我可以像这样链接它:
#[link(name = ":libsoundio-1.1.0/i686/libsoundio.a")]
#[link(name = "ole32")]
extern {
fn soundio_version_string() -> *const c_char;
}
Run Code Online (Sandbox Code Playgroud)
但我真的想指定#[link(name = "libsoundio")]甚至#[link(name = "soundio")],然后在其他地方提供链接器路径.
我在哪里可以指定该路径?
我尝试了rustc-link-search如下建议:
#[link(name = "libsoundio")]
#[link(name = "ole32")]
extern {
fn soundio_version_string() -> *const c_char;
}
Run Code Online (Sandbox Code Playgroud)
并在.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"]
Run Code Online (Sandbox Code Playgroud)
但它仍然只传递"-l" "libsoundio"给gcc并且失败了ld: cannot find -llibsoundio.我错过了一些非常明显的东西吗 文档似乎表明这应该有效.
She*_*ter 10
由构建脚本[...起始]打印到stdout的所有行
cargo:由Cargo [...]直接解释,rustc-link-search表示应将指定值作为-L标志传递给编译器.
在你的Cargo.toml:
[package]
name = "link-example"
version = "0.1.0"
authors = ["An Devloper <an.devloper@example.com>"]
build = "build.rs"
Run Code Online (Sandbox Code Playgroud)
你的build.rs:
fn main() {
println!(r"cargo:rustc-link-search=C:\Rust\linka\libsoundio-1.1.0\i686");
}
Run Code Online (Sandbox Code Playgroud)
请注意,您的构建脚本可以使用Rust的所有功能,并可以根据目标平台(例如32位和64位)输出不同的值.
最后,你的代码:
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);
}
Run Code Online (Sandbox Code Playgroud)
证据在于布丁:
$ cargo run
Finished debug [unoptimized + debuginfo] target(s) in 0.0 secs
Running `target\debug\linka.exe`
"1.0.3"
Run Code Online (Sandbox Code Playgroud)
理想情况下,您将使用soundio-sys包的约定*-sys创建包.它只是有一个构建脚本,链接到相应的库并公开C方法.它将使用Cargo links密钥唯一标识本机库并防止多次链接.其他库可以包含这个新的包,而不用担心链接细节.
另一种可能的方法是设置RUSTFLAGS如下:
RUSTFLAGS='-L my/lib/location' cargo build # or cargo run
Run Code Online (Sandbox Code Playgroud)
我不知道这是否是最有组织和推荐的方法,但它适用于我的简单项目。
我发现一些可以正常工作的东西:您可以links在您的Cargo.toml:
[package]
links = "libsoundio"
build = "build.rs"
Run Code Online (Sandbox Code Playgroud)
这指定项目链接到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"]
Run Code Online (Sandbox Code Playgroud)
(:前缀告诉 GCC 使用实际的文件名,而不是做所有愚蠢的lib-prepending 和扩展魔术。)
您还需要创建一个空的build.rs:
fn main() {}
Run Code Online (Sandbox Code Playgroud)
这个文件永远不会运行,因为 中的值.cargo/config覆盖了它的输出,但出于某种原因 Cargo 仍然需要它 - 任何时候links =你都必须拥有build =,即使它没有被使用。
最后在main.rs:
#[link(name = "libsoundio")]
#[link(name = "ole32")]
extern {
fn soundio_version_string() -> *const c_char;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
9032 次 |
| 最近记录: |