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
_で失敗します。私は本当に明らかなものを見逃していますか?ドキュメントはこれがうまくいくことを示唆しているようです。
ビルドスクリプトのドキュメント で述べたように:
cargo:
で始まるビルドスクリプト[...で始まる]によってstdoutに出力されるすべての行は、Cargo [...]によって直接解釈されます。rustc-link-search
は、指定された値が-L
フラグとしてコンパイラに渡されることを示します。
あなたのCargo.tomlで:
[package]
name = "link-example"
version = "0.1.0"
authors = ["An Devloper <[email protected]>"]
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"
理想的には、- soundio-sys
パッケージの規約 を使用して*-sys
パッケージを作成します。これには、適切なライブラリにリンクし、Cメソッドを公開するビルドスクリプトがあります。 Cargo links
key を使用してネイティブライブラリを一意に識別し、複数回リンクされるのを防ぎます。他のライブラリはこの新しいクレートを含めることができ、それらのリンクの詳細について心配する必要はありません。
正常に機能するものが見つかりました: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に実際のファイル名を使用し、そのばかげた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;
}
別の可能な方法は 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