对于我的项目,我需要能够运行一个预先编译成共享库的C函数。我在Ubuntu 20.10上做这个。我可以成功地使用锈蚀,但不是当我使用货物。
以下是我的文件列表(内容如下):
Cargo.tomlbuild.rsinclude/test.hsrc/test.csrc/lib.rssrc/main.rsCargo.toml
[package]
name = "libtest-sys"
version = "0.1.0"
links = "test"
build = "build.rs"
edition = "2021"
[dependencies]
libc = "0.2"
[build-dependencies]
cc = { version = "1.0", features = ["parallel"] }
pkg-config = "0.3"build.rs
fn main() {
println!("cargo:rustc-link-search={}", "/home/lanctot/rust_test");
println!("cargo:rustc-link-lib=dylib=test");
}test.h
void test();test.c
#include <stdio.h>
void test() {
printf("This is a test!\n");
}lib.rs
include!("./bindings.rs");main.rs
include!("./bindings.rs");
fn main() {
unsafe {
test();
}
}下面是我如何使用rustc生成共享库、锈蚀绑定和测试程序的方法:
$ pwd
/home/lanctot/rust_test
$ gcc -c -fpic -Iinclude src/test.c -shared -o libtest.so
$ bindgen include/test.h -o src/bindings.rs
$ cat src/bindings.rs
/* automatically generated by rust-bindgen 0.59.2 */
extern "C" {
pub fn test();
}
$ rustc -L. -ltest src/main.rs
$ ./main
This is a test!太好了,它跑了!但是,当我尝试处理货物时:
$ cargo build --verbose
Fresh pkg-config 3.24
Fresh libc v0.2.112
Fresh jobserver v0.1.24
Fresh cc v1.0.72
Compiling libtest-sys v0.1.0 (/home/lanctot/rust_test)
Running `rustc --crate-name libtest_sys --edition=2018 src/main.rs --error-format=json --json=diagnostic-rendered-ansi --crate-type bin --emit=dep-info,link -C embed-bitcode=no -C debuginfo=2 -C metadata=fb122eefc998dd8f -C extra-filename=-fb122eefc998dd8f --out-dir /home/lanctot/rust_test/target/debug/deps -C incremental=/home/lanctot/rust_test/target/debug/incremental -L dependency=/home/lanctot/rust_test/target/debug/deps --extern libc=/home/lanctot/rust_test/target/debug/deps/liblibc-315c8c30d4535204.rlib --extern libtest_sys=/home/lanctot/rust_test/target/debug/deps/liblibtest_sys-13ba9453242dae24.rlib -L /home/lanctot/rust_test`
error: linking with `cc` failed: exit status: 1
|
= note: "cc" "-m64" "-Wl,--eh-frame-hdr" "-Wl,-znoexecstack" "-Wl,--as-needed" "-L" "/usr/lib/rustlib/x86_64-unknown-linux-gnu/lib" "/home/lanctot/rust_test/target/debug/deps/libtest_sys-fb122eefc998dd8f.libtest_sys.57433ps7-cgu.0.rcgu.o" "/home/lanctot/rust_test/target/debug/deps/libtest_sys-fb122eefc998dd8f.libtest_sys.57433ps7-cgu.1.rcgu.o" "/home/lanctot/rust_test/target/debug/deps/libtest_sys-fb122eefc998dd8f.libtest_sys.57433ps7-cgu.2.rcgu.o" "/home/lanctot/rust_test/target/debug/deps/libtest_sys-fb122eefc998dd8f.libtest_sys.57433ps7-cgu.3.rcgu.o" "/home/lanctot/rust_test/target/debug/deps/libtest_sys-fb122eefc998dd8f.libtest_sys.57433ps7-cgu.4.rcgu.o" "/home/lanctot/rust_test/target/debug/deps/libtest_sys-fb122eefc998dd8f.libtest_sys.57433ps7-cgu.5.rcgu.o" "/home/lanctot/rust_test/target/debug/deps/libtest_sys-fb122eefc998dd8f.libtest_sys.57433ps7-cgu.6.rcgu.o" "-o" "/home/lanctot/rust_test/target/debug/deps/libtest_sys-fb122eefc998dd8f" "/home/lanctot/rust_test/target/debug/deps/libtest_sys-fb122eefc998dd8f.4257t6mbhq03i5nc.rcgu.o" "-Wl,--gc-sections" "-pie" "-Wl,-zrelro" "-Wl,-znow" "-nodefaultlibs" "-L" "/home/lanctot/rust_test/target/debug/deps" "-L" "/home/lanctot/rust_test" "-L" "/usr/lib/rustlib/x86_64-unknown-linux-gnu/lib" "-Wl,--start-group" "-Wl,-Bstatic" "/usr/lib/rustlib/x86_64-unknown-linux-gnu/lib/libstd-522c175df7e65c76.rlib" "/usr/lib/rustlib/x86_64-unknown-linux-gnu/lib/libpanic_unwind-6de0d9a99fa442f6.rlib" "/usr/lib/rustlib/x86_64-unknown-linux-gnu/lib/libminiz_oxide-acc51f402ffb0a47.rlib" "/usr/lib/rustlib/x86_64-unknown-linux-gnu/lib/libadler-cbf21249c0bb64a3.rlib" "/usr/lib/rustlib/x86_64-unknown-linux-gnu/lib/libobject-7811673bd6c230a1.rlib" "/usr/lib/rustlib/x86_64-unknown-linux-gnu/lib/libaddr2line-9d24c50c56b501a5.rlib" "/usr/lib/rustlib/x86_64-unknown-linux-gnu/lib/libgimli-f2bf86d8579f7abb.rlib" "/usr/lib/rustlib/x86_64-unknown-linux-gnu/lib/libstd_detect-a510913c7a93022a.rlib" "/usr/lib/rustlib/x86_64-unknown-linux-gnu/lib/librustc_demangle-113eb81ce98dbb76.rlib" "/usr/lib/rustlib/x86_64-unknown-linux-gnu/lib/libhashbrown-36a8ba3e35050b5b.rlib" "/usr/lib/rustlib/x86_64-unknown-linux-gnu/lib/librustc_std_workspace_alloc-6ec306849e1e0cbe.rlib" "/usr/lib/rustlib/x86_64-unknown-linux-gnu/lib/libunwind-cb42b322cd006390.rlib" "/usr/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcfg_if-598bd3c8385c4a71.rlib" "/usr/lib/rustlib/x86_64-unknown-linux-gnu/lib/liblibc-dcf076dc617ac8b6.rlib" "/usr/lib/rustlib/x86_64-unknown-linux-gnu/lib/liballoc-9231e3c18aac66ef.rlib" "/usr/lib/rustlib/x86_64-unknown-linux-gnu/lib/librustc_std_workspace_core-fb02ea9686597718.rlib" "/usr/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcore-f203df3b7c648201.rlib" "-Wl,--end-group" "/usr/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcompiler_builtins-b0414f7c79a0b9b4.rlib" "-Wl,-Bdynamic" "-lgcc_s" "-lutil" "-lrt" "-lpthread" "-lm" "-ldl" "-lc"
= note: /usr/bin/ld: /home/lanctot/rust_test/target/debug/deps/libtest_sys-fb122eefc998dd8f.libtest_sys.57433ps7-cgu.0.rcgu.o: in function `libtest_sys::main':
/home/lanctot/rust_test/src/main.rs:5: undefined reference to `test'
collect2: error: ld returned 1 exit status
error: aborting due to previous error
error: could not compile `libtest-sys`
Caused by:
process didn't exit successfully: `rustc --crate-name libtest_sys --edition=2018 src/main.rs --error-format=json --json=diagnostic-rendered-ansi --crate-type bin --emit=dep-info,link -C embed-bitcode=no -C debuginfo=2 -C metadata=fb122eefc998dd8f -C extra-filename=-fb122eefc998dd8f --out-dir /home/lanctot/rust_test/target/debug/deps -C incremental=/home/lanctot/rust_test/target/debug/incremental -L dependency=/home/lanctot/rust_test/target/debug/deps --extern libc=/home/lanctot/rust_test/target/debug/deps/liblibc-315c8c30d4535204.rlib --extern libtest_sys=/home/lanctot/rust_test/target/debug/deps/liblibtest_sys-13ba9453242dae24.rlib -L /home/lanctot/rust_test` (exit status: 1)我试过很多方法来解决这个问题。如果我删除main.rs,它就能工作。还要注意:我在上面的命令中没有看到所需的-ltest。我已经浏览了很多文档页面,并且相信所有的设置都是正确的。由于它可以很好地处理锈蚀,我相信不知何故,我缺少的是如何指示货物实际通过链接标志。
发布于 2021-12-28 14:20:13
来自货物簿
-l标志只传递给包的库目标,除非没有库目标,在这种情况下,它被传递给所有目标。这是因为所有其他目标都有对库目标的隐式依赖,并且给定的要链接的库应该只包含一次。这意味着如果包同时具有库和二进制目标,库可以访问给定库中的符号,而二进制程序应该通过库目标的公共API访问它们。
实际上,您的包有lib和bin:src/lib.rs,src/main.rs。
如书所述,解决方案是,不要在二进制文件中使用C符号,而只在库中使用C符号。其基本原理是,当一个机箱同时有lib和bin时,库被认为是主要的部分(只有一个,当用作依赖项时使用),而bin是一个助手。
https://stackoverflow.com/questions/70507167
复制相似问题