簡體   English   中英

使用FFI鏈接到Rust的本地C庫

[英]Linking to a local C library for Rust with FFI

我想在Rust中包裝一個非常大的C庫 我使用bindgen生成綁定。 Rust似乎滿足於那些。 然而,盡管我嘗試了不同的嘗試以及我對構建腳本文檔的許多讀取,但我仍然在進行鏈接問題。

我正在使用的庫有一組csh腳本,最終構建了兩個.a文件: cspice.acsupport.a 它們都存儲在我項目的cspice_linux_gcc_64bit/lib中(參見底部的樹)。

我目前通過調用我的測試中的常量和函數來測試正確的綁定,參見 lib.rs (在我的Github上)。

我非常懷疑我的build.rs有問題,或者不太可能是我的Cargo.toml

鏈接錯誤

Running `rustc --crate-name spice src/lib.rs --crate-type lib --emit=dep-info,link -C debuginfo=2 -C metadata=94c06ffe4bfd7d5f -C extra-filename=-94c06ffe4bfd7d5f --out-dir /home/chris/Workspace/rust/SPICE/target/debug/deps -L dependency=/home/chris/Workspace/rust/SPICE/target/debug/deps -L native=cspice_linux_gcc_64bit/lib -l static=cspice`

error: could not find native static library `cspice`, perhaps an -L flag is missing?

error: Could not compile `spice`.

Caused by:
  process didn't exit successfully: `rustc --crate-name spice src/lib.rs --crate-type lib --emit=dep-info,link -C debuginfo=2 -C metadata=94c06ffe4bfd7d5f -C extra-filename=-94c06ffe4bfd7d5f --out-dir /home/chris/Workspace/rust/SPICE/target/debug/deps -L dependency=/home/chris/Workspace/rust/SPICE/target/debug/deps -L native=cspice_linux_gcc_64bit/lib -l static=cspice` (exit code: 101)
Build failed, waiting for other jobs to finish...
error: linking with `cc` failed: exit code: 1
  |
  = note: "cc" "-Wl,--as-needed" "-Wl,-z,noexecstack" "-m64" "-L" "/home/chris/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib" "/home/chris/Workspace/rust/SPICE/target/debug/deps/spice-e22b64d176595306.0.o" "-o" "/home/chris/Workspace/rust/SPICE/target/debug/deps/spice-e22b64d176595306" "-Wl,--gc-sections" "-pie" "-nodefaultlibs" "-L" "/home/chris/Workspace/rust/SPICE/target/debug/deps" "-L" "cspice_linux_gcc_64bit/lib" "-L" "/home/chris/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib" "-Wl,-Bstatic" "-Wl,--whole-archive" "-l" "cspice" "-Wl,--no-whole-archive" "/home/chris/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libtest-163c20e386ec0612.rlib" "/home/chris/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libgetopts-bd312ea730ea22d0.rlib" "/home/chris/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libterm-4959b4e709084e0a.rlib" "/home/chris/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libstd-35ad9950c7e5074b.rlib" "/home/chris/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libpanic_unwind-fb44afc024bbc636.rlib" "/home/chris/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libunwind-14b8f3202acdad6a.rlib" "/home/chris/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/librand-20a50a22d4c2b1e9.rlib" "/home/chris/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcollections-b479831207997444.rlib" "/home/chris/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/liballoc-10b591f1a68dd370.rlib" "/home/chris/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/liballoc_jemalloc-28913dc5a1e63cd7.rlib" "/home/chris/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/liblibc-6ecacccb5bdc4911.rlib" "/home/chris/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libstd_unicode-f4f0ae88f5ad8ad4.rlib" "/home/chris/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcore-bfaa82017ca17cb2.rlib" "/home/chris/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcompiler_builtins-863b57a66ba6c3e1.rlib" "-Wl,-Bdynamic" "-l" "dl" "-l" "rt" "-l" "pthread" "-l" "gcc_s" "-l" "pthread" "-l" "c" "-l" "m" "-l" "rt" "-l" "pthread" "-l" "util"
  = note: /usr/lib64/gcc/x86_64-suse-linux/4.8/../../../../x86_64-suse-linux/bin/ld: cannot find -lcspice
          collect2: error: ld returned 1 exit status


error: aborting due to previous error(s)

error: Could not compile `spice`.

Caused by:
  process didn't exit successfully: `rustc --crate-name spice src/lib.rs --emit=dep-info,link -C debuginfo=2 --test -C metadata=e22b64d176595306 -C extra-filename=-e22b64d176595306 --out-dir /home/chris/Workspace/rust/SPICE/target/debug/deps -L dependency=/home/chris/Workspace/rust/SPICE/target/debug/deps -L native=cspice_linux_gcc_64bit/lib -l static=cspice` (exit code: 101)

build.rs

extern crate bindgen;

use std::env;
use std::path::PathBuf;


fn main() {
    let out_dir = env::var("OUT_DIR").unwrap();
    // Tell cargo to tell rustc to link the system bzip2
    // shared library.
    println!("cargo:rustc-link-search=native=cspice_linux_gcc_64bit/lib");
    println!("cargo:rustc-link-lib=static=cspice");
    //println!("cargo:rustc-flags=-L cspice_linux_gcc_64bit/lib");

    // The bindgen::Builder is the main entry point
    // to bindgen, and lets you build up options for
    // the resulting bindings.
    let bindings = bindgen::Builder::default()
        // The input header we would like to generate
        // bindings for.
        .header("spice_wrapper.h")
        // Finish the builder and generate the bindings.
        .generate()
        // Unwrap the Result and panic on failure.
        .expect("Unable to generate bindings");


    let out_path = PathBuf::from(out_dir.clone());
    // Write the bindings to the $OUT_DIR/bindings.rs file.
    bindings
        .write_to_file(out_path.join("spice_bindings.rs"))
        .expect("Couldn't write bindings!");
}

Cargo.toml

[package]
(...)
links = "cspice"
build = "build.rs"

[build-dependencies]
bindgen = "0.26.3"

[dependencies]

.
├── build.rs
├── Cargo.lock
├── Cargo.toml
├── cspice_linux_gcc_64bit
│   ├── data
│   ├── doc
│   ├── etc
│   ├── exe
│   ├── include
│   ├── lib
│   ├── makeall.csh
│   └── src
├── spice_wrapper.h
├── src
│   └── lib.rs
└── target
    └── debug

構建兩個.a文件: cspice.acsupport.a

在Linux上,靜態庫通常稱為libfoo.a ,但是您的庫沒有lib前綴。

將文件重命名為libcspice.a應該允許它編譯。 我不確定您是否要修改構建腳本或庫構建腳本以執行重命名。 庫本身甚至可能有一個編譯開關來使用平台標准命名方案。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM