首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >我如何将库链接到我的C代码并在一个锈蚀二进制文件中使用它?

我如何将库链接到我的C代码并在一个锈蚀二进制文件中使用它?
EN

Stack Overflow用户
提问于 2018-07-25 17:11:37
回答 2查看 1.6K关注 0票数 1

我试图在我的锈菌项目中包括一个C文件。C文件使用系统依赖项。下面是一个在运行cargo build时不编译的最小示例。

如果我接受货运正在运行的失败命令,并附加了"-l" "nl-genl-3" "-l" "nl-3",则该命令确实成功。它是不是把链接器标志放错了地方,因为这些标志肯定在命令中?

src/main.rs

代码语言:javascript
复制
#[link(name = "nl-genl-3")]
#[link(name = "nl-3")]
extern "C" {
    fn nl_test(help_me_pls: usize) -> usize;
}

fn main() {
    unsafe {
        println!("nl.c function result: {:?}", nl_test(6));
    }
}

src/nl.c

代码语言:javascript
复制
#include <linux/nl80211.h>
#include <netlink/netlink.h>
#include <netlink/genl/genl.h>

int nl_test(int help_me_pls) {
    struct nl_sock* socket = nl_socket_alloc();
    nl_socket_free(socket);
    return help_me_pls;
}

build.rs

代码语言:javascript
复制
extern crate cc;

fn main() {
    cc::Build::new()
        .include("/usr/include/libnl3")
        .file("src/nl.c")
        .compile("libnl.a");
}

Cargo.toml

代码语言:javascript
复制
[package]
name = "derp"
version = "0.1.0"

[build-dependencies]
cc = "1.0"

当我运行cargo build时,我得到以下输出

