2016-03-16 72 views
4

我的可執行文件Rust使用本機庫libfoo.a,它取決於共享庫libbar.so,但根本不公開。在Rust中混合使用靜態和動態庫FFI

我鏽病FFI使用來自libfoo的方法,所以我在我的extern代碼::

#[link(name="foo", kind="static")] 
extern "C"{ 
    pub fn do_foo(); 
} 

和我的build.rsCargo.toml包括使用build="build.rs"

fn main() { 
    let libs = &[(Some("../libs/foo/1.0/"), "static=foo"), // use ../libs/foo/1.0/libfoo.a 
       (None, "bar")]; // use libbar.so using LD_LIBRARY_PATH 
    for &(ref m_path, ref lib) in libs { 
     if let &Some(static_path) = m_path { 
      println!("cargo:rustc-link-search={}", &static_path); 
     } 
     println!("cargo:rustc-link-lib={}", &lib); 
    } 
} 

其輸出

限定的 link屬性
cargo:rustc-link-search=../libs/foo/1.0/ 
cargo:rustc-link-lib=static=foo 
cargo:rustc-link-lib=bar 

理論上,我預計Rust會鏈接到libfoo.alibbar.so。問題是rustc甚至不試圖承認libbar

cargo build --debug

/home/author/src/foo/foo.c:21: undefined reference to 'bar_do_stuff' 
collect2: error: ld returned 1 exit status 

結束當我檢查連接器的命令,有一種說法-L ../libs/foo/1.0,以及-l foo,但沒有的-l bar痕跡!

如果我手動將-l bar添加到cc,它會生成(並運行)就好了。

你能讓我知道我失蹤了嗎?我是否應該爲libbar創建FFI綁定,即使我沒有在Rust中使用它並且它沒有從libfoo的API中公開?

回答

2

問題是FFI定義中的#[link]屬性與build.rs構建腳本的輸出之間的衝突。

看起來#[link]屬性指示rustc忽略cargo:rustc-link-*指令。

該修復過程與刪除#[link]屬性一樣簡單。