- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我只是在这里很好奇。我创建了一个共享对象:
gcc -o liba.so -fPIC -shared liba.c
gcc -o libb.so -fPIC -shared libb.c liba.so
libb.so
的可执行文件时,我必须指定 -rpath-link 到 ld 以便它可以找到
liba.so
当发现
libb.so
取决于它:
gcc -o test -Wl,-rpath-link,./ test.c libb.so
liba.so
链接时
test
?因为对我来说,除了确认
liba.so
ld 似乎没有做太多其他的事情的存在。例如,运行
readelf --dynamic ./test
仅列出
libb.so
根据需要,所以我猜动态链接器必须发现
libb.so -> liba.so
依赖自己,并自行搜索
liba.so
.
test
调用
libb.so
中的函数依次调用
liba.so
中的函数.
最佳答案
Why is it, that ld MUST be able to locate
liba.so
when linkingtest
? Because to me it doesn't seem like ld is doing much else than confirmingliba.so
's existence. For instance, runningreadelf --dynamic ./test
only listslibb.so
as needed, so I guess the dynamic linker must discover thelibb.so -> liba.so
dependency on its own, and make it's own search forliba.so
.
libb.so
.它可以忽略
test
中所有未解析的引用希望动态链接器在加载
libb.so
时能够解决它们在运行时。但是如果 ld 这样做,许多“ undefined reference ”错误将不会在链接时检测到,而是会在尝试加载
test
时发现。在运行时。 So ld 只是额外检查所有在
test
中找不到的符号本身确实可以在
test
的共享库中找到。取决于。所以如果
test
程序有“ undefined reference ”错误(在
test
本身和
libb.so
中都没有找到某些变量或函数),这在链接时变得明显,而不仅仅是在运行时。因此,这种行为只是额外的健全性检查。
test
, ld 还会检查
libb.so
中所有未解析的引用在共享库中找到
libb.so
取决于(在我们的例子中
libb.so
取决于
liba.so
,所以它需要在链接时定位
liba.so
)。好吧,实际上 ld 在链接
libb.so
时已经做了这个检查。 .为什么要第二次进行这种检查...也许 ld 的开发人员发现,当您尝试将程序链接到可能在链接时加载的过时库时,这种双重检查对于检测损坏的依赖项很有用,但现在它可以' 不会被加载,因为它所依赖的库被更新(例如,
liba.so
后来被重新设计并且其中的一些函数被删除了)。
libb.so
时”是错误的。
liba.c
有以下内容:
int liba_func(int i)
{
return i + 1;
}
libb.c
有下一个:
int liba_func(int i);
int liba_nonexistent_func(int i);
int libb_func(int i)
{
return liba_func(i + 1) + liba_nonexistent_func(i + 2);
}
test.c
#include <stdio.h>
int libb_func(int i);
int main(int argc, char *argv[])
{
fprintf(stdout, "%d\n", libb_func(argc));
return 0;
}
libb.so
:
gcc -o libb.so -fPIC -shared libb.c liba.so
liba_nonexistent_func
无法解决,它只是默默地生成损坏的共享库
libb.so
.行为与您使用 ar 制作静态库 (
libb.a
) 相同,它也不会解析生成的库的符号。
test
:
gcc -o test -Wl,-rpath-link=./ test.c libb.so
libb.so: undefined reference to `liba_nonexistent_func'
collect2: ld returned 1 exit status
libb.so
时),但 ld 由于某些原因并没有这样做。这可能是为了允许为共享库创建循环依赖项。
liba.c
可以有以下实现:
int libb_func(int i);
int liba_func(int i)
{
int (*func_ptr)(int) = libb_func;
return i + (int)func_ptr;
}
liba.so
用途
libb.so
和
libb.so
用途
liba.so
(最好永远不要做这样的事情)。这成功编译并运行:
$ gcc -o liba.so -fPIC -shared liba.c
$ gcc -o libb.so -fPIC -shared libb.c liba.so
$ gcc -o test test.c -Wl,-rpath=./ libb.so
$ ./test
-1217026998
liba.so
不需要
libb.so
:
$ readelf -d liba.so | grep NEEDED
0x00000001 (NEEDED) Shared library: [libc.so.6]
$ readelf -d libb.so | grep NEEDED
0x00000001 (NEEDED) Shared library: [liba.so]
0x00000001 (NEEDED) Shared library: [libc.so.6]
liba.so
不可能。
$ readelf -d test | grep RPATH
0x0000000f (RPATH) Library rpath: [./]
test
如果共享库(
liba.so
和
libb.so
)位于您当前的工作目录(
./
)。如果您只是使用了 -rpath-link,那么
test
中将没有这样的条目ELF,您必须将共享库的路径添加到
/etc/ld.so.conf
文件或到
LD_LIBRARY_PATH
环境变量。
--no-undefined
选项必须用于这样做:
$ gcc -Wl,--no-undefined -o libb.so -fPIC -shared libb.c liba.so
/tmp/cc1D6uiS.o: In function `libb_func':
libb.c:(.text+0x2d): undefined reference to `liba_nonexistent_func'
collect2: ld returned 1 exit status
关于c - 为什么 ld 在将可执行文件与 a 链接时需要 -rpath-link 以便需要另一个 so ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24598047/
如果共享库链接到二进制文件,并且共享库还依赖于其他库,那么共享库的 RPATH 和二进制文件的 RPATH 的优先级(链接器搜索顺序)是什么?二进制文件的 RPATH 能否覆盖共享库中的 RPATH?
我已经对我的 IOS 应用程序进行了质量扫描分析。我收到以下警告: The binary has Runpath Search Path (@rpath) set. In certain cases
我在尝试通过 QtCreator 运行之前运行的程序时收到此警告。我还收到此警告: libicui18n.so.48,/home/maxim/install/Qt/lib/libQt5Core.so
我在我的 ELF 文件上运行了arm-linux-gnueabihf-ldd(一个来自 Cygwin,别问,一个来自 Ubuntu),尽管通过包含 -rpath-link 消除了 Ubuntu 上的警
我正在构建一个 C++ 应用程序,使用 Netbeans 6.9 作为我的 IDE。我有一个 C++ 库,它是一个纯 C 库的包装器。 我已将文件正确添加到项目中(使用添加库文件选项)。这是 g++
我正在使用 cmake 创建包 我有以下结构 bin/ bin1 lib/ lib1 lib2 其中 lib1 和 lib2 是外部动态库。如何设置 RPATH 使其自动与 l
我正在为 ARM 平台进行交叉编译。在我链接的许多库文件中,只有极少数有 rpath。 我不知道它来自哪里,因为我将我需要的所有库复制到一个文件夹中,然后使用 Netbeans(在带有 Linaro
我有一个应用程序,叫它 Animal.app .在其内部 Contents/Frameworks文件夹是一个框架,比如 Mammal.framework .而在 Versions/A/Framewor
我正在使用 CMake 进行交叉编译。 在我的 CMakeLists.txt 中(用于编译和交叉编译): set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) fin
在 Linux 上使用 CMake 构建之后(但在安装之前),所有链接的库都被添加到最终可执行文件的 RPATH 中。 但是,我想添加 $ORIGIN/../lib:到这个 RPATH。 到目前为止,
我在 OS X 上构建了一个可执行文件(名为 demux),但它总是无法加载而且我找不到原因: $ ./demux RPATH failed to expanding @rpath/sfeMo
我正在尝试设置一个项目,我的存储库将所有依赖项作为 git 子模块导入,以便于开发。我的同事可以简单地克隆 repo、git submodule update --init --recursive、c
我无法使 rpath 正常工作并使我的二进制文件在指定文件夹中搜索库: 我有 3 个非常简单的文件: main.c #include #include int main() { tes
可执行文件的 rpath 指定一个或多个目录,在其中查找运行时的共享对象。 我的问题是 - 共享对象文件自身是否也有静态编译的rpath? 我最近在链接共享对象时收到运行时错误: ./example:
我必须随应用程序一起发布第三方库。因为我不想手动设置 LD_LIBRARY_PATH 或需要任何包装脚本,所以我希望 automake 设置自定义 rpath。不幸的是 libtool 有它自己的 -
我很难确定我对使用我所使用的特定工具链进行交叉编译时rpath-link是如何工作的理解(尽管我认为这是一个普遍适用于交叉编译的普遍问题)。 当我查看构建库和应用程序时将哪些标志传递给编译器和链接器时
我有一个二进制“CeeloPartyServer”,它需要在运行时在 FreeBSD 机器上找到 libFoundation.so。它们都在同一个目录中。我编译(在另一个平台上,使用交叉编译器)Cee
构建二进制文件或库时,指定rpath,即 -Wl,rpath, 告诉链接器在二进制文件运行时在哪里找到所需的库。 这里关于绝对路径和相对路径的 UNIX 哲学是什么?使用绝对路径是否更好,以便可以从任
我想在Mac OSX下设置编译时可执行文件(用于链接器)的运行时路径,以便动态链接器在程序启动时找到非标准位置的共享库。 在Linux下,可以使用-Xlinker -rpath -Xlinker /p
基本上我想在自定义字典中使用库: 编译器参数: gcc -o conftest -Wl,-rpath=/MYPATH/ssl/lib -O2 -Wno-system-headers -I/MYPAT
我是一名优秀的程序员,十分优秀!