我是 Rust 中使用 C 的新手,目前正在尝试使用 BFD 构建二进制加载器。 使用bindgen 生成Rust 绑定非常有效。
在我的
build.rs
中我使用过:
println!("cargo:rustc-link-search=native=/usr/lib/x86_64-linux-gnu/");
和
println!("cargo:rustc-link-lib=static=bfd");
此操作失败,并出现几个
undefined reference to 'filename_cmp'
之类的错误。
但是:动态链接时(
println!("cargo:rustc-link-lib=bfd");
)一切正常。
我错过了什么?
我已确保
libbfd.a
存在于 /usr/lib/x86_64-linux-gnu/
中。
我想学习如何在 Rust 中使用 C 语言库
那么,你就做出了一个非常不幸的选择。
libbfd
是一个罕见的例外
库的共享版本和静态版本的规则
定义相同的符号(并保留相同的符号未定义)。 libbfd.a
没有
定义 libbfd.so
定义的所有符号,filename_cmp
是赤字之一。
参见:
$ nm -D /usr/lib/x86_64-linux-gnu/libbfd.so | grep filename_cmp
0000000000109930 T filename_cmp
它就在
libbfd.so
。 T
= 定义于 text
部分。
并且:
$ nm /usr/lib/x86_64-linux-gnu/libbfd.a | grep filename_cmp
U filename_cmp
U filename_cmp
U filename_cmp
libbfd.a
的成员中只有未定义的引用。
libbfd.a
v. libbfd.so
中缺少的符号定义于
libiberty
。 libiberty
本身是一个已退役的GNU软件包。
这可以解释为什么它提供给 libbfd
的定义是静态链接的
进入 libbfd.so
- 这是一个系统运行时 - 但维护人员显然还没有
围绕解耦libbfd.a
。我不知道为什么。在 Ubuntu 中,libbfd
共享库
与 libbinutils
封装在一起;运行时包 libiberty
不存在,但
开发包 libiberty-dev
可以并安装 libiberty.a
。
无论如何,这意味着您可以成功地自行动态链接到
libbfd
的程序
将无法自行静态链接到它。您必须安装libiberty
开发
打包并将 libiberty
附加到链接中。这是相关演示:
$ cat main.c
#include <stdio.h>
extern int filename_cmp (const char *s1, const char *s2);
int main(void)
{
if (filename_cmp("filename_cmp.c","FilenameCmp.c")) {
puts("Not equal");
} else {
puts("Equal");
}
return 0;
}
默认动态联动针对
libbfd
:
$ gcc -o prog main.c -lbfd
$ ./prog
Not equal
现在静态:
$ gcc -o prog main.c -Wl,-Bstatic -lbfd -Wl,-Bdynamic
/usr/bin/ld: /tmp/ccOy7HDt.o: in function `main':
main.c:(.text+0x1d): undefined reference to `filename_cmp'
collect2: error: ld returned 1 exit status
现在静态地附加了
-liberty
:
$ gcc -o prog main.c -Wl,-Bstatic -lbfd -liberty -Wl,-Bdynamic
$ ./prog
Not equal