代码语言:javascript
复制
   Compiling cc v1.0.18
   Compiling derp v0.1.0 (file:///root/derp)
error: linking with `cc` failed: exit code: 1
  |
  = note: "cc" "-Wl,--as-needed" "-Wl,-z,noexecstack" "-L" "/root/.rustup/toolchains/stable-armv7-unknown-linux-gnueabihf/lib/rustlib/armv7-unknown-linux-gnueabihf/lib" "/root/derp/target/debug/deps/derp-5a7445c256565e2d.1vmrdj4gsxr690x4.rcgu.o" "/root/derp/target/debug/deps/derp-5a7445c256565e2d.1y16o1qfye96o7m0.rcgu.o" "/root/derp/target/debug/deps/derp-5a7445c256565e2d.3rngp6bm2u2q5z0y.rcgu.o" "/root/derp/target/debug/deps/derp-5a7445c256565e2d.4oc10dk278mpk1vy.rcgu.o" "/root/derp/target/debug/deps/derp-5a7445c256565e2d.4xq48u46a1pwiqn7.rcgu.o" "/root/derp/target/debug/deps/derp-5a7445c256565e2d.51s1w397y42gpez1.rcgu.o" "/root/derp/target/debug/deps/derp-5a7445c256565e2d.8xzrsc1ux72v29j.rcgu.o" "/root/derp/target/debug/deps/derp-5a7445c256565e2d.oa3rad818d8sgn4.rcgu.o" "-o" "/root/derp/target/debug/deps/derp-5a7445c256565e2d" "/root/derp/target/debug/deps/derp-5a7445c256565e2d.crate.allocator.rcgu.o" "-Wl,--gc-sections" "-pie" "-Wl,-z,relro,-z,now" "-nodefaultlibs" "-L" "/root/derp/target/debug/deps" "-L" "/root/derp/target/debug/build/derp-c3cdcf1fbd0c70b2/out" "-L" "/root/.rustup/toolchains/stable-armv7-unknown-linux-gnueabihf/lib/rustlib/armv7-unknown-linux-gnueabihf/lib" "-l" "nl-genl-3" "-l" "nl-3" "-Wl,-Bstatic" "-Wl,--whole-archive" "-l" "nl" "-Wl,--no-whole-archive" "-Wl,--start-group" "/root/.rustup/toolchains/stable-armv7-unknown-linux-gnueabihf/lib/rustlib/armv7-unknown-linux-gnueabihf/lib/libstd-774f1a5992f88ec5.rlib" "/root/.rustup/toolchains/stable-armv7-unknown-linux-gnueabihf/lib/rustlib/armv7-unknown-linux-gnueabihf/lib/libpanic_unwind-a65ab1ab71045d14.rlib" "/root/.rustup/toolchains/stable-armv7-unknown-linux-gnueabihf/lib/rustlib/armv7-unknown-linux-gnueabihf/lib/liballoc_jemalloc-5cced33d7a39db8e.rlib" "/root/.rustup/toolchains/stable-armv7-unknown-linux-gnueabihf/lib/rustlib/armv7-unknown-linux-gnueabihf/lib/libunwind-76fba694360269fc.rlib" "/root/.rustup/toolchains/stable-armv7-unknown-linux-gnueabihf/lib/rustlib/armv7-unknown-linux-gnueabihf/lib/liballoc_system-b3f660c2be971c37.rlib" "/root/.rustup/toolchains/stable-armv7-unknown-linux-gnueabihf/lib/rustlib/armv7-unknown-linux-gnueabihf/lib/liblibc-64d840c62d40ace0.rlib" "/root/.rustup/toolchains/stable-armv7-unknown-linux-gnueabihf/lib/rustlib/armv7-unknown-linux-gnueabihf/lib/liballoc-b3d8b67c899d207d.rlib" "/root/.rustup/toolchains/stable-armv7-unknown-linux-gnueabihf/lib/rustlib/armv7-unknown-linux-gnueabihf/lib/libcore-d9124265921c5963.rlib" "-Wl,--end-group" "/root/.rustup/toolchains/stable-armv7-unknown-linux-gnueabihf/lib/rustlib/armv7-unknown-linux-gnueabihf/lib/libcompiler_builtins-1aad7d9a81def783.rlib" "-Wl,-Bdynamic" "-l" "dl" "-l" "rt" "-l" "pthread" "-l" "pthread" "-l" "gcc_s" "-l" "c" "-l" "m" "-l" "rt" "-l" "pthread" "-l" "util" "-l" "util"
  = note: /root/derp/target/debug/build/derp-c3cdcf1fbd0c70b2/out/libnl.a(nl.o): In function `nl_test':
          /root/derp/src/nl.c:6: undefined reference to `nl_socket_alloc'
          /root/derp/src/nl.c:7: undefined reference to `nl_socket_free'
          collect2: error: ld returned 1 exit status
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-07-25 20:45:40

来自构建脚本的货运文档

rustc-link-lib=[KIND=]NAME表示指定的值是一个库名,应该作为-l标志传递给编译器。可选的KIND可以是staticdylib (默认值)或framework中的一个,有关详细信息,请参阅rustc --help

将此添加到构建脚本中:

代码语言:javascript
复制
println!("cargo:rustc-link-lib=nl-genl-3");
println!("cargo:rustc-link-lib=nl-3");

并从锈蚀代码中删除link属性。

问题是您的链接器标志正在声明Rust代码需要链接到C库,但这不是完全正确的。您的C代码需要链接到库,而您的Rust代码需要链接到编译的C代码。如果您查看参数,您将看到以下(简写)输出

  • deps/derp-5a7445c256565e2d.1vmrdj4gsxr690x4.rcgu.o (您的锈蚀代码)
  • -l nl-genl-3 (系统库)
  • -l nl-3 (系统库)
  • -l nl (你的C垫片)

链接者的论点顺序很重要。如果在链接器处理对象时不需要某些东西,则不会使用它。

在这里,锈蚀代码添加了一个依赖于来自nl库的代码,因此链接器正在监视这些符号。当nl-3nl-genl-3被处理时,我们不需要它们的任何符号,所以它们大多被忽略。当nl被处理时,我们解析了锈蚀代码中的依赖项,但是nl需要来自nl-genl-3nl-3的符号,这些符号将不再被处理。

这并不明显,但是来自cccc方法会自动打印出一条cargo:rustc-link-lib行,以便将其构建结果与您的Rust代码相关联。

另请参阅:

票数 3
EN

Stack Overflow用户

发布于 2021-05-29 05:57:25

这就是我是如何解决它的铁锈+ .so库。希望能帮上忙

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51524371

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档