[英]Rust cargo.toml specify custom path for C linker and compiler
[英]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.