繁体   English   中英

如何在Rust中指定链接器路径?

[英]How do I specify the linker path in Rust?

我正在尝试将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失败ld: cannot find -llibsoundio 我错过了一些非常明显的东西吗 文档似乎表明这应该有效。

构建脚本文档中所述

所有通过构造脚本[...起始]与cargo:打印到stdout的行由货物直接解释[...] rustc-link-search表示指定的值应作为-L标志传递给编译器。

在你的Cargo.toml

[package]
name = "link-example"
version = "0.1.0"
authors = ["An Devloper <an.devloper@example.com>"]
build = "build.rs"

你的build.rs

fn main() {
    println!(r"cargo:rustc-link-search=C:\Rust\linka\libsoundio-1.1.0\i686");
}

请注意,您的构建脚本可以使用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);
}

证据在于布丁:

$ cargo run
    Finished debug [unoptimized + debuginfo] target(s) in 0.0 secs
     Running `target\debug\linka.exe`
"1.0.3"

理想情况下,您将使用*-sys包的约定创建一个soundio-sys包。 它只是有一个构建脚本,链接到相应的库并公开C方法。 它将使用Cargo links来唯一标识本机库并防止多次链接。 其他库可以包含这个新的包,而不用担心链接细节。

我找到了一些有效的方法:你可以在Cargo.toml指定links

[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使用实际的文件名,而不是做所有的idiotic lib -prepending和extension magic。)

您还需要创建一个空的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;
}

另一种可能的方法是设置RUSTFLAGS

RUSTFLAGS='-L my/lib/location' cargo build # or cargo run

我不知道这是否是最有条理和最推荐的方法,但它适用于我的简单项目。

使用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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM