【发布时间】:2023-03-15 22:11:01
【问题描述】:
我有一个基本问题,我无法找到解决方案。
假设我构建了一个共享库toto,由以下头文件和源文件组成:
toto.h
void print();
toto.cpp
#include <iostream>
#include "toto.h"
void print()
{
std::cout<<"WHAT A GREAT LIBRARY"<<std::endl;
}
基于这些文件,我使用创建共享库
g++ -fPIC -shared -I. -c toto.cpp -o libtoto.so
接下来,我想在测试文件中使用我新创建的共享库:
test.cpp
#include "toto.h"
int main()
{
print();
}
为此,我使用
将我的可执行文件链接到共享库g++ -I. -L. -ltoto test.cpp
我得到了我的a.out 可执行文件。
当我执行ldd a.out 时,我得到以下输出:
linux-vdso.so.1 => (0x00007fff322f5000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007fb7e7c24000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fb7e7865000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fb7e7568000)
/lib64/ld-linux-x86-64.so.2 (0x00007fb7e7f4d000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fb7e7352000)
我看不到我的可执行文件对toto 共享库的任何依赖。在链接过程中,一切似乎都像我的库已静态绑定到我的可执行文件一样。我可以从任何地方调用a.out 而无需将LD_LIBRARY_PATH 设置为存储我的libtoto.so 的路径,这似乎证实了这一点。真的是这样吗?如果是这样,我在上述命令中遗漏了什么或误解了什么?
仅供参考,此示例在 ubuntu 12.04、g++ 4.6.3 上运行
编辑:
同时我可以发现这段代码产生了一个“正确的”
可执行文件的意义在于ldd 显示了对libtoto 共享库的依赖关系,并且如果不设置LD_LIBRARY_PATH 变量就无法启动可执行文件:
g++ -I ./mydylib/ -fpic -c mydylib/toto.cpp -o mydylib/toto.o
g++ -shared -o mydylib/libtoto.so mydylib/toto.o
g++ -I ./mydylib/ -L ./mydylib/ test.cpp -ltoto -o ldd_correct
虽然这个仍然会产生具有上述功能的“错误”可执行文件:
g++ -I ./mydylib -fpic -shared -c mydylib/toto.cpp -o mydylib/libtoto.so
g++ -I ./mydylib -L ./mydylib test.cpp -ltoto -o ldd_wrong
【问题讨论】:
-
看看this question。提供的答案是否解决了您的问题?
-
g++的参数顺序很重要。-ltoto应该放在源文件(例如toto.cpp)和目标文件之后。 -
感谢大家的帮助,但不幸的是,您的建议都不能解决问题。这很奇怪。
-
那么,
./a.out会打印消息吗?如果删除.so并重新运行,会发生什么? (FWIW,在 Redhat Enterprise Linux Server 5.8 ldd 上显示了预期的依赖关系,表明这可能是对ld行为的另一个更改,可能是在 Michael 链接到的更改发生时进行的)。